zoukankan      html  css  js  c++  java
  • 字符串的数组形式和指针形式声明及其区别 整理版(摘自《C Primer Plus 中文版第六版》第11章及黑马程序员2018C语言提高深入浅出ch1-5 )

    本节内容需要掌握内存分区的概念,可以参见:C程序的内存分区(节选自黑马训练营day1)

    下面来看例程:

     #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define sTring "I like C!" //定义一个宏字符串

    1
    void locationOfString() //不同声明形式下,字符串的地址 2 { 3 char arrString[]="I am a freshman!"; //数组形式声明字符串 4 char *p=arrString; //声明指针指向上面字符串 5 char*q="I am a freshman!"; 6 printf("字符串本身的地址是: %p 字符串的内容是: %s","I am a freshman!","I am a freshman! "); 7 printf("字符串数组的地址是: %p 字符串数组的内容是: %s ",arrString,arrString); 8 printf("指向字符串数组的指针的地址是:%p 指向字符串数组的指针的内容是:%s ",p,p); 9 printf("指向字符串的指针的指向地址是:%p 指向字符串的指针的内容是: %s ",q,q); 10 }

    程序运行后,输出如下:

       字符串本身的地址是:                  00405064    字符串的内容是:                          I am a freshman!
       字符串数组的地址是:                  0060FEF7    字符串数组的内容是:                  I am a freshman!
       指向字符串数组的指针的地址是:0060FEF7    指向字符串数组的指针的内容是:I am a freshman!
       指向字符串的指针的指向地址是:00405064    指向字符串的指针的内容是:        I am a freshman!

       从上面程序运行的结果可以推断出:
       1、当编程者定义一个字符串的时候,编译器将字符串存放在程序数据区(静态存储区)。
       2、以数组形式声明的字符串,字符串本身在程序数据区(全局区)。程序运行后,编译器拷贝字符串,并将其放在栈区,形成副本。
            字符串数组的地址就是字符串栈区副本的地址,该地址的内存随着函数运行结束被释放。
       3、以指针形式声明的字符串,则在栈上没有副本,指针指向字符串本身在程序数据区的地址。

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #define sTring "I like C!" //定义一个宏字符串
     5 
     6 void outputArrayString()
     7 {
     8     char arrString[]=sTring;
     9     printf("数组形式输出字符串数组的第4个字符是:  arrString[3]=%c 
    ",arrString[3]);
    10     printf("指针形式输出字符串数组的第4个字符是:*(arrString+3)=%c 
    
    ",*(arrString+3));
    11     printf("字符串数组的地址是  :    arrString=%p 
    ",arrString);
    12     printf("字符串数组的首地址是:&arrString[0]=%p 
    ",&arrString[0]);
    13     printf("字符串本身的首地址是:      &sTring=%p 
    ",&sTring);
    14     printf("字符串本身的地址是  :       sTring=%p 
    
    ",sTring);
    15 }
    16 void outputPointString()
    17 {
    18     char *p=sTring;
    19     printf("数组形式输出字符串数组的第5个字符是:  p[4]=%c 
    ",p[4]);
    20     printf("指针形式输出字符串数组的第5个字符是:*(p+4)=%c 
    
    ",*(p+4));
    21 }


       通过outputArrayString和outputPointString例程的运行,我们可以看出:
         1、只要将字符串与数组或者指针联系起来(以赋值的形式),我们就可以输出字符串中的字符。
         2、无论是用数组还是用指针与字符串联系起来,在定位字符串的位置,以输出字符串的某个字符时,
              用指针偏移或者数组偏移的形式都可以。这时,数组形式和指针形式的定位是通用的,并且可以互换。

     1 #define sTring "I like C!"
     2 void editArrayString()
     3 {
     4     char arrString[] = sTring;
     5     printf("数组字符串=%s  宏字符串=%s
    ", arrString, sTring);
     6     arrString[0] = 'W';
     7     printf("数组字符串=%s  宏字符串=%s
    ", arrString, sTring);
     8     *(arrString) = 'I';
     9     printf("数组字符串=%s  宏字符串=%s
    ", arrString, sTring);
    10     //++arrString='h';  当程序运行到这条语句时,提示错误。
    11     printf("数组字符串=%s  宏字符串=%s
    
    ", arrString, sTring);
    12 }

     通过上面例程可以看出:
       1、声明一个数组,并将其与宏字符串关联后,字符串数组可以被修改。
       2、被修改的仅仅是字符串数组,也就是宏字符串在栈上的副本,宏字符串本身并没有改变。
       3、字符串的地址不能被修改,也就是说,字符串数组变量名不能做左值。

     1 void editArrayString2()
     2 {
     3     char arrString[] = "I believe tomorrow to be a better day!";
     4     printf("程序数据区字符串地址=%p	", &("I believe tomorrow to be a better day!"));
     5     printf("程序数据区字符串=%s
    ", *(&("I believe tomorrow to be a better day!")));
     6     printf("字符串数组地址      =%p 	 字符串数组     =%s
    ", arrString, arrString);
     7     arrString[0] = 'W';
     8     //*((char*)("I believe tomorrow to be a better day!")) = 'W';  程序运行至此,系统报错!
     9     printf("程序数据区字符串地址=%p	", &("I believe tomorrow to be a better day!"));
    10     printf("程序数据区字符串=%s
    ", *(&("I believe tomorrow to be a better day!")));
    11     printf("字符串数组地址      =%p 	 字符串数组     =%s 
    
    ", arrString, arrString);
    12 }

    通过上面例程可以看出:
       1、声明一个字符串数组后,编译器在内存的程序数据区写入一个字符串常量。
       2、声明字符串数组的函数被调用后,编译器在栈区写入一个字符串常量副本作为字符串数组。
       3、字符串数组可以被修改,但被修改的仅仅是字符串数组,也就是字符串在栈上的副本,
       存放在程序数据区的字符串常量并没有改变。
       4、字符串本身不可以被修改,被当作常量处理。

    1 void editPonintString()
    2 {
    3     char *p="persevere in!";
    4     printf("指针声明字符串=%s 
    ",p);
    5     //*(p+1)='E';  //程序运行至此,系统报错!
    6     printf("指针声明字符串=%s 
    ",p);
    7     p=p+2;
    8     printf("指针声明字符串的第3个字符=%c 
    ",*(p));
    9 }

    通过上面例程可以看出:
       1、以指针形式声明一个字符串变量后,该字符串不能被修改。
       2、指针的地址可以被修改,也就是说,指针变量名能做左值。

  • 相关阅读:
    [不知道哪来的题] Subsequence
    [不知道哪来的题] 变量(variable)
    [不知道哪来的题] 串(string)
    LOJ#500. 「LibreOJ β Round」ZQC 的拼图
    Codeforces855C Helga Hufflepuff's Cup
    Codeforces895C Square Subsets
    Codeforces757D Felicity's Big Secret Revealed
    bzoj3694 最短路
    maven安装时报错的问题
    java static关键字
  • 原文地址:https://www.cnblogs.com/GoldCrop/p/11031818.html
Copyright © 2011-2022 走看看