user-0 提问: 关于c语言的const问题

回复:
user: user-1
content: const char *p  表示char *的内容不可以被修改。  char * const p  表示p不可以被修改，永远只能指向这个位置。  const 靠近哪个表示哪个不能被修改。  编译器会把const修饰的变量放在只读区域。在MMU的系统上，会在cpu中的虚拟地址到物理地址的内存描述符中设置read only属性。在没有mmu的系统上，没有实际的意义，只能作为编译器的提醒作用。

user: user-2
content: C专家编程 里面说过 某个变量加了const这个关键字。表示限制这个符号不能够修改。但是并不代表不可以通过其它的方法来修改  const char a='a';//在这里const只是用来限制变量名为a这个符号不能改。 char *p=(char*)&a;//这里不存在问题 *p='b';  只不过在C++里面const又是另外一种解释。在C语言里面const只是把变量作为一个只读变量。但是说到底还是变量。在C++里面用const修改的变量。就只只是常量。不能通过更改。上面的代码如果是C++编译器。结果是a的值不变。如果是C编译器。变量a的值会变为'b'。 楼主可以去看看C专家编程。里面有说过这个问题。

user: user-3
content: 引用 7 楼 q328965539 的回复:[quote=引用 3 楼 Falleyes 的回复:] a不是指向const数据，所以a可以修改数据内容。 b声明为const char* b=a;意思是说不能通过b这个指针改变其所指向的数据。跟a能不能修改没有关系。 有深层次点的解释么，我是想知道为什么不能通过b这个指针改变其所指向的数据？ 内部是不是const指定那块内存为只读的？（事实证明那块内存还是可读写的） 还是用const去限制了这个指针去读那块内存？那又是怎么限制的，这机制怎么实现的？[/quote] const更多的意义是用于语法检查。在C语言的实现里，一般真正不可修改的只有字符常量这类位于常量内存区的数据（当然内存读写控制需要CPU和操作系统支持）。 一般比如我们写memcpy这样功能的函数，源地址const指针，目标地址是普通指针。这样就能防止我们代码中的bug导致不小心修改了源内存。 另外像const char *p= “abc"; 这样的，如果写成char *p=”abc“，就会有隐患。如果我们程序不小心修改了"abc”的内存，这个编译器就检查不出来。只能等到程序运行时发生段错误，然后死得很难看了。（对于DOS等环境，甚至不会有段错误，程序的bug更隐蔽）

user: user-4
content: const & 指针  　　类型声明中const用来修饰一个常量，有如下两种写法，那么，请问，下面分别用const限定不可变的内容是什么?  　　1)、const在前面  　　const int nValue； //nValue是const  　　const char *pContent; //*pContent是const, pContent可变  　　const (char *) pContent;//pContent是const,*pContent可变  　　char* const pContent; //pContent是const,*pContent可变  　　const char* const pContent; //pContent和*pContent都是const  　　2)、const在后面，与上面的声明对等  　　int const nValue； // nValue是const  　　char const * pContent;// *pContent是const, pContent可变  　　(char *) const pContent;//pContent是const,*pContent可变  　　char* const pContent;// pContent是const,*pContent可变  　　char const* const pContent;// pContent和*pContent都是const  　　答案与分析：  　　const和指针一起使用是C语言中一个很常见的困惑之处，在实际开发中，特别是在看别人代码的时候，常常会因为这样而不好判断作者的意图，下面讲一下我的判断原则：  　　当const所在代码段中不包含括号时，沿着*号划一条线，如果const位于*的左侧，则const就是用来修饰指针所指向的变量，即指针指向为常量；如果const位于*的右侧，const就是修饰指针本身，即指针本身是常量。你可以根据这个规则来看上面声明的实际意义，相信定会一目了然。  　　另外，需要注意：对于const (char *) ; 因为char *是一个整体，相当于一个类型(如 char)，因此，这时限定指针是const。  　　一个简单的判断方法：指针运算符*，是从右到左，那么如：char const * pContent，可以理解为char const (* pContent)，即* pContent为const，而pContent则是可变的。

user: user-4
content: 上面打错，是const char* const b

user: user-4
content: 你那种情况是表示指针指向的地址是常量，而不是该地址的内容  const char const* b  就连指向地址的内容也要是常量

user: user-5
content: 首先,源代码内的各种变量,在编译链接以后生成的执行文件中都被转变成了内存的相对地址,运行时cpu会根据寄存器保存的绝对地址+相对地址 = 通过地址总线译码找到真正的物理地址 然后通过数据总线去读入或写人数值     char a[]="abcd"; //a变量在内存j就是比如地址0x1000,里面存放了31 32 33 34 就是abcd字符的ascill码     const char* b=a; //b变量在内存就是比如地址0x8000,但注意这个0x8000是在内存的常量区,这段地址里面的值被赋值后是不能被改写的,里面放了一个值0x1000,     //b[0]='!'; a[0]='f'; //然后通过这条指令对地址0x1000写人一个值,这个就是跟0x8000里面那个x1000没一点关系了!!!     printf("%s\n",b);

user: user-6
content: 只是不能通过b来修改其指向的内容，a还是可以修改的

