| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C语言中关于const关键字的用法及详解 -> 正文阅读 |
|
[C++知识库]C语言中关于const关键字的用法及详解 |
前言:C90标准新增了const关键字,用于限定一个变量为只读,const类型限定符声明的是变量,不是常量,使其成为一个只读值,也就是说可以在计算中使用它,也可以打印它,但是不能改变它的值,并且,const推出的初始目的就是为了取代预编译指令,消除它的缺点同时继承它的优点。
一.我们先来介绍一下什么是const: 我们通常用类型和存储类别来描述一个变量。C90还新增了两个属性:恒常性(constancy)和易变形(volatility),两个关键字const和volatile,以这两个关键字创建的类型是限定类型(qualified type)今天我们所讲的关键字const就是来声明恒常性的,通常有很多地方也把修饰的变量叫做常变量(即给一个变量赋予恒常性,处理时当常量来看待)。???????? C99标准为类型限定符增加了一个新属性,他们具有幂等性质,意思是在一条声明中多次使用同一个限定符,多余的限定符将被忽略:
有了这个新属性,就可以编写类似下面代码:
二.const与#define指令相比的优点: 如果一个变量被const修饰,那么他的值就不能再改变,那么有人会提出这样的疑问,C语言中不是有#define嘛?干嘛还要用const呢?所以比较之后又如下优点: 1.预编译指令只是对值进行简单的替换,不能进行类型检查。 2.可以保护被修饰的变量,防止意外修改,增强程序的健壮性。 3.在C++语言中编译器通常不为普通的const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。 三.const与static的对比 static修饰的变量为静态变量,存储再全局(静态)区,生命周期从程序编译到运行结束。 const修饰的变量不会存放在全局(静态)区,而是取决于它定义的地方,局部定义的就存在栈区,全局定义的就存放在静态区。 四.const修饰局部变量的用法如下: 1.const修饰过的变量不能直接的改变。
2.可以初始化const变量。 初始化后就不能改变他的值了,也就是不能再次重定义或者再次初始化这个变量。
3.const关键字创建不允许修改的数组:
如果使用C99之后的编译器,还可以创建如下数组:
此时数组内有a=10个元素,这个a我们不能改变它了,但是这个数组我们并没有用const修饰,所以我们可以进行以下操作:
如果我们不希望数组可以改变,那我们得在数组前加一个const限定符:const int arr[a]? 4.const修饰一个常量静态字符串:
如果没有const修饰那么可以有意无意的将str[1]='x'这样的操作,但是加上const之后,这个错误就能在程序被编译的时候立即检查出来,这就是const的好处。让逻辑错误能够在编译器发现。 const修饰全局变量的用法如下: 使用全局变量是一种冒险的方法,因为这样做暴露了数据,程序的任何部分都能修改数据。如果把数据设置为const,就可以避免这样的危险,因此使用const限定符声明全局变量很合理。可以创建const变量,const数组,const结构。 当然,在文件之间共享const数据要小心。可以采用两个策略: 第一,遵循外部变量的使用规则,即在一个文件中使用定义式声明。在其他文件中使用引用式声明(即用extern关键字)。 第二,把const变量放在一个头文件中,然后在其他文件中包含此头文件即可。但是这种方案必须要求在头文件中使用关键字static声明全局const变量。因为如果去掉static变量,那么假设两个文件 file1.c 和 file2.c 使用了同一个头文件constant.h? 那么将导致每个文件中都有一个相同的标识符的定义式声明,C标准不允许(虽然有些编译器允许)这么做。加上static关键字实际上是给每个文件都提供了一个单独的数据副本,每个副本只对该文件可用。 两种方案,方案二使用头文件的好处是方便你偷懒,不用惦记着在一个文件中使用定义式声明,另一个文件中使用引用式声明,只需要包含同一个头文件即可,但是缺点也有,就是导致数据是重复的,如果头文件中某个static const修饰的变量过于庞大,就会出现一些问题。 变量指针,指针变量与指向常量的常指针: 常量指针是指针指向的内容是常量,下面两种定义方式是相同的:
常量指针说的是不能通过这个指针改变变量的值(但是可以通过其他方式改变变量的值)。
还有一点重要的是常量指针指向的值不能改变,但是这部意味着指针本身不能改变,常量指针也可以指向其他地方的地址。
指针常量是指指针本身是个常量,不能再指向其他的地址,写法如下: int? * const n; 如下是使用的例子
我们不难发现指针常量和常量指针的区别就在于星号的位置: int const *n是常量指针? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ?int * const n是指针常量 指向常量的常指针 是以上两者的结合,写法如下
指针ptr指向的位置不能改变,并且也不能通过指针ptr改变变量的值,但是依然可以通过其他的变量指针(例如再定义一个指针*p指向同一个值a,可以通过指针*p来操作这个值)改变变量的值。 ? 拓展到作为函数参数的思考: 根据以上的讨论那么const修饰函数的参数也有三种用法: 1.防止修改指针指向的内容: int Add(const int *a,const int *b,int sum); 其中a和b是输入的参数,sum是待输出的参数。给a和b加上const修饰后,如果函数体内的语句试图改动a和b的内容,编译器将报错。 2.防止修改指针指向的地址: int swap(int *const p1,int * const p2); 指针p1和指针p2指向的地址都不能改变。 3.即防止修改指针指向的内容,又防止修改指针指向的地址; 例如 void sort(int const *const p1,int const *const p2?); 拓展到作为函数返回值的思考: C标准定义了如下规则 把const数据或非const数据的地址初始化为指向const的指针或为其赋值的合法的。
但是只能把非const数据的地址赋给普通指针。
这个规则十分合理,否则,通过指针就能改变const数组中的数据。 总结:const限定符经常常用,学以致用const是变成大佬路上必须要学会的操作!但是众多细节不能忽略,仔细分析const用在哪里,联系它的不同用法。 最后还有一点关于引起我思考问题的解答,(a++)这个操作是创建一个a的副本进行运算,原来的a再自增,所以参加运算的那部分地址是临时创建的,不能作为左值。但是(++a)是直接对a进行自增操作再运用的,所以这个可以用来作为左值。 创作不易,麻烦各位读者点个赞或者关注激励一下作者! ? ? ? ? ? ? ? |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 5:39:36- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |