在.c文件中有程序:

int main()

{

int const a = 10;

a=20;

printf("a=%d\n",a);

return 0;

}

编译就知道C语言编译器会报错,说变量a是常量,常量是不能当左值的,这样看来,好像a是定义的一个常量,不能修改!

修改程序:

int main()

{

int *p;

int const a=10;

p=(int*)&a;

*p=20;

printf("a=%d\n",a);

return 0;

}

定义一个指向变量a的指针变量p,通过指针修改指针p所指向位置的值,也就是a的值,编译运行:

a=20

Press any key to continu

我们发现a的值变成了20,被修改了!

也就是说我们通过指针间接修改了a的值,也就是说在c语言中const是个“冒牌货”。

同样的代码,我们运行在C++环境下:

int main()

{

int *p;

int const a=10;

p=(int*)&a;

*p=20;

printf("a=%d\n",a);

system("pause");

return 0;

}

运行结果:

啊0

请按任意键继续...

发现运行结果跟C语言环境不同,在C++中并没有改变变量a的值。

所以,在C++中,const是一个真正的常量。

问题原因分析:

因为C++编译器对const做了加强,当C++编译器扫描到const常量声明时,它不会像C语言一样为const单独分配内存。

在C++中,int const a = 10;之后,C++编译器会将a放到一个符号表里面,符号表的存在形式:

我们定义常量a=10,key就是a,value就是10,这个值就是锁死了,不能变的,当使用a的时候,就会从符号表里面把10拿出来。

当对a变量取地址的时候,C++编译器会为a单独的开辟一块内存空间,p = (int *)&a;然后这个内存空间赋给指针p,就是p指向这个内存空间。

通过*p去间接修改的值,是这个新开辟的内存空间的值,而不是符号表中a的值,我们让*p=20、30、100…修改的都是新开辟内存空间中的值。我们可以通过打印*p去验证这两个区域并不是一回事。

int main()

{

int *p;

int const a=10;

p=(int*)&a;

*p=20;

printf("a=%d\n",a);

printf("*p=%d\n",*p);

system("pause");

return 0;

}

运行结果:

a=10

*p=20

请按任意键继续...

结论

C语言中的const变量

C语言中的const变量是只读变量,有自己的存储空间。

C++中的const变量

可能分配存储空间,也可能不分配存储空间;

当const常量为全局,并且需要在其它文件中使用时分配内存空间;

当使用&操作符取const常量的地址分配内存空间;

长按解锁

解锁更多精彩内幕

依法编程

微信:Lightspeed-Tech

技术驱动生活

