const关键字有什么作用以及用法?
1、定义变量为常量(局部变量或全局变量)
例如:
const int n=10;
int const n=10;
const int n; //错误
上面两种写法是一样的,都是表示变量n的值不能被改变了,需要注意的是,用const修饰变量时,一定要给变量初始化,否则之后就不能再进行赋值了。
2、修饰常量静态字符串
例如:
const char* str="abcdefg";
如果没有const的修饰,如果我们在后面写到 str[3]=’x’;这样的语句,这样会导致对只读内存区域的赋值,然后程序会立刻异常终止。有了const,这个错误就能在程序被编译的时候就立即检查出来,这就是const的好处,让逻辑错误在编译期被发现。
3、修饰常数组
int const a[8]={1,2,3,4,5,6,7,8}
const int a[8]={1,2,3,4,5,6,7,8}
4、修饰常指针(常量指针与指针常量)
常量指针
const int * p;
int const * p;
常量指针说的是指针指向的内存可以变,但指针指向的数值不可变。
根据这个特点,可以通过其它的引用改变变量的值
int a=5;
const int* p=&a;
a=6;
或者改变常量指针指向其它的地址
int a=5;
int b=6;
const int* p=&a;
p=&b;
指针常量
int *const p;
指针常量是指 指针本质是个常量,而用指针修饰它,即指针指向的内存不可以变,内存中的数值可以变。
所以,可以通过其它指向的指针来修改值。
int a=5;
int *n=&a;
int* const p=&a;
*n=6;
区分常量指针和指针常量的关键就在于星号的位置,我们以星号为分界线,如果const在星号的左边,则为常量指针,如果const在星号的右边则为指针常量。如果我们将星号读作‘指针’,将const读作‘常量’的话,内容正好符合。int const * n;是常量指针,int *const n;是指针常量。
指向常量的常指针
const int* const p;
指针指向的内存和数值都不可变。但是依然可以通过其它普通指针改变变量的值。
int a=5;
int *n=&a;
const int* const p=&a;
*n=6;
5、修饰函数的参数
void Fun(const int Var)//告诉编译器Var在函数体内不能被改变,防止使用者无意或错误的更改
void Fun(char *Data1, const char *Data2);//防止修改指针指向的内容,给Data2加上const修饰后,如果函数体内的语句试图改动Data2的内容,编译器将指出错误。
void Fun(int * const p1,int * const p2)//防止修改指针指向的内存
6、修饰函数的返回值
1、如果const修饰的返回值类型为指针,那么函数返回值(即指针)的内容是不能被改变的,而且这个返回值只能赋给被const修饰的指针。
const char GetString() //定义一个函数
char *str= GetString() //错误,因为str没有被 const修饰
const char *str=GetString() //正确
2、如果用const修饰普通的返回值,如返回int变量,由于这个返回值是一个临时变量,在函数调用结束后这个临时变量的生命周期也就结束了,因此把这些返回值修饰为const是没有意义的
7、在另一连接文件中引用const常量
extern const int 1;
extern const int j=5;
extern关键字用法参考 C语言extern关键字用法和理解
8、修饰全局变量
全局变量的作用域是整个文件,我们应该尽量避免使用全局变量,因为一旦有一个函数改变了全局变量的值,它也会影响到其他引用这个变量的函数,导致除了bug后很难发现,如果一定要用全局变量,我们应该尽量的使用const修饰符进行修饰,这样防止不必要的人为修改,使用的方法与局部变量是相同的。
9、节省空间,避免不必要的内存分配。
#define PI 3.14159//该宏用来定义常量
const doulbe Pi=3.14159//此时并未将P放入只读存储器中
double i=Pi//此时为Pi分配内存,以后不再分配
double I=PI//编译期间进行宏替换,分配内存
double j=Pi//没有内存分配再次进行宏替换,又一次分配内存