user-0 提问:  char s[] = "abcdef";"abcdef"是在栈区还是堆区？

回复:
user: user-1
content: C版的那只老鼠呢？他解释的最好！  C. FAQ 1.32 http://c-faq.com/decl/strlitinit.html  C.FAQ 6.2 http://c-faq.com/aryptr/aryptr2.html

user: user-2
content: 引用 18 楼 lm_whales 的回复:[quote=引用 17 楼 u012942555 的回复:] [quote=引用 11 楼 lm_whales 的回复:] 第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  我理解的这句话的意思是，在初始化之前“abcdef”在常量区，初始化之后在a[]内部？不知道是不是这样 这样的话岂不是两份“abcdef”了，实在是Yun[/quote] 就是这么做的， 因为局部非静态变量，在函数运行的过程中初始化。 这样，编译器无法预先把数据，存放到 a[] 中。 于是，只好先存起来，然后再用。 a[]中这份，你可以随便处理， 预存的那份，你根本摸不清它在哪里， 所以根本不能处理它，不能读，不能写。 如果你可以读写了，那么编译器就不能保证初始化，是正确的了。 [/quote] 另外， 像 int a[20] =｛0｝ ，//C,C++   int a[20]｛｝, //C++11 等 int a [20]={}   //C++11，等 这种，可以直接生成填充代码， 也可以用一批全零数据，预先存下来，再复制过去。  关于堆对象  C malloc 函数分配的数据，不能初始化  C++11 标准之前： C++ 运算符 new 只能初始化 类对象，内置类型，new[]不能初始化数组.  C++11算符 new 可以初始化类对象，内置类型, new[] 数组也可以初始化 C++11 new[] 初始化如下  T *p= new T[100] {1,2,3,4,5,6,}; //用 初始化列表初始化数组， T *q; q =new T[100]{1,2,3,4,5,6} //用 初始化列表初始化数组，

user: user-3
content: 引用 10 楼 lm_whales 的回复:这个是有这么几种情况的：    char s[] = "abcdef"; //1） s在静态区，"abcdef"无需额外存放，就是数组s内部，总共占用一个串的内存 const char *p ="abcdef";//2）p在静态区,"abcdef",必须额外存放（在常量区，通常也在静态区）                                     //总共占用一个指针，和一个串的内存 int main(){ char a[]= "abcdef" ; //3）a在栈区,"abcdef" 必须额外存放（在常量区，通常也在静态区）,这个初始化，一般就是复制数据。                              //编译器，一般不会把串中的字符，编译成立即数，一个一个装填 a[i]; printf("s=%s\np=%s\na=%s\n",s,p,a); return 0; } s,p,a "abcdef" 各在什么位置： 第1）种情况，不需要再寻找了，二者占用同一个位置s，"abcdef"是一家，不必骑驴找驴。 第2）种情况，你可以简单的通过代码，找到 “abcdef”，存储的位置。也就是指针的值。 第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。 数组和指针不同的是 指针只是一个表示地址的数据，它的类型指的是，那个地址中存放的数据的类型。 数组，是一批同一类型数据组合。它就是这一批数据。 数组，可以用 数据存储位置（指针）和数据量（元素个数）两个特征来表征。    楼主，好好看下这楼的解释，这是正解，理解最深刻的一位。

user: user-2
content: 引用 17 楼 u012942555 的回复:[quote=引用 11 楼 lm_whales 的回复:] 第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  我理解的这句话的意思是，在初始化之前“abcdef”在常量区，初始化之后在a[]内部？不知道是不是这样 这样的话岂不是两份“abcdef”了，实在是Yun[/quote] 就是这么做的， 因为局部非静态变量，在函数运行的过程中初始化。 这样，编译器无法预先把数据，存放到 a[] 中。 于是，只好先存起来，然后再用。 a[]中这份，你可以随便处理， 预存的那份，你根本摸不清它在哪里， 所以根本不能处理它，不能读，不能写。 如果你可以读写了，那么编译器就不能保证初始化，是正确的了。

user: user-0
content: 引用 11 楼 lm_whales 的回复:第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  我理解的这句话的意思是，在初始化之前“abcdef”在常量区，初始化之后在a[]内部？不知道是不是这样 这样的话岂不是两份“abcdef”了，实在是Yun

