user-0 提问: 关于数据存储的疑惑（变量，常量）100分求讲解。。。。

回复:
user: user-0
content: 引用 32 楼 u012348978 的回复:你在临阵磨枪，但这把枪不好磨。c不仅需要广泛的知道，还需要实践的经验。快速掌握c不太容易。  1）编译时和运行时。 编译时刻可以确定的量，就是常量。否则就是变量。  2）值，对象。 值；是一个计算过程，他是不需要储存空间。如；（1+1）这个2是不需要储存空间。同理（2）这个被认为是一个值的话，也是不需要储存空间的。"hello,world"这个字符串被解释为值，在任意时刻唯一确定的。不能有储存空间。这是规则，就像禁止闯红灯一样。  int a = 3；"hello,world"；他们都是值，他是不需要储存空间的，只能怎么理解。因为这是规则。  对象；没什么好解释的，就是一块储存区。  3）指针； 指针有两个意思，一个是指针变量，如；（char  *ch ）一个是指针的值。如； ch = "hello,world"； ch = &c； ch = NULL； ch = 0；  "hello,world"， &c， NULL ，0 ，他们都是指针，也就是指针值；  你知道的太多了，这对你不好，关了电脑出去走走吧。 不是临阵磨枪，我刚开始学习c，认真看了半个月左右。所以是在刚起步阶段。而且打算坚持学习下去，所以不是为了应付考试什么的，只是喜欢，想学习。遇到疑惑，周围没人交流，书上又没写到。所以想搞清楚，就来问各位大神。

user: user-1
content: 为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。

user: user-1
content: 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址；  人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

user: user-1
content: 其实电脑开机后物理内存的每个字节都是可读写的，区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

user: user-2
content: 你在临阵磨枪，但这把枪不好磨。c不仅需要广泛的知道，还需要实践的经验。快速掌握c不太容易。  1）编译时和运行时。 编译时刻可以确定的量，就是常量。否则就是变量。  2）值，对象。 值；是一个计算过程，他是不需要储存空间。如；（1+1）这个2是不需要储存空间。同理（2）这个被认为是一个值的话，也是不需要储存空间的。"hello,world"这个字符串被解释为值，在任意时刻唯一确定的。不能有储存空间。这是规则，就像禁止闯红灯一样。  int a = 3；"hello,world"；他们都是值，他是不需要储存空间的，只能怎么理解。因为这是规则。  对象；没什么好解释的，就是一块储存区。  3）指针； 指针有两个意思，一个是指针变量，如；（char  *ch ）一个是指针的值。如； ch = "hello,world"； ch = &c； ch = NULL； ch = 0；  "hello,world"， &c， NULL ，0 ，他们都是指针，也就是指针值；  你知道的太多了，这对你不好，关了电脑出去走走吧。

user: user-0
content: 引用 30 楼 Adol1111 的回复:[quote=引用 24 楼 u010412073 的回复:] 	char a[10]="abcd";对于这种情况，此时是不是不能把字符串和char *p=“abcd”中的等价，因为此时可以对字符串内容进行修改。是不是此时就理解成把n个数组元素分别作为立即数存在是存在寄存器中的。 这个属于第二点，就是先生成指定的空间，然后再把值丢进这些空间里。这些空间都是在栈上的。 后者的话，就不一样了，这个是先生成指定的字符串，然后再取出地址给指针p。而这些字符串是在分配在文字常量区的，而不是在栈上的，所以无法修改。  还有就是多次生成的字符串常量是不能保证一定是一个地址的。 比如if("abc"=="abc")这两者会比较地址，而不是比较两者的内容，这要依靠编译器的实现了，如果编译器允许的话，会直接取文字常量区已有的地址，如果不行的话会重新生成一个"abc"，所以会有可能不相等。[/quote] 嗯嗯，明白了。真心太感谢了。终于可以不这么纠结了。。。。必须给高分。。嘿嘿。。。可以去外面转一圈了，o(︶︿︶)o ~~

user: user-3
content: 引用 24 楼 u010412073 的回复:char a[10]="abcd";对于这种情况，此时是不是不能把字符串和char *p=“abcd”中的等价，因为此时可以对字符串内容进行修改。是不是此时就理解成把n个数组元素分别作为立即数存在是存在寄存器中的。 这个属于第二点，就是先生成指定的空间，然后再把值丢进这些空间里。这些空间都是在栈上的。 后者的话，就不一样了，这个是先生成指定的字符串，然后再取出地址给指针p。而这些字符串是在分配在文字常量区的，而不是在栈上的，所以无法修改。  还有就是多次生成的字符串常量是不能保证一定是一个地址的。 比如if("abc"=="abc")这两者会比较地址，而不是比较两者的内容，这要依靠编译器的实现了，如果编译器允许的话，会直接取文字常量区已有的地址，如果不行的话会重新生成一个"abc"，所以会有可能不相等。

user: user-0
content: 引用 27 楼 Adol1111 的回复:[quote=引用 21 楼 u010412073 的回复:] 第三点讲的太好了，也就说果然字符串比较特殊了，是一个左值，可以取地址，所以char *p=“abcd”就是取了首地址，而1，2，‘a’在c语言中是立即数，是右值，是没有地址所以int *p=‘a’这样的操作不允许了。。。我一直就是想知道为什么字符串这么特殊。。谢谢啦! 因为只有字符串不能直接用寄存器直接生成啊，总不可能单单用一个数就生成一个字符串吧。比如我说'ABC'那么对应的值就是65、66、67，这样寄存器生成了3次，那么我直接说198你能告诉我这是个怎样的字符串么？  所以单单一个寄存器不可能生成一个字符串。那么多用几个寄存器呢？计算机总共就那么几个寄存器，而字符串的长度有的长有的短，长度超过寄存器个数怎么办？最简单的办法就是先写入到一个内存中，每生成一个就插入到指定的空间中，这样就能保证在大部分情况下都能生成有效的字符串了。  既然写入了内存，那么就会有所谓的地址，就可以进行一定的操作了，这至少符合了左值的标准。当然是否是右值还是左值，要看标准的规定了。临时变量也有地址（但地址很快就会无效），却是右值。[/quote] 恩呢，真是太好了。越来越清楚了，然后就可以去认真看看汇编的书，详细了解下了。 还有就是就是不知道如何看待char a[4]=“abc”这种情况，是不是此时不同于直接给指针赋值的那种字符串，此时相当于看作数组，因为我们知道对于char *p=“abc”内容不可以修改。而此时的可以修改。。（所以此时和一般数组一样，不作为字符串常量看待？）

user: user-0
content: 引用 25 楼 user-4 的回复:3） 是这样的，因为，到目前为止 {。。。。} 的类型是不确定的，可能是结构，数组等 所以，不能看作某一类型的数组常量。  而字符串的类型，是确定的，字符串是带结束符的字符数组。 所以和字符指针，类型是兼容的，而且也比较方便，所以可以这样做。  C是强类型和弱类型并存的语言，所以可以用常量字符串（字符串字面值）初始化字符指针， 也可以用常量字符串（字符串字面值）给字符指针赋值。  C++，由于强类型，把这看成对C的让步； 早期是可以的。  现在C++， 认为只有常量字符指针，才可以常量字符串（字符串字面值）初始化，赋值。  变量的地址，是不可以改变的，因为改变后的地址和这个变量无关。  变量是地址和值的统一体。  没有初始化，也没有赋值的变量，它的值是未指定的。 他的地址不变，才能访问。 随便改变的话，就难以访问了。  指针变量，也是一个变量，所以它的值可以改变。 他自己的地址也是不能改变的。  变量就是一个名字，和一个地址（一块内存），建立的一种映射关系， 一个变量名字，对应一块内存区域，这块内存的位置，就是它的地址。  变量的值，就是这块内存中的数据。  数组是一批变量，所以数组名，会表示他的首元素的地址。 数组名不代表它的值，因为它是一批数据。  C 语言中数组，没有一个单一的值。 他有一批值，他的每个元素有一个值。  C++继承了C的这种表示方法，所以不能整体赋值。 只能整体初始化。谢谢，让我更加明确了。。。自己这样理解，就是担心会错。书上又没有这方面的，所以才请各位大神，给我确定，是不是这样的，你解释的很细致。让我更加确定了。谢谢。然后对于不可以int *p=3或者等等（不是用字符串赋值的情况），我感觉楼上的有一个解释说，字符串是比较特殊的是左值，是有地址的，其它类型的是立即数，是没有地址所以才不可以。这样比较好。。就是不知道如何看待char a[4]=“abc”这种情况，是不是此时不同于直接给指针赋值的那种字符串，此时相当于看作数组，因为我们知道对于char *p=“abc”内容不可以修改。而此时的可以修改。。（所以此时和一般数组一样，不作为字符串常量看待？）

