C 学习笔记1-const前缀
C 学习笔记1|const前缀、static前缀
1. 使用方法
const int a = 10;
int const a = 10;
这二者是等价的。
2. const的含义
const关键字是constant的缩写,意思是不变的。用const定义的变量,具有了常量的部分属性,但是其本质依然是变量。
上面两条语句都将变量a定义成了const类型的变量。当变量被定义成const类型后,最明显的一个特征就是不允许再对他进行赋值了,如果赋值,编译器会报错。
int main(void){const int a = 10;a = 2;}
经过 const 修饰的变量,无论是局部变量还是全局变量,其生命周期都是程序运行的整个过程。全局变量的生存周期为程序运行的整个过程不难理解,而使用const修饰过的局部变量有了静态的特性。我们知道全局变量是静态的,而 const 修饰过的只是有了静态的特性,并没有说就变成了静态变量
组成原理中讲到,局部变量是存储在栈中,静态变量存储在静态存储区中,而经过 const 修饰过的变量存储在内存中 “只读数据段” 种,只读数据段存放着常量和只读变量等不可修改的变量
定义变量
(1)const
修饰变量,以下两种定义形式在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value是不可变的,readonly。
TYPE const ValueName = value;
const TYPE ValueName = value;
(2)将const改为外部连接,作用于扩大至全局,编译时会分配内存,并且可以不进行初始化,仅仅作为声明,编译器认为在程序其他地方进行了定义.
extend const int ValueName = value;
定义指针
(1)指针本身是常量不可变
char * const pContent;
const (char*) pContent;
(2)指针所指向的内容是常量不可变
const char *pContent;
char const *pContent;
(3)两者都不可变
const char* const pContent;
(4)还有其中区别方法,沿着号划一条线:如果const位于的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
函数中使用
const
(1)const修饰函数参数
a.传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)
void function(const int Var);
b.参数指针所指内容为常量不可变
void function(const char* Var);
c.参数指针本身为常量不可变(也无意义,因为char* Var也是形参)
void function(char* const Var);
d.参数为引用,为了增加效率同时防止修改。修饰引用参数时:
void function(const Class& Var); //引用参数在函数内不可以改变
void function(const TYPE& Var); //引用参数在函数内为常量不可变
这样的一个const引用传递和最普通的函数按值传递的效果是一模一样的,他禁止对引用
的对象的一切修改,唯一不同的是按值传递会先建立一个类对象的副本, 然后传递过去,而它直接传递地址,所以这种传递比按值传递更有效.另外只有引用的const传递可以传递一个临时对象,因为临时对象都是const属性, 且是不可见的,他短时间存在一个局部域中,所以不能使用指针,只有引用的const传递能够捕捉到这个家伙.
(2)const 修饰函数返回值
const修饰函数返回值其实用的并不是很多,它的含义和const修饰普通变量以及指针的含义基本相同。
a.
const int fun1() //这个其实无意义,因为参数返回本身就是赋值。
b.
const int * fun2() //调用时
const int *pValue = fun2(); //我们可以把fun2()看作成一个变量,即指针内容不可变。
c.
int* const fun3() //调用时
int * const pValue = fun2(); //我们可以把fun2()看作成一个变量,即指针本身不可变。
3. const VS define
const 和 define在功能上有相似之处,但又有一些不同。
- define 是预编译指令,定义的宏是在预处理阶段展开的,而 const 定义的只读变量是在运行阶段使用的
- const 定义的是变量,而 define 定义的是常量,define完成的是字符的替换,而 const 是具有类型的有名字的变量,编译器可以很方便地对后者进行安全检查,不容易出问题
4. const VS static
static可以作用于变量,也可以作用于函数。
作用于变量时,如果是局部变量,则会改变为变量分配内存的时间。一般的变量是自动变量或者说动态存储的,当指令执行到变量定义时才给变量分配存储单元,生命周期结束(跳出代码块)时释放内存单元。如果用 static 修饰后,则在编译时就为变量分配内存,直到程序结束才释放内存,因此可以记录上次调用的值,不过由于仍然是局部变量,因此只能在代码块内部使用,作用域不变
作用于全局变量时,使变量的作用域仅限于本文件
作用于函数时,使函数的作用域仅限于本文件,是对函数的一种保护机制
如果想要在其他文件中引用本地函数,要在函数定义时使用 extern
,表明该函数是外部函数,可供其他文件调用,另外要在引用别的文件中定义的外部函数的文件中,使extern
声明要用的外部函数即可
const 和 static 都改变了局部变量的生命周期,但没有改变作用域
保护机制
如果想要在其他文件中引用本地函数,要在函数定义时使用 extern
,表明该函数是外部函数,可供其他文件调用,另外要在引用别的文件中定义的外部函数的文件中,使extern
声明要用的外部函数即可
const 和 static 都改变了局部变量的生命周期,但没有改变作用域