const介绍

const是一个C语言(ANSI C)的关键字,具有着举足轻重的地位。它限定一个变量不允许被改变,产生静态作用。使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一定帮助。另外CONST在其它编程语言中也有出现,例如Pascal、C++、PHP5、B#.net、HC08 C、C#等。

https://baike.baidu.com/item/CONST/1036


const 关键字

您可以使用 const 前缀声明指定类型的常量,如下所示:

const type variable = value;

具体请看下面的实例:

实例

#include <stdio.h> int main()
{ const int LENGTH = 10; const int WIDTH = 5; const char NEWLINE = '\n';int area; area = LENGTH * WIDTH; printf("value of area : %d", area); printf("%c", NEWLINE); return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

value of area : 50

请注意,把常量定义为大写字母形式,是一个很好的编程实践。

http://www.runoob.com/cprogramming/c-constants.html


const笔记

const 定义的是变量不是常量,只是这个变量的值不允许改变是常变量!带有类型。编译运行的时候起作用存在类型检查。

define 定义的是不带类型的常数,只进行简单的字符替换。在预编译的时候起作用,不存在类型检查。

1、两者的区别

(1) 编译器处理方式不同

  • #define 宏是在预处理阶段展开。
  • const 常量是编译运行阶段使用。

(2) 类型和安全检查不同

  • #define 宏没有类型,不做任何类型检查,仅仅是展开。
  • const 常量有具体的类型,在编译阶段会执行类型检查。

(3) 存储方式不同

  • #define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。(宏定义不分配内存,变量定义分配内存。)
  • const常量会在内存中分配(可以是堆中也可以是栈中)。

(4) const 可以节省空间,避免不必要的内存分配。 例如:

#define NUM 3.14159 //常量宏
const doulbe Num = 3.14159; //此时并未将Pi放入ROM中 ......
double i = Num; //此时为Pi分配内存,以后不再分配!
double I= NUM; //编译期间进行宏替换,分配内存
double j = Num; //没有内存分配
double J = NUM; //再进行宏替换,又一次分配内存!

const 定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象 #define 一样给出的是立即数,所以,const 定义的常量在程序运行过程中只有一份拷贝(因为是全局的只读变量,存在静态区),而 #define 定义的常量在内存中有若干个拷贝。

(5) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

(6) 宏替换只作替换,不做计算,不做表达式求解;

宏预编译时就替换了,程序运行时,并不分配内存。

http://www.runoob.com/cprogramming/c-constants.html


指针与const

下面分别用const限定不可变的内容是什么?

1)const在前面

const int nValue; //int是const

const char *pContent; //char是const, pContent可变

const char* const pContent; //pContent和*pContent都是const

2)const在后面,与上面的声明对等

int const nValue; //nValue是const

char const * pContent; //*pContent是const, pContent可变

char* const pContent; //pContent是const,*pContent可变

char const* const pContent; //pContent和*pContent都是const

答案与分析:

const和指针一起使用是C语言中一个很常见的困惑之处,在实际开发中,特别是在看别人代码的时候,常常会因为这样而不好判断作者的意图,下面讲一下我的判断原则:

const只修饰其后的变量,至于const放在类型前还是类型后并没有区别。如:const int a和int const a都是修饰a为const。注意*不是一种类型,如果*pType之前是某类型,那么pType是指向该类型的指针

一个简单的判断方法:指针运算符*,是从右到左,那么如:char const * pContent,可以理解为char const (* pContent),即* pContent为const,而pContent则是可变的。

例一

int const * p1,p2;

p2是const;(*p1)是一整体,因此(*p1)是const,但p1是可变的。int * p1,p2只代表p1是指向整型的指针,要表示p1、p2都是指针是需写成int * p1,* p2。所以无论是* const p1,p2还是const * p1,p2,里面的*都是属于p1的。

例二

int const * const p1,p2;

p2是const,是前一个const修饰的,*p1也被前一个const修饰,而p1被后一个const修饰。

例三

int * const p1,p2;

p1是const,(* const p1)是整体,所以const不修饰p2。

例四

指针指向及其指向变量的值的变化

const在*的左边,则指针指向的变量的值不可直接通过指针改变(可以通过其他途径改变);在*的右边,则指针的指向不可变。简记为“左定值,右定向”。

1)指针指向的变量的值不能变,指向可变

int x = 1;

int y = 2;

const int* px = &x;

int const* px = &x; //这两句表达式一样效果

px = &y; //正确,允许改变指向

*px = 3; //错误,不允许改变指针指向的变量的值

2)指针指向的变量的值可以改变,指向不可变

int x = 1;

int y = 2;

int* const px = &x;

px = &y; //错误,不允许改变指针指向

*px = 3; //正确,允许改变指针指向的变量的值

3)指针指向的变量的值不可变,指向不可变

int x = 1;

int y = 2;

const int* const px = &x;

int const* const px = &x;

px = &y; //错误,不允许改变指针指向

*px = 3; //错误,不允许改变指针指向的变量的值

补充

在c中,对于const定义的指针,不赋初值编译不报错,

int* const px;这种定义是不允许的。(指针常量定义的时候对其进行初始化)

