浅析C语言的字符串的初始化

在说c的字符串之前,先来看看另一个东西,字符数组。这两者的区别搞清楚了,看到字符串后,就不会有那种模模糊糊的感觉了。

字符数组的基本形式为:

char CharArray[5]={'h','e','l','l','o'};

可以看到上面的形式就是一般的数组初始化形式。

如果改成:

char CharArray[6]={'h','e','l','l','o','\0'};

这其实就是一个c风格的字符串,上面的形式可以完全等价于:

char *CharArray ="hello";

下面主要来讲一下c的字符串的两种初始化方式

1、char *p1 = "Hello";

2、char p2[] = "Another Hello";

 我有很长一段时间把形式2当做了字符数组,其实他也是一种字符串形式。其实本来文章到这里也差不多了,但是还有一些小细节需要注意一下,比如说,形式1中的字符串是不能修改的,但是形式2中的字符串是可以修改的,这是为什么呢?

直接简单粗暴一些吧,上反汇编代码:

(看不懂汇编的同学没关系,可以直接看我下面的解释)

char *p1 = "Hello"; //直接将常量区中字符串对应的地址赋值给p1
0113A3AC  mov         dword ptr [ebp-48h],offset string "Hello" (118AF10h)  


char p2[] = "Another Hello.";//将常量区中对应的字符串,以4个字节为单位,一个一个复制到栈内存中,最后局部指针p2指向这片内存
0113A3B3  mov         eax,dword ptr [string "Another Hello." (118AEFCh)]  
0113A3B8  mov         dword ptr [ebp-60h],eax  
0113A3BB  mov         ecx,dword ptr ds:[118AF00h]  
0113A3C1  mov         dword ptr [ebp-5Ch],ecx  
0113A3C4  mov         edx,dword ptr ds:[118AF04h]  
0113A3CA  mov         dword ptr [ebp-58h],edx  
0113A3CD  mov         ax,word ptr ds:[0118AF08h]  
0113A3D3  mov         word ptr [ebp-54h],ax  
0113A3D7  mov         cl,byte ptr ds:[118AF0Ah]  
0113A3DD  mov         byte ptr [ebp-52h],cl  

常量区内的内存:

0x0118AEEB  73 65 00 00 00 6a 69 6e 6c 61 69 00 00 25 78 0a 0041 6e 6f 74 68 65 72 20 48 65 6c 6c 6f 2e 00 00 00 00 00 00    se...jinlai..%x..Another Hello.......
0x0118AF10   48 65 6c 6c 6f   00 00 00 63 6d 64 2e 65 78 65 00 00 00 00 00 2f 63 00 00 2a 00 63 00 6f 00 6d 00 6d 00 61 00 6e   Hello...cmd.exe...../c..*.c.o.m.m.a.n

栈空间中的内存:

0x0044F78D  cc cc cc cc cc cc cc 41 6e 6f 74 68 65 72 20 48 65 6c 6c 6f 2e 00 cc cc cc cc cc cc cc cc cc 10 af 18 01 cc cc   ???????Another Hello..?????????.?..??

 

解释:

上面的汇编的大致意思是,形式1 char *p1 = "Hello",直接将常量区中字符串对应的地址赋值给p1,在栈空间中10 af 18 01就是p1存储的地址,上面我把反汇编后的Hello的地址标成蓝色了,因为小端的缘故(不懂小端是什么的话就问一下度娘吧),所以这个地址其实就是常量区中Hello对应的地址所以用如*p1 ='h'这种操作是不行的,因为p1指向的是常量区的内存,常量区的内存是不允许修改的,在编译期间就已经确定了。

形式2 char p2[] = "Another Hello.",细心的同学可以看到常量区内Hello和Another Hello都存在,而Another Hello存在于占空间的内存中,这是因为形式2是将常量区中对应的字符串,以4个字节为单位,一个一个复制到栈内存中,最后局部指针p2指向这片栈内存。所以*p2 =‘h’,这个操作是允许的,因为这修改的是栈内存中的内容。

 

如有错误,欢迎指正

 

===================2017/11/8 更新========================

 

下面评论的这位大兄弟,我测试了一下,没有问题啊

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值