概述
C语言中的const关键字用于修饰变量、函数参数、函数返回值,以指明它们的值在程序的整个执行期间都不会被改变。const限定的变量值是只读的,不能通过程序改变它的值。const是一个C语言(ANSIC)的关键字,具有着举足轻重的地位。它限定一个变量不允许被改变,产生静态作用
const修饰符有以下的优点:
1、预编译指令只是对值进行简单的替换,不能进行类型检查
2、可以保护被修饰的东西,防止意外修改,增强程序的健壮性
3、编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高
1.const修饰普通变量
变量名前加上const关键字,表明该变量是一个常量,它的值在程序运行期间不能被改变。const 修饰的变量是一个常量,它的值在程序执行期间不会改变,只能被赋值一次。
const int a = 10;
int const b = 10;
a = 20; // 编译错误,无法修改 const 变量的值
b = 20; // 编译错误,无法修改 const 变量的值
这两种写法是一样的,都是表示变量 a,b 的值不能被改变了,需要注意的是,用const修饰变量时,一定要给变量初始化,否则之后就不能再进行赋值了。
2.修饰指针变量
(区分常量指针和指针常量的关键就在于星号的位置,我们以星号为分界线,如果const在星号的左边,则为常量指针,如果const在星号的右边则为指针常量。如果我们将星号读作‘指针’,将const读作‘常量’的话,内容正好符合。int const * n;是常量指针,int *const n;是指针常量)
指向常量的指针(不能通过指针修改所指向的值,但是还是可以通过其他的引用来改变变量的值的):
int a = 5;
const int *p = &a;
*p = 20; // 编译错误,不能通过指针p来修改所指向的整数的值
a = 6; // 修改指针指向的数据
常量指针(指针本身的值不能改变,但可以修改所指向的值):
int a = 10, b = 20;
int *const p = &a;
*p = 30; // 可以修改所指向的值
p = &b; // 编译错误,不能改变常量指针的指向
3.修饰引用
const int &ref = a;
ref = 20; // 编译错误,不能修改 const 引用的值
const与指针
const int *p 和 int const* pi 用法相同
const int *p 和 int const* pi 是一个指针,它指向一个整数值,但是不允许通过该指针修改所指向的整数值
例:
#include<stdio.h>
int main() {
int a = 10;
const int b = 20;
const int *p; // 声明一个指向常量整数的指针
int const* pi;
p = &a; pi=&a; // 错误!不能将非const变量的地址赋给const指针
p = &b; pi=&b; // 正确!可以将const变量的地址赋给const指针
printf("Value of p: %d\n", *p);
printf("Value of pi: %d\n", *pi);
return 0;
}
在这个例子中我们声明了一个 const int *p 和 const int *p 类型的指针,并将其指向一个常量整数变量 b。我们不能将非const变量的地址(如 a)赋给这个指针,因为这样可能导致通过指针修改原始数据。但是,我们可以将该指针指向一个const变量(如 b),并通过指针访问其值。
(2)int *const p 用法
int *const p 我们不能改变这个指针的指向,但可以修改它所指向的值。尝试重新分配指针或将其指向另一个变量将导致编译错误
例:
#include<stdio.h>
int main() {
int a = 10;
int b = 20;
int *const p = &a; // 初始化常量指针,指向整数变量 a
// int *const p2 = &a; // 错误!常量指针必须在声明时初始化
printf("Value of p: %d\n", *p);
*p = 30; // 可以通过指针修改指向的值
// p = &b; // 错误!不能改变常量指针的指向
printf("Value of p after modification: %d\n", *p);
return 0;
}
在这个例子中,我们声明了一个 int *const p 类型的指针,并将其初始化为指向整数变量 a。我们不能改变这个指针的指向,但可以修改它所指向的值。尝试重新分配指针或将其指向另一个变量将导致编译错误。