关于C++中const的一些研究

       最近复习的过程中发现网上对于const的说法不一,让人摸不着头脑,为了搞清其原理,决定通过反汇编的方式来看一看其内部究竟发生了什么,下面是一篇简单的介绍反汇编指令的文章,用来理解本次所研究的东西已经足够

https://www.lagou.com/lgeduarticle/1754.html

下面将按照一个观点一个例子的方式来进行:(该测试基于VS2017环境)

1.将字面值赋给const变量时,会在编译期间将程序中用到该变量的地方替换成对应的数值(类似于宏替换),同时该变量在内存中分配空间,通过指针也可以对该变量的内容进行更改,但不会影响到程序中使用const变量的地方,因为程序真正执行的时候,const变量所在的地方已经替换成了字面值,例如

#include<iostream>

int main()

{

    const int x = 12;

    int *ppx = (int *)&x;

    *ppx = 13;

    int b = *ppx;

    int c = x;

    std::cout << "*ppx = " << *ppx << " x = " << x << std::endl;

    std::cout << "b = " << b << " c = " << c << std::endl;

    system("pause");

}

 

其反汇编的结果为:

从结果分析可知,

在1处,程序将字面值0Ch直接赋值给了x变量

在2处,程序通过指针访问x变量的地址,将0Dh赋值给了x所在的内存位置

其过程可由下图看出

执行前:

执行后:

在3处,程序通过访问x变量所在的内存地址将值取出并赋给变量b

在4处,本应将x变量的值赋给变量c,但在反汇编结果中可见,程序将字面值0Ch直接赋给了变量c,而没有通过地址取值

 

2.若通过一个变量赋值给一个const变量,那么上面的说法将不再成立,经过试验发现,此种情况下const限制只对变量名访问有效,对于指针修改的方式并不能起到限制写的作用,试验过程如下:

#include<iostream>

//此代码相对于上一个例子只是将x变量赋值的方式改变,其余位置不变

int main()

{

    int y = 12;

    const int x = y;

    int *ppx = (int *)&x;

    *ppx = 13;

    int b = *ppx;

    int c = x;

    std::cout << "*ppx = " << *ppx << " x = " << x << std::endl;

    std::cout << "b = " << b << " c = " << c << std::endl;

    system("pause");

}

其反汇编的结果为:

此次反汇编结果仅1,2两处与先前不同,中间部分一致,不再赘述

从结果分析可知:

通过变量赋值方式初始化的const变量,其赋值时需要访问原变量的地址

通过此方式初始化的const变量,在使用时也会到内存中取它的值,而不会像上一个例子中一样做宏替换

 

3.代码中出现字符串的地方都会在内存常量区中保存,若同一个字符串在代码中多次出现,编译器会自动识别,不会重复产生同样的串

#include<iostream>

#include<string>

int main()

{

    std::string *s = new std::string("aaa");

    const char *cptr = "aaa";

    char * cptr1 = (char *)"bbb";

    char ch[] = "aaa";

   

    system("pause");

}

其反汇编的结果为:

       观察1.2.4可看出,当程序中使用同一个字符串时,编译器并不会产生新的串,而是共用一块地址中的内容,当串不同时,才会在常量区中保存新的串

       观察2.3并结合图二可看出,当使用指针指向常量区中的地址时,由于常量区的内容本身就是不可更改的,因此,用不用const都是一样的,即使强制类型转换为普通指针修改了其中的内容,也会在运行时产生异常

       观察2.4可看出,使用指针指向常量时,指针变量内存入的是常量区中常量的地址值,而使用字符数组保存字符串时,编译器会将常量区中的常量复制一份赋给栈中的字符数组空间

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值