user: user-3
content: 引用 21 楼 u010412073 的回复:第三点讲的太好了，也就说果然字符串比较特殊了，是一个左值，可以取地址，所以char *p=“abcd”就是取了首地址，而1，2，‘a’在c语言中是立即数，是右值，是没有地址所以int *p=‘a’这样的操作不允许了。。。我一直就是想知道为什么字符串这么特殊。。谢谢啦! 因为只有字符串不能直接用寄存器直接生成啊，总不可能单单用一个数就生成一个字符串吧。比如我说'ABC'那么对应的值就是65、66、67，这样寄存器生成了3次，那么我直接说198你能告诉我这是个怎样的字符串么？  所以单单一个寄存器不可能生成一个字符串。那么多用几个寄存器呢？计算机总共就那么几个寄存器，而字符串的长度有的长有的短，长度超过寄存器个数怎么办？最简单的办法就是先写入到一个内存中，每生成一个就插入到指定的空间中，这样就能保证在大部分情况下都能生成有效的字符串了。  既然写入了内存，那么就会有所谓的地址，就可以进行一定的操作了，这至少符合了左值的标准。当然是否是右值还是左值，要看标准的规定了。临时变量也有地址（但地址很快就会无效），却是右值。

user: user-0
content: 引用 22 楼 zhao4zhong1 的回复:拼！ 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  恩呢，我就是想从本质上了解，发现需要学的东西越来越多。。。。 必须努力学习这些。。。。 话说能不能先对这个问题稍微解释下。。。都不知道Alt+8、Alt+7、Alt+6和Alt+5,这些情况，需要从最简单的程序看起、现在这个问题不合适这样观察啊，水平还不足、、、可是又想现在解决。。。

user: user-4
content: 3） 是这样的，因为，到目前为止 {。。。。} 的类型是不确定的，可能是结构，数组等 所以，不能看作某一类型的数组常量。  而字符串的类型，是确定的，字符串是带结束符的字符数组。 所以和字符指针，类型是兼容的，而且也比较方便，所以可以这样做。  C是强类型和弱类型并存的语言，所以可以用常量字符串（字符串字面值）初始化字符指针， 也可以用常量字符串（字符串字面值）给字符指针赋值。  C++，由于强类型，把这看成对C的让步； 早期是可以的。  现在C++， 认为只有常量字符指针，才可以常量字符串（字符串字面值）初始化，赋值。  变量的地址，是不可以改变的，因为改变后的地址和这个变量无关。  变量是地址和值的统一体。  没有初始化，也没有赋值的变量，它的值是未指定的。 他的地址不变，才能访问。 随便改变的话，就难以访问了。  指针变量，也是一个变量，所以它的值可以改变。 他自己的地址也是不能改变的。  变量就是一个名字，和一个地址（一块内存），建立的一种映射关系， 一个变量名字，对应一块内存区域，这块内存的位置，就是它的地址。  变量的值，就是这块内存中的数据。  数组是一批变量，所以数组名，会表示他的首元素的地址。 数组名不代表它的值，因为它是一批数据。  C 语言中数组，没有一个单一的值。 他有一批值，他的每个元素有一个值。  C++继承了C的这种表示方法，所以不能整体赋值。 只能整体初始化。

