1.用法
a. 修饰const修饰普通类型的变量
b. const关键字修饰数组
c. 常量指针与指针常量
d. const参数传递和函数返回值。
e. const修饰函数体
f. const修饰类成员函数体
2. 注意点
a. const修饰的值,不是一定不可以改变的。
3. const与define的区别
a. 预编译指令只是对值进行简单的替换,不能进行类型检查
b. 可以保护被修饰的东西,防止意外修改,增强程序的健壮性
c. 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高
4.1 const修饰普通类型的变量 ,变量不能再修改值。
/* 1. 修饰const修饰普通类型的变量 */
void test_23_01(){
const int a23_01 = 1;
int b23_01 = 1;
// a23_01=2;//报错“错误:向只读变量‘a23_01’赋值”
b23_01=2;
printf("a23_01=%d\n",a23_01);
printf("b23_01=%d\n",b23_01);
}
输出结果:
a23_01=1
b23_01=2
4.2 const修饰普通类型的变量 ,加上volatile关键字,变量能修改其值。
void test_23_02(){
const int a23_02 = 1;
volatile const int b23_02 = 1;
int *p1 = (int*)(&a23_02);//这这种强转并没有能修改a23_01值,输出结果a23_01还是为1
*p1 = 2;
int *p2 = (int*)(&b23_02);//定义的const变量,用volatile修饰,可以修改值,值变为了2
*p2 = 2;
printf("a23_02=%d\n",a23_02);
printf("b23_02=%d\n",b23_02);
}
输出结果:
a23_02=1
b23_02=2
4.3 const 修饰的数组,不能修改数组值。
/* const数组 */
void test_23_03(){
const int a23[10]={1,2,3,4};
int b23[10]={1,2,3,4};
printf("a23[0]=%d\n",a23[0]);
printf("b23[0]=%d\n",b23[0]);
// a23[0]=5;//报错:“错误:向只读位置‘a23[0]’赋值
b23[0]=5;
printf("a23[0]=%d\n",a23[0]);
printf("b23[0]=%d\n",b23[0]);
}
输出结果:
a23[0]=1
b23[0]=1
a23[0]=1
b23[0]=5
4.4 常量指针与指针常量
/* 常量指针,const修饰的是(*p) */
void test_23_04(){
int a1 = 4;
int b1 = 4;
const int *p1 = &a1;
int *p2 = &b1;
printf("*p1=%d\n",*p1);
printf("*p2=%d\n",*p2);
printf("a1=%d\n",a1);
printf("b1=%d\n",b1);
// *p1 = 5;//报错:“ 错误:向只读位置‘* p1’赋值”,常量指针,不能修改指针指向的值。
*p2 = 5;//非常量指针 ,可以修改指针指向的值。
printf("*p1=%d\n",*p1);
printf("*p2=%d\n",*p2);
printf("a1=%d\n",a1);
printf("b1=%d\n",b1);
}
输出结果:
*p1=4
*p2=4
a1=4
b1=4
*p1=4
*p2=5
a1=4
b1=5
/* 指针常量,const 修饰的是(p) */
void test_23_05(){
int a1 = 4;
int b1 = 4;
int* const p1 = &a1;
int *p2 = &b1;
printf("*p1=%d\n",*p1);
printf("*p2=%d\n",*p2);
int a2 = 5;
int b2 = 5;
// p1 = &a2;//报错 : "错误:向只读变量‘p1’赋值"
p2 = &b2;
printf("*p1=%d\n",*p1);
printf("*p2=%d\n",*p2);
输出结果:
*p1=4
*p2=4
*p1=4
*p2=5
4.5 const参数传递和函数返回值。
/* const参数传递,参数不能被修改 */
void test_23_06_01(const int x){
// x++;// 报错: "错误:令只读形参‘x’自增"
printf("x=%d\n",x);
}
void test_23_06_02(int y){
y++;
printf("y=%d\n",y);
}
void test_23_06(){
int a1 = 4;
test_23_06_01(a1);
test_23_06_02(a1);
}
输出结果:
x=4
y=5
4.6 const修饰函数返回值
/* const修饰函数返回值-返回值为普通类型 */
const int test_23_07_01(){
return 3;
}
int test_23_07_02(){
return 3;
}
void test_23_07(){
int a1 = test_23_07_01();//可以使用不用const修饰的变量接收
int b1 = test_23_07_02();
printf("a1=%d\n",a1);
printf("b1=%d\n",b1);
a1 = 5;//即便有const修饰,也可修改返回值。
b1 = 5;
printf("a1=%d\n",a1);
printf("b1=%d\n",b1);
}
输出结果:
a1=3
b1=3
a1=5
b1=5
/* const修饰函数返回值-返回值为指针 */
const char* test_23_08_01(){
char *a = new char[10];
strcpy(a,"hello");
return a;
}
char* test_23_08_02(){
char *a = new char[10];
strcpy(a,"hello");
return a;
}
void test_23_08(){
// char *p1 = test_23_08_01();//报错:“错误:从类型‘const char*’到类型‘char*’的转换无效”
const char *p1 = test_23_08_01();//const修饰的指针可以接收
char *p2 = test_23_08_02();
printf("p1=%s\n",p1);
printf("p2=%s\n",p2);
}
输出结果:
p1=hello
p2=hello
4.7 const修饰函数体 (“一个函数名字后有const,这个函数必定是成员函数,
也就是说普通函数后面不能有const修饰....”)
/* const修饰函数体 */
// void test_23_09_01() const {
// printf("this is test_23_09_01()\n");
// }
/* 报错:“错误:非成员函数‘void test_23_09_01()’不能拥有 cv 限定符”
(“一个函数名字后有const,这个函数必定是成员函数,
也就是说普通函数后面不能有const修饰....”) */
void test_23_09_02(){
printf("this is test_23_09_02()\n");
}
void test_23_09(){
// test_23_09_01();
test_23_09_02();
}
4.8 const修饰类成员函数体
/* const修饰类成员函数体 */
class A23_10
{
private:
int a1 = 1;
public:
void fun1() const{
// a1++;//报错:"错误:increment of member ‘A23_10::a1’ in read-only object"
printf("a1=%d\n",a1);
}
void fun2() {
a1++;
printf("a1=%d\n",a1);
}
};
void test_23_10(){
A23_10 a23_10;
a23_10.fun1();
a23_10.fun2();
}
输出结果
a1=1
a1=2
参考: c学习-28