关于字符串和字符数组的再讨论

字符串指针与字符数组(转载)

选择自 happycock 的 Blog

很多刚从C转C++的人都不明白,在C中这样的代码

char *pChar="hELLO!"; //定义字符指针pChar,指向一个字符数组首元素即h

*pChar='H'; //问题所在行

到了C++中怎么就不行了?你翻遍参考书,都会说,pChar指向的是常量,怎么能允许改变呢?你又问了,怎么我在C中运行的好好的?没人回答你。于是,你只好自我安慰,这就是C++的保护机制吧。

我来做个总结吧,发现这个问题如果不深入研究一下,总是人云亦云,就像我以前那样。于是,我用BC++3.1编译这段代码后运行,无论是编DOS程序还是Windows程序都是能运行的,结果也和你预期的一样。没什么问题。但是VC++6运行时就会出错,错误你想必相当熟悉(XX内存不能写)。但这只是编译器的问题的吗?

你可以把你在VC++中编译的程序拿到纯DOS下运行,哪怕他是Console程序,他也会说“Can not run in DOS”,因为他是32位的。而BC++3.1哪怕是编一个Windows程序,也只是16位的。所以问题的关键在于内存的管理上。32位系统对于应用程序使用的内存定义了操作权限,能读还是能写,或者是其他什么。而16位的系统缺乏这种安全机制,哪怕你说这段数据只能读,但是写一下也没什么关系。

这种代码之所以能在C中运行的很好,就是因为那时C的编译器都是16位的;现在在C++中不行了,是因为你用的C++编译器是32位的——能找到BC++3.1这种古董还真不容易,相对而言TC2.0更好找。我反汇编TC2.0生成的这两条语句char *p = “hellow”;char p[] = “hellow”;发现他们的实现并不相同,相对而言,char *p = “hellow”;生成的代码更简洁一些。虽然C也想定义常量字符串,但由于16位的欠缺保护,这种想法被人误解了;几乎所有学习过C的人都曾耗费力气去理解如上的代码,然后泛滥的使用。不为别的,只因为这种代码效率高,从反汇编结果能看出来。于是使用char p[] = “hellow”;这种语法的人被嘲笑,但事实上,这种语法才是本意,那种语法只是钻了个空子,于是,在32位程序中,他被剥夺了生存的权利。

这让我想起了C中很多怪异的写法,虽然他们让人很费解,但是确实,他们的效率要比容易看懂的写法来得高,当然,我不知道这其中有没有钻空子的例子;从C设计的本意来说,他们有存在的意义,但是从现在的程序设计潮流来看,代码的可读性要求超过了他的效率。不知道这些语法能不能算是程序员中的一种外语——想写高效的程序吗,掌握我吧,哪怕是死记硬背。

PS:32位系统运行16位程序采用的是模拟仿真的方法,就是说和运行在16位系统一样。

//--------------------------------------------------------------------------------------------------------------------------C语言里定义一个字符串可以使用指针也可以使用数组,如:
(1) char *s="hello"; //"hello"是字符串常量,s是指向常量的指针,常量是不允许改变的,不能写成s[0]=X,但可以改变指针的值,使其指向不同的常量,如 s = "Xeron";
(2) char s[]="hello"; //指针常量,s本身的值不能修改,但可以修改其指向的内容,s[0]=X
两者的区别是
(1)定义的字符串在程序里不能被修改,因为它存放在代码段内;
(2)定义的字符串可被修改,它存放在数据段或者栈内。

这两种定义字符串的方法在函数内部和外部稍有区别

*函数外部:
(1) char *s="hello"; /*定义了指针s(数据段)和常量字符串"hello"(数据段),s的值为字符串首地址*/
(2) char s[]="hello"; /*定义了字符数组s,数组内容为"hello"(代码段),注意这里s只是一个符号而不是变量实体*/

*函数内部:
如果在函数内部使用(1),(2)定义,则"hello"字符串本身存放在代码段,当函数被调用时,
(1) 仅把字符串"hello"的首地址地址赋给s
(2) 把字符串"hello"拷贝一份放到栈内,把拷贝串的首地址赋给s

所以(1)中s所指的内容不能改变,而(2)中s所指的串可修改,s指向的是"hello"串的拷贝,不会影响原串,每次调用函数的时候都拷贝一次

注:在函数内部使用(1)(2)是没有加static关键字修饰的,如果加了static关键字,那就跟在函数外部没什么区别了.
******************************
(1)稍加改变就能满足"hello"串可修改
char *s = (char []){"hello"}; //好像不可行
此时匿名"hello"串存放在数据段。
也可以给定义一个匿名数组赋给int型指针,如:
int *p=(int [10]){[0 ... 9]=0};

转载于:https://www.cnblogs.com/CBDoctor/archive/2012/09/27/2706415.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值