找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 276|回复: 2

Question1.32:What is the difference between these initializations?

[复制链接]

210

主题

371

回帖

0

积分

管理员

积分
0
发表于 2013-7-7 10:16:40 | 显示全部楼层 |阅读模式

Q: What is the difference between these initializations?
char a[] = "string literal";char *p  = "string literal";
My program crashes if I try to assign a new value to p[] .

A: A string literal (the formal term for a double-quoted string in C source) can be used in two slightly different ways:
  • As the initializer for an array of char, as in the declaration of char a[] , it specifies the initial values of the characters in that array (and, if necessary, its size).

  • Anywhere else, it turns into an unnamed, static array of characters, and this unnamed array may be stored in read-only memory, and which therefore cannot necessarily be modified. In an expression context, the array is converted at once to a pointer, as usual (see section 6), so the second declaration initializes p to point to the unnamed array's first element.

Some compilers have a switch controlling whether string literals are writable or not (for compiling old code), and some may have options to cause string
literals to be formally treated as arrays of const char (for better error catching). See also questions 1.31, 6.1, 6.2, 6.8, and 11.8b.

210

主题

371

回帖

0

积分

管理员

积分
0
 楼主| 发表于 2013-7-7 10:49:04 | 显示全部楼层
问题:这两个初始化有什么不同?
char a[]="string literal";
char *p="string literal";
如果我试着给p[]赋一个新的值的时候,我的程序就崩溃了(在linux下执行代码的时候提示segmentation fault(段错误))。
回答:一个字面上的字符串(C语言中的源程序中是用双引号引用的字符串)可以有两种不同的使用方式:
1、作为一个数组字符的初始化的值,比如声明了的字符数组a[]。它指定了该数组中的初始化的值(如果与必要的话可以指定数组的大小)。
2、在另外一个地方,它变成了一个未命名的、静态的字符数组,并且这个未命名的数组可能被存放在只读存储区,当然了它是肯定不能被修改的。在一个表达式中,该数组被立即转化为了一个指针(同样可以参考第6章节),因此,第二种对于初始化的p是指向的是未命名的数组的第一个元素。
很多的编译器有一个开关来控制字符串是否可写(用来编译旧代码),而有的编译器提供了选项将字符串转换为了const char型的数组(这样可以更好地做出错处理)(这两种方式我都没有使用过,但对于上述两种初始化还是可以理解的)。
也可以参考问题1.31、6.1、6.2、6.8和11.8b。

210

主题

371

回帖

0

积分

管理员

积分
0
 楼主| 发表于 2013-7-7 10:59:41 | 显示全部楼层
为了更好的理解内存中的变量的分配,这里有一个很好的简易的笔记:
一个由C/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(静态区)(static)全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区。常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区。存放函数体的二进制代码。

这是一个前辈写的,非常详细
//main.cpp
int a = 0; //
全局初始化区

char *p1;//
全局未初始化区

main()
{
       int b; //

       char s[] = "abc"; //

        char *p2;//

        char *p3 = "123456";// 123456
在常量区,p3在栈上。

        static int c =0
//全局(静态)初始化区

        p1 = (char *)malloc(10);
        p2 = (char *)malloc(20);
//分配得来得1020字节的区域就在堆区。

        strcpy(p1, "123456"); //123456
放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

}


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-1 04:43 , Processed in 0.128457 second(s), 20 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表