char a[]="hello";
a[0]='X';//ok
printf("%s ", a);
![指针和字符串常量 指针常量和指针变量](http://img.413yy.cn/images/31101031/31111746t01262228564b3a983f.jpg)
char *pl="world";
pl[0]='H';//运行时错误
*pl='X';//运行时错误
printf("%s ", pl);
char *s=NULL;
s=(char*)malloc(sizeof(char)*6);//让俺的s到堆上去
strcpy(s, "hello ");
s[0]='x';//ok
printf("%s ", s);
"hello "是字符常量。但char *s定义的是字符指针的。
s[0]= 'X ';当然是错误的,因为s[0]其实说的就是 'h '啦,h是常量来的,当然不能修改,假如你需要修改的话请用。
char s[6]= "hello ";
s[0]= 'X '; 就没事了。 其实char *pl="world";最好写成const char *pl="world";;以免被误用
s不是常量
指向常量
因此在此应用中不能更改
char *s= "ddd ";
一般应该定义成 const char *s = "dddd ";
如果想修改字符串字符的值就用char a[]="hello";
下面的观点总结得很好。
void main()
{
const char *s= "hello ";//此处加了个const修饰.
s[0]= 'X ';
}
简单地说,除了存在栈和堆上的字符串才不是字符串常量.其余的都是字符串常量.
举一个例子:char buffer[20]= "hello ";这个字符串是用来初始化字符数组buffer的,存在栈上,不是一个字符串常量,可以用下标读写其值.又比如,char *p=malloc(...);
strcpy(p, "hello ");这个 "hello "也不是一个字符串常量,因为是在堆上,也可以用指针p进行读写.至于在这两者的前面加上const修饰,虽然表明 "hello "是不允许更改的,但是对于字符串来说,不能说明是字符串常量.因为,const要修饰的不是明确说hello是不可写的,而是说p指向的这段内存区域是不可写的.修饰的对象是不同的,只是恰巧这段区域里存的是hello这个字符串(说得有点绕了吧,你再坚持一下).
除了这两个情况以外,程序中出现的字符串都应该被视为字符串常量了.
比如const char *p= "hello ";这个字符串是存放在静态存储区上的,是不可以更改的.它的有效范围是整个程序的生命期.如果有另外的语句p= "nb ";那么,hello这个字符串将会永远不被引用,但是它会存在于整个程序的生命期.这才是真正的字符串常量.
这与i386的运行模式有关,现在大部分程序是32位的,一般都是运行在保护模式下,这种模式可以设定某个数据段不能write。
但TC的程序是16位实模式的,数据段无所谓read/write限制,甚至连代码段都是可以write的。