关于C、C++中的const和指针

11 篇文章 0 订阅

偶然的因素,对const来了点兴趣,做了一下实验:

1. 语法:const、指针

       gcc中, 对于C语言,下面的语句是合法的:

const int a=0;

int *p=&a;

      C++中,需要手工强制转换才能编译通过:

           const int a=0

           int *p=int *&a

2.  既然能够将const变量的地址赋给指向非const变量的指针,那么能否改变通过指针改变const变量的值呢?

    1)gcc中,编译执行以下代码:

const    int c=2;

      int *p=&c;

      *p=1;

printf("c is :%d/n",c);

编译时会有警告:警告:初始化丢弃了指针目标类型的限定

结果为:

c is 1

 

说明虽然有警告,但是顺利编译通过,并且成功改变了常量c的值(从2变为1)。

     2.接下来看下面一段代码:

#include <stdio.h>

#include <unistd.h>

int main(void)

{

      const   int c=2;

      int a=0;

     

      const int *p;

      p=&a;

     

      int *p2=&a;

      p2[1]=-1;

 

      printf("p2[1] is :%d/n",p2[1]);

      printf("a is :%d/n",a);

      printf("c is :%d/n",c);

      printf("c address is:%d/n",&c);

      printf("p2[1] address is:%d/n",p2+1);

      printf("*(&c) is :%d/n",*(&c));

}

这段代码,程序会有怎样的输出呢?

1.保存为后缀为.c的文件,用gcc编译,执行结果如下:

p2[1] is :-1

a is :0

c is :-1

c address is:-1076230280

p2[1] address is:-1076230280

*(&c) is :-1

说明p2+1的地址和c的地址一样,程序成功的间接改变了c的值(p2越界访问,不容易看出)

 

考虑一下这段代码在C++中会有怎样的表现呢?

保存后.cpp的文件,用g++编译,执行结果如下:

c is :2

p2[1] is :-1

a is :0

c is :2

c address is:-1077876024

p2[1] address is:-1077876024

*(&c) is :2

    这个就奇怪了……

    明明p2[1]的地址和c的地址一样,为什么p2[1]的值和c不一样呢?

后来想到因为c是常量,编译器可能优化,将c放入寄存器,取值的时候取的是寄存器的值,内存里面的值实际已经被改变了。

为了证实这个想法,我们将c的定义改为:

volatile const    int c=2;

 

    再次用g++编译,执行结果如下:

p2[1] is :-1

a is :0

c is :-1

c address is:-1074816520

p2[1] address is:-1074816520

*(&c) is :-1

    结果证实了我的猜测,c在内存里面的值确实改变了。(注:如果不把c改为volatile,即使将g++设置为-O0,程序输出的c依然是2,囧……)

以上纯粹是无聊所作,没啥大的意义。不过,从这里我也能稍微理解一下那些说“指针不安全”的人了……上面例子中的p2越界竟然改变了const变量。看来const也不一定const啊……同时,g++默认对程序做的优化……这个如果没想到它有可能变量放到寄存器的话,估计对上面默认编译执行的结果会疑惑不已了……囧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值