C++笔记十七:C语言中 “冒牌货”const和const符号表的更多相关文章

  1. C语言中无符号数和有符号数之间的运算

    C语言中无符号数和有符号数之间的运算 C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算当然是返回0或1了. un ...

  2. R语言学习笔记1——R语言中的基本对象

    R语言,一种自由软件编程语言与操作环境,主要用于统计分析.绘图.数据挖掘.R本来是由来自新西兰奥克兰大学的Ross Ihaka和Robert Gentleman开发(也因此称为R),现在由“R开发核心 ...

  3. C语言学习笔记:15_c语言中的进制操作.c

    /* * 15_c语言中的进制操作.c * * Created on: 2015年7月5日 * Author: zhong */ #include <stdio.h> #include & ...

  4. 【R笔记】R语言中的字符串处理函数

    内容概览 尽管R是一门以数值向量和矩阵为核心的统计语言,但字符串同样极为重要.从医疗研究数据里的出生日期到文本挖掘的应用,字符串数据在R程序中使用的频率非常高.R语言提供了很多字符串操作函数,本文仅简 ...

  5. c语言中为什么左移不分符号数无符号数,而右移分呢??

    因为在C语言标准中,只规定了无符号数的移位操作是采用逻辑移位(即左移.右移都是使用的逻辑左移和逻辑右移).而对于有符号数,其左移操作还是逻辑左移,但右移操作是采用逻辑右移还是算术右移就取决于机器了!( ...

  6. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅱ

    3.1.2 有序的符号表 典型的应用程序中,键都是Comparable的对象,因此可以使用a.compare(b)来比较a和b两个键.许多符号表的实现都利用Comparable接口带来的键的有序性来更 ...

  7. 《OOC》笔记(1)——C语言const、static和extern的用法

    <OOC>笔记(1)——C语言const.static和extern的用法 C语言中const关键字用法不少,我只喜欢两种用法.一是用于修饰函数形参,二是用于修饰全局变量和局部变量. 用c ...

  8. sqlite学习笔记7:C语言中使用sqlite之打开数据库

    数据库的基本内容前面都已经说得差点儿相同了.接下看看如何在C语言中使用sqlite. 一 接口 sqlite3_open(const char *filename, sqlite3 **ppDb) 打 ...

  9. C语言中关键字auto、static、register、const、volatile、extern的作用

    原文:C语言中关键字auto.static.register.const.volatile.extern的作用 关键字auto.static.register.const.volatile.exter ...

随机推荐

  1. Servlet处理流程分析-Servlet学习之旅(二)

    tomcat的处理处理客户端流程分析 tomcat即是servlet容器也具有web服务器的功能,即也具有html页面的功能. 1.首先客户端会将html请求发给tomcat内置的web服务器 2.w ...

  2. (九十七)集成JPush实现远程通知和推送的发送

    上节介绍了通过直接和APNS交互实现推送的方法,较为繁琐,最为重要的是发送推送需要特定的服务端,通过JPush,不仅可以简化客户端的接收,还可以通过控制台或者API实现通知的发送. 首先注册JPush ...

  3. 学习笔记-JS公开课二

    typeof运算符的使用 JS中内置对象Array/Date/Math/String可以看成引用类型 做如下测试: <scripttype="text/javascript" ...

  4. ubuntu文件管理常用命令

    1.关闭防火墙:ufw disable 2.以.开头的表示隐藏文件 3..和..分别代表当前目录以及当前目录的父目录 4.显示当前用户所在目录pwd 5.touch创建空文件 6.mkdir创建新目录 ...

  5. UNIX网络编程——fcntl函数

    fcntl函数提供了与网络编程相关的如下特性: 非阻塞式I/O.  通过使用F_SETFL命令设置O_NONBLOCK文件状态标志,我们可以把一个套接字设置为非阻塞型. 信号驱动式I/O. 通过使用F ...

  6. 《C语言点滴》书评

    说起C语言方面的书,你最先想到的是哪一本?不论图书本身是好是坏,反正我想到的是谭浩强的<C程序设计>--它已然是一部"圣经"了.那么,为什么赵岩老师还要写一本<C ...

  7. Mybatis源码之(TypeAliasRegistry)TypeAlias别名实现机制

    在Mybatis编程中我们经常会用到将某个bean作为参数类型parameterType或者结果返回值类型ResultType,所以很多时候我们需要把完成的Bean的包名在mapper文件中写上,如下 ...

  8. 【Python】Talk Python To Me Podcast播客

    这是Python相关的一个播客,通过播客的形式给大家讲述python那点事,相关的链接都会列出来,有一些是由文本内容的,如果听不太懂就看看英文原文.不fanqiang的情况下,网页打开没有问题,但是播 ...

  9. JQuery实战总结一 可编辑的表格

    JQuery视频看完了,总结学习,记得在牛腩视频中的修改新闻类别的时候也使用了这样的可编辑的表格,使用到 了ajax控制界面不再刷新,轻松解决了类别的名称的修改的问题,直接提交到数据库,这样的方式比起 ...

  10. 《java入门第一季》之StringBuffer小案例

    这里是针对其反转功能来举的例子,再对比之前写的一篇String类的反转功能,StringBuffer明显提高了代码量,提高了效率. import java.util.Scanner; /* * 把字符 ...