user: user-7
content: 引用 8 楼 q328965539 的回复:int main(void) {       const int a=10;    int* p=(int*)(&a);    *p=20;    cout<<a<<" "<<*p<<endl;    return 0; } 这样又如何？这样的代码是错的 结果没有意义

user: user-8
content: 引用 11 楼 yizhizhuen 的回复:这个问题，关乎这一点，首先C语言是一种弱类型的语言。也就是说每次读取数据的时候，都会从内存地址中读取，尽管用const修饰，但是内存的内容依旧可以修改（弱类型语言），多说一点，相比较C而言，C++在这一点就做的和好，尽管C++中，虽然采用指针也可以修改内存地址的数据，但是C++编译器编译时对其进行了优化，读取数据的时候，是不在内存地址读取的。不知道这样能否解决你的问题。 可以看看这个例子：http://www.cnblogs.com/gongxijun/p/4375458.html  加 volatile 关键字的变量才会每次从内存中读取, 否则编译器会结合上下文进行优化

user: user-9
content: const int a = 0; a的值不能改  int  b = 0; int c = 0; const int* a = &b; 还是a的值不能改，但a指向的地址里的内容是可以改的 之后在执行 a=&c 就是错误的了

user: user-10
content: http://goobbe.com/questions/2910914/does-const-just-mean-read-only-or-something-more-in-c-c

user: user-0
content: 引用 15 楼 tangtangtangbaoli 的回复:首先,源代码内的各种变量,在编译链接以后生成的执行文件中都被转变成了内存的相对地址,运行时cpu会根据寄存器保存的绝对地址+相对地址 = 通过地址总线译码找到真正的物理地址 然后通过数据总线去读入或写人数值     char a[]="abcd"; //a变量在内存j就是比如地址0x1000,里面存放了31 32 33 34 就是abcd字符的ascill码     const char* b=a; //b变量在内存就是比如地址0x8000,但注意这个0x8000是在内存的常量区,这段地址里面的值被赋值后是不能被改写的,里面放了一个值0x1000,     //b[0]='!'; a[0]='f'; //然后通过这条指令对地址0x1000写人一个值,这个就是跟0x8000里面那个x1000没一点关系了!!!     printf("%s\n",b); 解释挺不错。 但是b真的在常量区？ b确定在常量区吗？b指针不是应该在栈区吗，他是局部变量啊

user: user-11
content: 这里指针b是指向常量的指针变量，只是不能通过指针b改变它指向的对象的值，通过a改变没问题。而且这里b指针的指向也可以改变。谭浩强的c++程序设计讲的很清楚

user: user-12
content: 引用 7 楼 q328965539 的回复:[quote=引用 3 楼 Falleyes 的回复:] a不是指向const数据，所以a可以修改数据内容。 b声明为const char* b=a;意思是说不能通过b这个指针改变其所指向的数据。跟a能不能修改没有关系。 有深层次点的解释么，我是想知道为什么不能通过b这个指针改变其所指向的数据？ 内部是不是const指定那块内存为只读的？（事实证明那块内存还是可读写的） 还是用const去限制了这个指针去读那块内存？那又是怎么限制的，这机制怎么实现的？[/quote] 这些都是编译器做的，编译器会检查有没有对const修饰内容做修改，若发现编译时刻就告诉你错误了。

user: user-13
content: 这个问题，关乎这一点，首先C语言是一种弱类型的语言。也就是说每次读取数据的时候，都会从内存地址中读取，尽管用const修饰，但是内存的内容依旧可以修改（弱类型语言），多说一点，相比较C而言，C++在这一点就做的和好，尽管C++中，虽然采用指针也可以修改内存地址的数据，但是C++编译器编译时对其进行了优化，读取数据的时候，是不在内存地址读取的。不知道这样能否解决你的问题。 可以看看这个例子：http://www.cnblogs.com/gongxijun/p/4375458.html

user: user-14
content: 引用 8 楼 q328965539 的回复:int main(void) {       const int a=10;    int* p=(int*)(&a);    *p=20;    cout<<a<<" "<<*p<<endl;    return 0; } 这样又如何？阿里面试题

user: user-8
content: const 常量符其实在 c\c++ 中被认为是多余的了, 最多的作用是提示自己或提示交接项目的人, 这个变量或地址不能被更改而已 它只能在编译的时候提示你有非法修改, 熬过了编译到了实际运行阶段, 与普通的变量是一个样

user: user-0
content: int main(void) {       const int a=10;    int* p=(int*)(&a);    *p=20;    cout<<a<<" "<<*p<<endl;    return 0; } 这样又如何？

user: user-0
content: 引用 3 楼 Falleyes 的回复:a不是指向const数据，所以a可以修改数据内容。 b声明为const char* b=a;意思是说不能通过b这个指针改变其所指向的数据。跟a能不能修改没有关系。 有深层次点的解释么，我是想知道为什么不能通过b这个指针改变其所指向的数据？ 内部是不是const指定那块内存为只读的？（事实证明那块内存还是可读写的） 还是用const去限制了这个指针去读那块内存？那又是怎么限制的，这机制怎么实现的？