user: user-4
content: 这是字符数组，是在栈上（不是楼上所说的常量区），只有用动态分配的才是在堆上

user: user-0
content: 你们的回答让我彻底找不到北了   findfun能不能详细点

user: user-3
content: 都是在常量区，只不过在栈区有映射。

user: user-5
content: 理解 char s[ ] = "abc"; 与 char *s = "abc"; 的区别。

user: user-6
content: 引用 4 楼 u012942555 的回复:char *s="abcdef";//"abcdef"是在常量区 char s[]="abcdef";//"abcdef"应该不在常量区，但我不知道在哪里 char s[]="abcdef";//"abcdef"应该在堆区.

user: user-0
content: char *s="abcdef";//"abcdef"是在常量区 char s[]="abcdef";//"abcdef"应该不在常量区，但我不知道在哪里

user: user-7
content: 引用 2 楼 u012942555 的回复:char *s="abcdef";//"abcdef"是在常量区  这个不是  楼主，你想说什么？

user: user-0
content: char *s="abcdef";//"abcdef"是在常量区  这个不是

user: user-7
content: "abcdef"在常量区

user: user-2
content: 引用 13 楼 u012942555 的回复:[quote=引用 11 楼 lm_whales 的回复:] 第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  第3中情况  如果在常量区，常量区的内容可以修改吗，第三种的情况内容可以被修改a[2]='w';，如果在常量区，内容应该是不能修改的啊[/quote] 第3）种情况这个常量区，你根本就不能修改，你找不到它的位置，你的程序不认识它，它是匿名的。 你只能修改，已经被初始化为 “abcdef”的数组 a[] 的元素。

user: user-8
content: 引用 14 楼 u012942555 的回复:[quote=引用 12 楼 user-8 的回复:] 1) char *s = "abcd".  s 是一个字符指针，指向“abcd”字符串，也就是存放该字符的地址。 “abcd”实际存放在该进程地址空间的全局数据区，或者叫常量区。证明： #include<stdio.h>  char *s1 = "abcd";   void func() { 	char *s2 = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char *s3 = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  以上程序的s1, s2, s3定义在不同地方，但他们的值相等。  2)  char s[] = "abcd". "abcd"在s所在的栈区。 证明： #include<stdio.h>  char s1[] = "abcd";   void func() { 	char s2[] = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char s3[] = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  显示三个地址不一样。 只有当用new，或者malloc，比如 char *s = new char[5].  分配的空间才在堆区。   我认为是s2,s3在栈区，s1在常量区[/quote]  你说的对，我忘了还有个全局指针。

user: user-0
content: 引用 12 楼 user-8 的回复:1) char *s = "abcd".  s 是一个字符指针，指向“abcd”字符串，也就是存放该字符的地址。 “abcd”实际存放在该进程地址空间的全局数据区，或者叫常量区。证明： #include<stdio.h>  char *s1 = "abcd";   void func() { 	char *s2 = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char *s3 = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  以上程序的s1, s2, s3定义在不同地方，但他们的值相等。  2)  char s[] = "abcd". "abcd"在s所在的栈区。 证明： #include<stdio.h>  char s1[] = "abcd";   void func() { 	char s2[] = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char s3[] = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  显示三个地址不一样。 只有当用new，或者malloc，比如 char *s = new char[5].  分配的空间才在堆区。   我认为是s2,s3在栈区，s1在常量区

user: user-0
content: 引用 11 楼 lm_whales 的回复:第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  第3中情况  如果在常量区，常量区的内容可以修改吗，第三种的情况内容可以被修改a[2]='w';，如果在常量区，内容应该是不能修改的啊

user: user-8
content: 1) char *s = "abcd".  s 是一个字符指针，指向“abcd”字符串，也就是存放该字符的地址。 “abcd”实际存放在该进程地址空间的全局数据区，或者叫常量区。证明： #include<stdio.h>  char *s1 = "abcd";   void func() { 	char *s2 = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char *s3 = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  以上程序的s1, s2, s3定义在不同地方，但他们的值相等。  2)  char s[] = "abcd". "abcd"在s所在的栈区。 证明： #include<stdio.h>  char s1[] = "abcd";   void func() { 	char s2[] = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char s3[] = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  显示三个地址不一样。 只有当用new，或者malloc，比如 char *s = new char[5].  分配的空间才在堆区。

user: user-2
content: 第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。