user: user-0
content: 引用 20 楼 Adol1111 的回复:1、int a=3中，a变量分配在栈上，然后把3存储在这块区域内。就好比，我在内存上租了一个房间（分配了一块内存空间给a），然后让张三住到了这个房间中（张三就是你要存储的值3），如果你要修改里面的值，就等于把张三赶出来，然后让其他人进去。 如果是单纯的3，则是一个立即数，是存在寄存器中的。赋值的操作其实就是先在寄存器上生成这个数，然后再把这个数写入到指定的空间内。你可以去看下汇编了解下。  2、这是声明一个数组，然后把这些常量丢到一个指定的空间内，理解同上。  3、C/C++的常量只的是字面值常量，其中只有字符串比较特殊，其他的常量都是立即数，他们属于右值，不存在所谓的地址。（立即数的地址即寄存器地址，寄存器地址再CPU中，而不是在内存上，具体的可以看汇编中的几种寻址方式。） 在C/C++中，只有左值可以取地址，右值是不可以取地址的，当然右值不一定是指常量，临时变量等等也属于右值。  4、++&a不一样&a是一个右值，不能对右值进行操作。至于普通的变量的地址，也可以++但++后的地址不保证可以正常使用，要么是段错误，要么就是访问了其他地址。 	char a[10]="abcd";对于这种情况，此时是不是不能把字符串和char *p=“abcd”中的等价，因为此时可以对字符串内容进行修改。是不是此时就理解成把n个数组元素分别作为立即数存在是存在寄存器中的。

user: user-1
content: http://bbs.csdn.net/topics/390627329

user: user-1
content: 拼！ 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

user: user-0
content: 引用 20 楼 Adol1111 的回复:1、int a=3中，a变量分配在栈上，然后把3存储在这块区域内。就好比，我在内存上租了一个房间（分配了一块内存空间给a），然后让张三住到了这个房间中（张三就是你要存储的值3），如果你要修改里面的值，就等于把张三赶出来，然后让其他人进去。 如果是单纯的3，则是一个立即数，是存在寄存器中的。赋值的操作其实就是先在寄存器上生成这个数，然后再把这个数写入到指定的空间内。你可以去看下汇编了解下。  2、这是声明一个数组，然后把这些常量丢到一个指定的空间内，理解同上。  3、C/C++的常量只的是字面值常量，其中只有字符串比较特殊，其他的常量都是立即数，他们属于右值，不存在所谓的地址。（立即数的地址即寄存器地址，寄存器地址再CPU中，而不是在内存上，具体的可以看汇编中的几种寻址方式。） 在C/C++中，只有左值可以取地址，右值是不可以取地址的，当然右值不一定是指常量，临时变量等等也属于右值。  4、++&a不一样&a是一个右值，不能对右值进行操作。至于普通的变量的地址，也可以++但++后的地址不保证可以正常使用，要么是段错误，要么就是访问了其他地址。 第三点讲的太好了，也就说果然字符串比较特殊了，是一个左值，可以取地址，所以char *p=“abcd”就是取了首地址，而1，2，‘a’在c语言中是立即数，是右值，是没有地址所以int *p=‘a’这样的操作不允许了。。。我一直就是想知道为什么字符串这么特殊。。谢谢啦!

