字符串数组的初始化问题

来源:互联网 发布:windows ime是什么 编辑:程序博客网 时间:2024/04/28 02:17

对于早期的编译器,对楼主的程序可能不会报错或警告,但是,更符合标准的编译器,一定会有警告甚至报错的.
楼主的程序准确的写法应该是这样的:
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这个字符串将会永远不被引用,但是它会存在于整个程序的生命期.这才是真正的字符串常量.

说了半天,语无伦次,楼主凑合看吧.

 

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 char buf[10]="2222222";

 buf[3]='1';

 

上面是可以运行的,没问题,这里的字符串数组是在栈上;

 


 char *buf1="111111111";

*buf='2';

这个编译没有问题,运行却要出错。按道理内容“111111111“也应该是在栈上,但是却被限定为常量无法修改。

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

和任何数组名一样,字符数组名也是数组首元素的地址.因此,下面的式子对于数组m1成立:
m1 == &m1[0], *ml == 'L', *(m1 + 1) == m[1] == 'i'
      的确,可以使用指针符号建立字符串.例如,我们可以有下面这样的声明:
const char *m3= "/nEnough about me - what's your name? ";
      这个声明和下列声明的作用几乎(不是完全,这正是我要讨论的)相同:
char m3[] = "/nEnough about me - what's your name? ";
那么,数组和指针形式的不同是什么呢?数组形式(m3[])在计算机内存中被分配一个有38个元素的数组(其中每个元素对应一个字符,还有一个附加的元素对应结束的空字符'/0').每个元素都被初始化为响应的字符.通常,被应用的字符串存储在可执行文件的数据段部分;当程序被加载到内存中时,字符串也被加载到内存中.被引用的字符串位于一块被称为静态存储区的地方.但是在程序开始运行厚才为数组分配存储空间.这时候,把被引用的字符串复制到数组中(以后我会讨论存储类,链接和内存管理).此后,比那一起会把数组名m3看作是数组首元素的地址&m3[0]的同义词.这里重要的一点是.在数组形式中m3是个地址常量.我们不能更改m3本身,因为这意味着更改数组存储的位置(地址).可以使用运算符m3+1(加一个单位,而不是加数值1,在我们这个例子中,如果系统char是8位的,+1将会导致把地址加8,也就是一个字节,这样m3+1指向的就是字符串中的第二个字符)来表示数组里的下一个元素,但是不允许使用++m3.增量运算符只能用于变量,而不能用于常量.
      指针形式(*m3)也在静态存储区位字符串预留38个元素的空间.此外,一旦程序开始执行,还要位指针变量m3另外预留一个存储位置.以在该指针变量中存储字符串的地址.这个变量初始时指向字符串的第一个字符,但是它的值时可以改变的(废话,不能改变叫什么变量).因此可以对它使用增量运算符.例如,++m3将指向第二个字符E.
      总之,数组初始化是从静态存储区把一个字符串复制给数组,而指针初始化只是赋值字符串的地址.这些区别重要吗?通常来说不中要,但是这要取决于做什么.

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

明白了吧!数组初始化用到了拷贝,数据在栈中存在,而指针这种初始化方式的时候,数据只在静态数据区存在,栈中根本没有,也就没法修改了!18701597246