int const *px;这种定义是允许的。(常指针可以再定义的时候不初始化)

但是,在C++中

int* const px;和const int* const px;会报错,const int* px;不报错。

必须初始化指针的指向int* const px = &x;const int* const px=&x;

强烈建议在初始化时说明指针的指向,防止出现野指针!

https://baike.baidu.com/item/CONST/1036

【 C 】const 学习笔记相关推荐

  1. 2020-09-21C++学习笔记之与C语言区别和加强——四种const意义(const int a; int const b; const int *c; int * const d)

    2020-09-21C++学习笔记(const int a; int const b; const int *c; int * const d) 这两天在上课更新晚了. 1.C/C++中的const ...

  2. ES6基础(var let const 箭头函数)-学习笔记

    文章目录 ES6基础(var let const 箭头函数)- 学习笔记 定义:var let const 箭头函数 数据结构 set map ES6基础(var let const 箭头函数)- 学 ...

  3. ES6学习笔记02:let 与 const

    ES6学习笔记02:let 与 const 用var声明的变量会造成全局污染,于是就产生了新的声明方式. 1.let 用let声明变量,必须先声明后使用. 在for循环头里用let定义循环变量i,那么 ...

  4. JavaScript:学习笔记(7)——VAR、LET、CONST三种变量声明的区别

    JavaScript:学习笔记(7)--VAR.LET.CONST三种变量声明的区别 ES2015(ES6)带来了许多闪亮的新功能,自2017年以来,许多JavaScript开发人员已经熟悉并开始使用 ...

  5. SVO 学习笔记(深度滤波)

    SVO 学习笔记(深度滤波) 这篇博客 论文中的深度滤波 深度滤波的代码流程 更新Seed对象 初始化Seed对象 结尾 这篇博客  这篇博客将介绍SVO论文中的Mapping部分,主要介绍深度滤波器 ...

  6. SVO 学习笔记(三)

    SVO 学习笔记(三) 这篇博客 Initialization Frame_Handler_Mono processFirstFrame processSecondFrame processFrame ...

  7. SVO学习笔记(二)

    SVO学习笔记(二) 这篇文章 稀疏图像对齐 地图点投影(地图与当前帧间的关系) reprojectMap reprojectPoint reprojectCell 特征点对齐中的非线性优化 结尾 这 ...

  8. SVO学习笔记(一)

    SVO学习笔记(一) 这篇文章 Frame Featuredetection Featrue_matcher 三角测量求深度 特征匹配 非线性优化寻找匹配特征 极线搜索匹配特征 总结 这篇文章  一个 ...

  9. 【学习笔记】线性代数全家桶(在编程竞赛中的应用)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 0x00. 矩阵 0x01. 矩阵 0x02. 矩阵的加法与数量乘法 0x03. 矩阵乘法 0x ...

最新文章

  1. asp.net程序性能优化的七个方面
  2. 录入键盘字母输入并将小写变为大写
  3. python经典好书-推荐几本高质量的Python书籍--附github下载路径
  4. 解决查询时报的cannot be cast to com.credithc.enjoy.manager.OrderResp错误
  5. echarts 有引导线和内部文字_点、线、面构图的异同以及相互转化
  6. php使用未定义常数,php-使用未定义的常量SIGTERM-gt;假定为’SIGTERM’
  7. 参加 CSDN 2009 英雄大会有感(二)
  8. Ubuntu 学习系列-安装Flash播放器
  9. 【天锐绿盾】之常见问题处理:控制台登录提示采集服务器空间不足,修改数据保存时间
  10. python有趣的简单代码-盘点10个一行强大的、有趣的Python源代码
  11. Go语言-测试与性能分析
  12. 三菱PLC与上位机进行通讯
  13. php脚本是什么,PHP脚本的编写
  14. 最新使用Python进行开发网站教程项目实战(完整)
  15. 微信小程序chooseMedia应用
  16. “矢量网络分析仪”检测同轴电缆的驻波比(SWR)
  17. 计算机讲Word文档中的组合,电脑Word文档中两个表格如何合并
  18. 深度学习epochs、batch、batch_size和iteration的区分
  19. 基于matlab的正交振幅调制与解调,正交幅度调制和解调(QAM)
  20. 区块链学习笔记21——ETH智能合约

热门文章

  1. WISEGATE:SIEM的最佳实践讨论
  2. django in的一点心得
  3. SES机箱管理知识回顾(四)之SES Over SAS
  4. ali arthas 火焰图_带你上手阿里开源的 Java 诊断利器:Arthas
  5. 原生 遍历_细品原生JS从初级到高级知识点汇总(三)
  6. python返回unicode_Python 中通过 unicode 码返回单字符的函数是 ,返回单字符 unicode 码的函数是 。_学小易找答案...
  7. 危险工种 机器人逃生记_袋料自动搬运机器人为什么能取代人工搬运
  8. 计算机二级各个科目的作用,计算机二级考试的各个科目的内容及区别.doc
  9. 常用计算机主要硬件设备,个人计算机常用的输出设备41.计算机硬件的组成部分主要包括:...
  10. php 复选框 数组,php数组的复选框