关于常量字符串的问题

1.存储位置

首先,常量字符串存储在静态存储区,对于静态存储区,其中的变量常量在程序运行期间会一直存在,不会释放,且变量常量在其中只有一份拷贝,不会出现相同的变量和常量的不同拷贝。常量字符串系统将它们放在常量区,只读的,不可以更改,并且一个字符串只有一个拷贝。

2.与字符数组的区别

常量字符串:

char *p1="abcde;

系统自动在末尾添加字符串结束标志'\0'.

如果你这时候想改变第一个字符的值,用p[0] =’b’,系统会报一个错,常量字符不能更改。

字符数组:

如果你定义一个char a[10],那么系统会“只分配”10个char这么长的内存区域,一个char是一个字节,那么系统会分配十个字节的内存空间,并且将这一片连续的内存空间的首地址赋值给a。也就是说“数组名的值是数组所在内存区域的首地址”换句话说“数组名是一个指针,指向数组第一个值的地址”。

如果你定义一个char a[] = “abcdefg”;这句代码就复杂点了。定义一个数组,数组长度未知,那么系统会根据等号后面的值来“初始化”这个数组,等号后面是什么?前面说过,它是一个常量字符串。在内存中占8个字节,7个字符加上一个结束标志。这时候在内存中就有两个”abcdefg”的字符串了,一个是常量区域的,另一个是根据前者复制了一份的。这句代码的意思就是复制一个常量区域的字符串,将复制后的字符串的首字母的地址赋值给a。

也就是说,最后a所指向的内存区域,已经不是常量里的”abcdefg”了,这里为什么要复制一份呢?原因是因为常量是不允许更改的,而数组一般都意味着需要修改,所以就复制了一份数据,放在非常量区域,就可以更改了。测试程序如下: 

    char* p1 = "abcdef";
    char* p2 = "abcdef" ;
    char a[]= "abcdef" ;
    unsigned long dwP1 = (unsignedlong)p1 ;
    //32位系统里的指针就是4个字节的整数,这样可以具体查看指针的值。
    unsigned long dwP2 = (unsignedlong)p2 ;
    unsigned long dwA = (unsignedlong)a ;
    printf("p1的值(32位地址)= 0x%X\n",dwP1);
    //%X是打印十六进制,X是大写,x是小写
    printf("p2的值(32位地址)= 0x%X\n",dwP2);
    printf("a的值(32位地址) = 0x%X\n",dwA);

字符串常量在内存中只有一份。而赋值给数组的时候,系统会拷贝一份。

3.strlen和sizeof的区别

strlen求字符串的长度,遇到字符串结束符'\0’即终止。sizeof求字节数,包括终止符'\0'.

char a[]="abcdef";
char b[]={'a','b','c','d','e','f'};
char *p="abcdef";


strlen(a)=6;sizeof(a)=7;//包括字符串终止符'\0'

strlen(p)=6;sizeof(p)=4;//指针的大小;

strlen(b)=?;//未知值,首先strlen函数一直会扫描字符数组,直到遇到'\0',而数组中不存在'\0',所以会一直往后扫描,直到遇到某个'\0'为止

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值