C语言关键字之const

版权声明:本文为小生原创,转载请注明出处,好吗好的,善哉善哉!!! https://blog.csdn.net/u010650845/article/details/79667990

1. Const

ANSI C 允许你声明常量,常量的样子和变量完全一样,只是它们的值不能修改,你可以使用 const 关键字来声明常量

int const a;
const int a;

这两条语句,都把 a 声明为一个整型常量,它的值不能被修改,所以你无法把任何值赋值给它,如此一来,怎么样才能让它一开始拥有一个值呢?有两种办法:

  • 声明时就对它进行初始化
int const a = 5const int a = 5
  • 函数中声明为 const 的形式参数在函数被调用时会得到实参的值
void function( const int a ){
    ...
}
void main( void ){
    int a = 10;
    function( a );
}

1.1. 常量指针与指针常量

int *p

p 是一个普通的指向整型变量的指针,而变量

int const *p;
const int *p;

则是一个常量指针,你可以修改指针本身的值,但是不能通过指针 p 修改它所指向的呢个值(可以通过其他引用修改 p 指向的那个值),例如:

int a = 5int b = 5int const *p = &a;
//如下 3 种情况:
1. p = &b;//正确,可以修改指针 p 本身的值
2. a = 10//正确,可以通过其他引用修改 p 指向的那个值
3. *p = 10//错误语法,试图通过常量指针 p 修改 p 指向的那个值

指针常量声明如下

int * const p;

p 本身的值不允许修改,但是可以修改 p 指向的那个值,例如:

int a = 5int b = 5int * const p = &a;
//如下 2 种情况
1. p = &b;//语法错误,试图修改 p 本身的值
2. *p = 10//正确,可以修改 p 指向的那个值

区分常量指针与指针常量的关键在于星号的位置,如果把 * 修饰符读作指针,把 const 修饰符读作常量:

int const *p;//常量指针
const int *p;//常量指针
int *const p;//指针常量

指向常量的常指针,无论是指针本身还是指针指向的那个值,都不允许被修改,声明如下:

int const * const p;
const int * const p;

1.2. Const修饰函数参数

防止修改指针指向的那个值,如果函数体内试图修改 p 指向的那个值,编译器将指出错误:

void functionconst int *p ){
    *p = 10//错误
}

防止修改指针本身的值,如果函数体内试图修改 p 本身的值,编译器将指出错误:

void functionint * const p){
    int a = 5;
    p = &a;//错误
}

防止修改指针本身的值+指针指向的那个值,否则编译器将指出错误:

void function( int const *const p){
    int a = 5;
    *p = 10//错误
    p = &a;//错误
}
void function( const int *const p);//同上

1.3. Const修饰函数返回值

如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加 const 修饰的同类型指针。

const char *GetString( void );
char *str = getString();//错误
char *const str = GetString();//错误
const char *str = GetString();//正确
char const *str = GetString();//正确

1.4. Const与#define

#define 指令是另一种创建名字常量的机制, 例如:

#define MAX 50
int const MAX = 50

在这种情况下,使用 #define 比使用 Const 变量更好,因为只要允许使用字面值常量的地方都可以使用前者,比如数组的长度,Const 变量只能用于允许使用变量的地方,Const 与预编译指令相比,有如下优点:

  • 预编译指令只是对值进行简单的替换,不能进行类型检查
  • 可以保护被修饰的东西,防止意外修改,增强程序的健壮性
  • 编译器通常不为普通 const 常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高

猜你喜欢

转载自blog.csdn.net/u010650845/article/details/79667990