C语言字符串中的指针与数组

≡放荡痞女 提交于 2020-03-15 21:52:56

先说一下字符串字面量(字符串常量):双引号中的字符和编译器自动加入末尾的\0字符,都作为字符串储存在内存中。字符串常量属于静态存储类别,说明如果在函数中使用字符串常量,该字符串只会储存一次,在整个程序的生命周期内存在,即使函数被调用多次。用双引号扣起来的内容被视为指向该字符串储存位置的指针。

字符串的赋值可以用指针与数组,请看下面的例子

char str1[] = "I am a student"; 
const char *str2 = "I am a student too";
以上两种表示方法还是有一些不同的

先说数组表示法,数组形式str1[]在计算机的内存中分配一个内含15个元素的数组(末尾还要加上空字符'\0'),当程序载入内存时,也载入了程序中的字符串,字符串存储在静态存储区中,但是当程序在开始时才会为该数组分配内存,此时才将字符串拷贝到数组中,注意此时字符串有两个副本,一个是静态存储区中的常量,另一个是存储在数组中的字符串。str1为首元素的地址(&str1[0]),是常量地址,不能更改,可以进行str1+1(&str1[1]),但是不允许str++这样的操作,因为递增运算符只能对变量名进行运算。

指针形式(*str2)也使得编译器为字符串在静态存储区预留19个元素空间,一旦开始执行程序,它会为指针变量str2流出一个储存位置,并把字符串的地址储存在指针变量中,该变量最初指向该字符串的首地址,但它的值可以改变。因此可以使用自增运算符,如++str2将指向第二个字符。

总结一下,初始化数组把静态存储区的字符串拷贝到数组中,而初始化指针只把字符串的地址拷贝给指针。

看一下例子

#include <stdio.h>
#define MSG "I'm special"
int main(void) { 
    char str1[] = MSG; 
    const char * str2 = MSG;
    printf("address of \"I'm special\":%p\n","I'm special");
    printf("              address str1:%p\n",str1);
    printf("              address str2:%p\n",str2);
    printf("               address MSG:%p\n",MSG);
    printf("address of \"I'm special\":%p\n","I'm special");
    return 0;
}
运行结果为:

address of "I'm special":0x4006e8
              address str1:0x7fff05a39f40
              address str2:0x4006e8
               address MSG:0x4006e8
address of "I'm special":0x4006e8

str2与MSG的地址相同,而与str1的地址不同。虽然字符串常量"I'm special"在两个printf()函数中出现了两次,但是编译器只使用了一个存储位置,而且与MSG的地址相同。
————————————————
版权声明:本文为CSDN博主「咔嚓杨」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013252047/article/details/86608539

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!