C/C++中的const分析

本文探讨了C/C++中的const关键字,分析了其在C语言中的缺陷和C++中的强化。const用于定义常量,提高代码可读性和系统健壮性。在C语言中,const可以通过指针间接修改,而在C++中,这被视为未定义行为。C++编译器可能为const分配或不分配存储空间,视情况而定。const与#define不同,前者提供类型和作用域检查,后者是文本替换。

const基础知识(用法,含义,好处)

先附上一段C语言代码

#include "stdlib.h"
#include "stdio.h"

int main()
{
	const int a = 1;
	int const b = 1;
	const int *c = 1;
	int * const d = NULL;
	const int * const e = NULL;
	return 0;

}

初级理解:const是定义常量==》const意味着只读。
现在分析一下代码中const修饰的语句的含义:
第一个第二个意思一样 代表一个常整形数,数值不可以直接赋值改变 (C语言中)
第三个 c 是一个指向常整形数的指针 (所指向的内存数据不能被修改,但是本身可以修改)
第四个 d 常指针 (指针变量不能被修改,但是它所指向内存空间可以被修改)
第五个 e一个指向常整形的常指针 (指针和它所指向的内存空间,均不能被修改)

const优点:
合理的利用const有以下两个好处:
1 指针做函数参数,可以有效的提高代码可读性,减少bug。
2 清楚的分清参数的输入和输出特性。

int setTeacher_err( const Teacher *p)

3 const修改形参的时候,在利用形参不能修改指针所向的内存空间,提高系统的健壮性。

C语言中const的缺陷

#include "stdlib.h"
#include "stdio.h"

int main()
{
	const int a = 10;
	int *p = (int*)&a;
	printf("a===>%d\n", a);
	*p = 11;
	printf("a===>%d\n", a);
	return 0;
}

运行结果:
在这里插入图片描述
C语言编译器无法直接对const修饰的变量进行修改,但是可以利用指针来进行间接的修改,这样造成const的不严谨或者说是缺陷,在工作埋下隐患。而C++对这个修饰符const进行的强化。根据C++标准,对于修改const变量,属于:未定义行为(指行为不可预测的计算机代码),这样一来此行为取决于各种编译器的具体实现**(即不同编译器可能表现不同)。 下面在C++编译器中进行相同的实验(VS2013环境)

#include <iostream>
using namespace std;
int main()
{
	const int a = 10;
	int *p = (int*)&a;
	*p = 20;
	cout << "a的值 = " << a <<endl;
	cout << "*p的值 = " << *p << endl;
	cout << "a的地址 = " << &a << endl;
	cout << "p指向的地址 = " << p << endl;
	return 0;
}

测试结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191018110720192.png在这里插入图片描述
注意到一个问题,通过指针的方式,我们间接的修改了a中地址的值,但是输出的a的值并没有发生改变。输出a的地址和指向a的地址时吗,发现两者的地址居然是一致。但是在代码中已经通过指针修改了地址中的值为20,难道一个地址中可以放置两个不同的值吗? 我们不妨在做一个测试。

#include <iostream>
using namespace std;
int main()
{
	volatile const int a = 10;
	int *p = (int*)&a;
	*p = 20;
	cout << "a的值 = " << a <<endl;
	cout << "*p的值 = " << *p << endl;
	cout << "a的地址 = " << &a << endl;
	cout << "p指向的地址 = " << p << endl;
	return 0;
}

在const前加入volatile 修饰符 volatile 修饰符资料
测试结果:
在这里插入图片描述
我们发现利用确保本条指令不会因编译器的优化而省略的修饰符volatile 可以保证可以间接修改const的值,换句话说C++在编译过程中对const修饰符进行优化,那么如何优化了?
C++编译器对const常量的处理
当碰见常量声明时,在符号表中放入常量。 问题:那有如何指针解释取地址行为?
编译过程中若发现使用常量则直接以符号表中的值替换 (提高效率)
编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间(兼容C)
注意:C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值。

结论

C语言中的const变量。

C语言中const变量是只读变量,有自己的存储空间。
C++中的const常量。
可能分配存储空间,也可能不分配存储空间 。
当const常量为全局,并且需要在其它文件中使用,会分配存储空间
当使用&操作符,取const常量的地址时,会分配存储空间
当const int &a = 10; const修饰引用时,也会分配存储空间

const和#define不同

对比加深
C++中的const常量类似于宏定义
const int c = 5; ≈ #define c 5
C++中的const常量与宏定义不同
const常量是由编译器处理的,提供类型检查和作用域检查
宏定义由预处理器处理,单纯的文本替换:换句话说就是 define 可以定义在任何地方,在预编译过程中替换,除非使用#undef 常量 # undef 否则整个作用域都可以使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值