C语言中的const

const修饰的变量是只读的,本质还是变量

const修饰的局部变量在栈上分配空间

const修饰的全局变量在只读存储区分配空间

const只在编译期有用,在运行期无用

注意:const修饰的变量不是真的常量,它只是告诉编译器该变量不能出现在赋值符号的左边。

总结:

C语言中的const使得变量具有只读属性

const将具有全局生命周期的变量存储于只读存储区

const不能定义真正意义上的常量!

C语言中只有通过enum定义的标识符才是真正意义上的常量。

编程实验

C/C++中的const

假设为test.c

 #include <stdio.h>

 int main()

 {

   const int c = ;

   int *p = (int*)&c;

   printf("Begin...\n");

   *p = ;

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

   printf("End ...\n");

   return ;

 }

1)利用C编译器,即执行

gcc test.c

./a.out

得到C的值为5;

2)利用C++编译器,即执行

g++ test.c

./a.out

得到C的值是0,

说明第13行*p = 5 不起作用了。

同一个程序用C语言编译器和用C++编译器编译得到的运行结果不同。

下面再来修改程序,观察程序的运行结果:

 #include <stdio.h>

 int main()

 {

   const int c = ;

   int *p = (int*)&c;

   printf("Begin...\n");

   *p = ;

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

      return ; 

 }

利用C编译器,得到

c = 5;

*p = 5;

利用C++编译器,得到

c = 0;

*p = 5;

为什么会这样呢?

说明了const关键字在从C语言到C++语言的进化中得到了很大的改变。那么变化究竟在哪里呢?

C++在C的基础上对const进行了进化处理

——当碰见const声明时在符号表中放入常量

——编译过程中若发现使用常量则直接以符号表中的值替换

——编译过程中若发现下述情况则给对应的常量分配存储空间(C++天生兼容C语言,也会有给常量分配空间的情况)

  对const常量使用了extern

  对const常量使用了&操作符

注意:

C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值。(就是为了兼容C语言,兼容的意义就在于以前用C编译器编译过得程序,也能用C++编译器编译过,但运行的结果可能不同)

C语言中的const变量

——C语言中const变量是只读变量,会分配存储空间

C++中的const常量(从C语言中的只读变量变为一个常量了,但为了兼容C语言,可能为常量分配空间)

——可能分配存储空间

  当const常量为全局,并且需要在其他文件中使用

  当使用&操作符对const常量取地址

C++中的const常量类似于宏定义

——const int c = 5; 约等于 #define c 5

C++中的const常量在与宏定义不同

——const常量是由编译器处理

——编译器对const常量进行类型检查和作用域检查

——宏定义由预处理器处理,单纯的文本替换

const与宏的代码分析

 #include <stdio.h>

 void f()
{
#define a 3
const int b = ;
} void g()
{
printf("a = %d\n", a);
//printf("b = %d\n", b);
} int main()
{
const int A = ;
const int B = ;
int array[A + B] = {};
int i = ; for(i=; i<(A + B); i++)
{
printf("array[%d] = %d\n", i, array[i]);
} f();
g(); return ;
}

1)用C语言编译器进行编译,会发现出错。出错的地方在于:

int array[A + B] = {0};
虽然A与B是由const修饰的,根据上面所学的知识,A和B都是只读变量。数组的长度用两个变量相加,相加的结果到运行的时候才知道,
编译器就不乐意了,因此肯定会出错。

2)用C++编译器进行编译,就通过了。

此时A和B就是真正意义上的常量了。因此A+B也是常量

注意一个地方:

在g()函数中直接访问f()函数所定义的宏变量,结果没有出错,为什么?

因为宏是被预处理所处理的,直接进行文本替换,编译器压根不知道宏是什么,根本不知道宏的存在。其实,编译器看到的是这样的代码:

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

说明宏是没有作用域的概念的。

在g()函数中调用

printf("b = %d\n", b);是不对的。

小结:

与C语言不同,C++中的const不是只读变量

C++中的const是一个真正意义上的常量

C++编译器可能会为const常量分配空间

C++完全兼容C语言中const常量的语法特性


进化后的const分析的更多相关文章

  1. C++解析(2):进化后的 const 分析

    0.目录 1.C语言中的const 2.C++中的const 3.对比 3.1 C语言与C++中的const 3.2 C++中的const与宏定义 4.小结 1.C语言中的const const修饰的 ...

  2. 第3课 进化后的 const分析

    1.  C语言中的const (1)const修饰的变量是只读的,使得变量具有只读属性,但本质还是变量.所以不是真正的常量,它只是告诉编译器该变量不能出现在赋值符号的左边. (2)const修饰的局部 ...

  3. 第3课 进化后的const分析

    C语言中的const const修饰的变量是只读的,本质还是变量 const修饰的局部变量在栈上分配空间(改变这个空间的值,这个变量就会改变) const修饰的全局变量在只读存储区分配空间 const ...

  4. 第3课.进化后的const

    1.c语言中 const修饰的变量是只读的,本质上还是变量 const修饰的局部变量在栈上分配空间(因为在栈上分配空间,所以我们可以通过改变这个空间的值.间接去改变这个变量.) const修饰的全局变 ...

  5. C++ 成员函数前和函数后加const修饰符区别

    博客转载自: https://www.iteblog.com/archives/214.html 分析以下一段程序,阐述成员函数后缀const 和 成员函数前const 的作用 #include< ...

  6. [阿里DIEN] 深度兴趣进化网络源码分析 之 Keras版本

    [阿里DIEN] 深度兴趣进化网络源码分析 之 Keras版本 目录 [阿里DIEN] 深度兴趣进化网络源码分析 之 Keras版本 0x00 摘要 0x01 背景 1.1 代码进化 1.2 Deep ...

  7. [Reprint]C++函数前和函数后加const修饰符区别

    c++中关于const的用法有很多,const既可以修饰变量,也可以函数,不同的环境下,是有不同的含义.今天来讲讲const加在函数前和函数后面的区别.比如: 01 #include<iostr ...

  8. C++函数前和函数后加const修饰符区别

    class Test(){ public: Test(){} const int foo(int a); const int foo(int a) const; }; 一.概念 当const在函数名前 ...

  9. C++类的成员函数的形参列表后面的const

    看到(C++ Primer)类的成员函数这里,突然对成员函数形参列表后面的const感到迷惑. 因为书中开始说是修饰隐含形参this的,然后又说是声明该函数是只读的. 大为不解! 翻资料.找人讨论.. ...

随机推荐

  1. jmeter BeanShell的几种使用方式

    jmeter的BeanShell Sampler,可以直接引用java代码,有下面3种方式: 1.直接输入java代码:2.导入java文件:3.导入class文件 BeanShell脚本访问变量主要 ...

  2. luoguP2597 [ZJOI2012]灾难

    题意 这题思路好奇怪啊 见到有向无环图显然是要拓朴排序,不妨按照被吃向吃连边,那么\(x\)灭绝当且仅当x的入点都灭绝,于是考虑怎样x的入点都灭绝 比如4号节点,它灭绝当且仅当2和3灭绝,2和3灭绝当 ...

  3. luoguP1791 [国家集训队]人员雇佣

    题意 考虑先将所有价值加上,之后用最小割求最小代价. 考虑每个点对\((i,j)\),我们这样建边: 1.源点向每个点i连\(\sum\limits E_{i,j}\)容量的边. 2.每个点向汇点连雇 ...

  4. go 通过select实现超时

    package main import ( "fmt" "time" ) func main() { ch := make(chan int) quit := ...

  5. ESP8266 LUA脚本语言开发: 外设篇-GPIO中断检测

    https://nodemcu.readthedocs.io/en/master/modules/gpio/#gpiomode 测试引脚 GPIO0 gpio.mode(,gpio.INT) func ...

  6. Protobuf 文件导入和生成

    build: protoc -I=$(GOPATH)/pkg/mod/github.com/micro/micro@v1.13.1/api/proto -I /Users/lzy/Git/Learn/ ...

  7. vs安装包离线下载

    1.首先打开visual studio 的官网下载最新的安装程序. https://www.visualstudio.com/zh-hans/?rr=https%3A%2F%2Fwww.baidu.c ...

  8. Redis的Sorted-Sets排行榜功能实现

    Redis的ZSet排行榜功能实现 1. 功能需求 类似给用户n张图片, 用户左滑不喜欢右滑喜欢.所以每个用户就会有一些喜欢的图片集合和不喜欢的图片集合.现在我们要做一个将按照一个算法将喜欢的排到前面 ...

  9. IL 语法分析

    Managed Heap: GC auto manage. One process, One heap. Call Stack: Runtime auto manage, every time whe ...

  10. python 统计使用技巧

    python 统计使用技巧 # 1.不输入回车获取值 注:需要tty模块配合. fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) ...