up16367 发表于 2022-11-13 16:40:48

常量指针的问题

在带你学C带你飞的p27,常量和指针那里,我知道了
const int cnum = 1;
int num = 10;
const int * const p = &cnum;
这样的话,p的指向不能改变,也不能通过解引用去修改值。我当时就想我要是指向的是num呢,小甲鱼后面就讲到了,然后我又想到,既然你通过两个const限制了p,外层限制的是解引用,内层限制的是p,那么我要是指向一个const量,是不是就可以省掉外层的const,有了下面的代码
#include <stdio.h>


int main()
{

          int num = 100;
          const int cnum = 1024;
          int * const p = &cnum;

          printf("cnum = %d,&cnum = %p\n",cnum,&cnum);
          printf("*p = %d,p = %p\n",*p,p);
          *p = 1023;
//      p = &num;

          printf("cnum = %d,&cnum = %p\n",cnum,&cnum);
          printf("*p = %d,p = %p\n",*p,p);
          return 0;
}
注释部分会报错,这个能理解,但是为啥解引用那里真的修改成功了,一个地址能有两个值?
执行结果如下:
gcc test3.c && ./a.out
test3.c:9:14: warning: initializing 'int *const' with an expression of type 'const int *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
      int * const p = &cnum;
                  ^   ~~~~~
1 warning generated.
cnum = 1024,&cnum = 0x16cfa74a4
*p = 1024,p = 0x16cfa74a4
cnum = 1024,&cnum = 0x16cfa74a4
*p = 1023,p = 0x16cfa74a4

jackz007 发表于 2022-11-13 17:37:31

本帖最后由 jackz007 于 2022-11-13 17:40 编辑

const int *p
       const 限制的是作为指针的变量 p 的值的改变(不允许为 p 赋值),但是并不限制 p 所指向存储空间内变量值的改变。对 p 限制修改是通过把这个变量储存在特定的常变量区得到落实,这个区域的变量不允许修改是系统机制性的策略,用户绝对不可能通过任何的旁门左道变通绕过限制而实现修改。

love_V 发表于 2022-11-14 14:59:05

Const关键字只是编译器限制 你这个值都在栈里 用指针当然可以改了

up16367 发表于 2022-11-14 17:29:29

love_V 发表于 2022-11-14 14:59
Const关键字只是编译器限制 你这个值都在栈里 用指针当然可以改了

但是我打印的cnum依然是1024

xiaotubie 发表于 2022-11-15 15:18:58

本帖最后由 xiaotubie 于 2022-11-15 18:13 编辑

const int cnum = 1024;
int * const p = &cnum;   你这样写按理是会报错的,会说类型不一致。

const int cnum = 1024;
int * const p =(int*) &cnum;强制转换下这样就不会报错了
*p=1023;

你说的通过*p去修改掉cnum是可以,实际也已经修改掉了
因为const修饰了哪个变量,只是让程序员无法通过该变量去修改而已,绕过该变量去修改是可以的
至于你说为什么打印cnum还是原来的值,其实是假象

因为当你定义一个变量为const 的时候,编译器认为该变量不能改变了,直接把你代码中用到cnum值的地方,全部替换成1024
编译器相当于把你的代码改成了这样   printf("cnum = %d,&cnum = %p\n",1024,&cnum); 直接把cnum替换成了1024
实际cnum内存中的那个值已经改变了


页: [1]
查看完整版本: 常量指针的问题