user: user-3
content: 1、int a=3中，a变量分配在栈上，然后把3存储在这块区域内。就好比，我在内存上租了一个房间（分配了一块内存空间给a），然后让张三住到了这个房间中（张三就是你要存储的值3），如果你要修改里面的值，就等于把张三赶出来，然后让其他人进去。 如果是单纯的3，则是一个立即数，是存在寄存器中的。赋值的操作其实就是先在寄存器上生成这个数，然后再把这个数写入到指定的空间内。你可以去看下汇编了解下。  2、这是声明一个数组，然后把这些常量丢到一个指定的空间内，理解同上。  3、C/C++的常量只的是字面值常量，其中只有字符串比较特殊，其他的常量都是立即数，他们属于右值，不存在所谓的地址。（立即数的地址即寄存器地址，寄存器地址再CPU中，而不是在内存上，具体的可以看汇编中的几种寻址方式。） 在C/C++中，只有左值可以取地址，右值是不可以取地址的，当然右值不一定是指常量，临时变量等等也属于右值。  4、++&a不一样&a是一个右值，不能对右值进行操作。至于普通的变量的地址，也可以++但++后的地址不保证可以正常使用，要么是段错误，要么就是访问了其他地址。

user: user-4
content: 变量名代表一个确定的地址和其中的数据，虽然自动变量是在函数调用时，确定地址的；  但是在每次调用时地址是固定的。 相当于常量。 而 &a 不是可修改的数据，所以 ++ &a 是不允许的。   至于 int a =10 ;这种内置类型的自动变量，可以直接当作指令的操作数， 编译后10 就嵌入到代码中了（10 成了指令中的立即数），所以就不会存储10这个常量了。  而数组初始化，直接把操作数嵌入指令中，代码太长，而且方法也不统一； 所以直接存储到数据区或者常量区。  在函数调用后复制过来，实现初始化，既方便，方法也统一，代码量也比较少，显然是更好的安排。

user: user-0
content: 来人啊。。。。帮忙确认下。。。。新手表示很疑惑。。。

user: user-0
content: 引用 4 楼 max_min_ 的回复:1 int a =3;是在栈分配的空间的，具体的常量也看怎么定义的！如果是3 这个一个，是没有存储空间的！         当需要存储起来才会用对应的类型变量申请空间存储      2 int a[3]={1,2,3}不是常量，这里只是初始化操作，然后把这几个值赋值给 int a 数组而已！      3 不是的！指针可以指向任何有效的内存地址都是可以的！        int  a= 10;  int *p = &a;        char a[] = "hello", char *p = a;        这些操作都是可以的！只要指向的地址是有效，但是注意指向不同，可能导致某些操作出错而已！       4 是不是可以理解变量的话，就是开辟一个区域。前面部分勉强可以这么理解！          地址也是可以++操作的，只是如果跨变量访问的话，只是可能得不到有效数据而已!如果空间申请的是连续的地址空间的，         地址++操作来访问对象是可以的！ 1.你说的这些我都明白，我的意思是直接利用指针只能指向字符串常量，不可以指向别的常量？比如 int *p=1；char *p=‘2’；int *p=｛1，2，3｝这样的表述肯定是不可以的吧，我就是看到char *p=“abcd”就再想为什么只能字符串不能用别的数据类型呢？所以才会这样问。强调的是直接，类似于字符串这样的形式，把字符串换成别的类型。原因我是这样理解字符串在此处表示了首地址，所以可以用指针变量直接赋值，别的数据类型没有这种特点。比如3 ，‘a’直接这样赋给int *p或cha *p 不能给p一个地址。所以不可以。虽然这种问题感觉没意义，我就是想对比深究一下。从而形成一个完整的体系。然后就意味可以把char *p="abcd"作为一种特殊情况看待。 2.然后还有就是int a=3；这个3到底如何理解。是在栈中分配好的区域内存入数据3，可读可写。和常量3有关系么? 有关系的话，到底如何实现？ 没关系的话，就理解成这里分配空间然后自己写入3，可读可写，那么自然也不必深究，我就是想确认下。