const
const的使用
-
1>const 修饰变量
const修饰符可以把对象转变成常数对象,意思就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用任何修改该变量的尝试都会导致编译错误。因为常量在定以后就不能被修改,所以定义时必须初始化。 -
2>const 修饰函数的参数
参数采用“指针传递”,那么加const修饰可以防止意外地改动该指针,起到保护作用。
void Func(const A &a)“引用传递”起到保护作用。- const char * ch
char const * ch //const在*前面说明这是一个字符串常量指针,它所指向的内容不能被更改,但是这个指针的指向可以改变 - char * const ch //const在*后面则表示一个指针常量,它的指向不能被修改,但是可以修改所指向的内容
- const char * ch
-
3>const修饰成员函数
const放在成员函数名后面,const修饰的成员函数不能修改任何成员变量的值。 -
4>const修饰指针
1.const int * p = &a;
int const * p = &a; //修饰 * p即a,a不可变。
2.int * const p = &a; //修饰p,地址不可变,即p的指向不可变。
3.const int* const p = &a; //*p和p都被const修饰了,所以p指向的内存单元,和p指向内存单元中存放的内容都是不可变的。 -
总结:对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。
对于内部数据类型的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。
C/C++const的区别
- 在C语言中const修饰只读变量,例如 const int a = 0; 此时a为只读的,不能通过 a = 10;这种手段进行值的修改,若想修改a的值,可通过指针来完成,如 int *pa = (int *)&a, *pa = 10;此时 a 的值变为10;
- 在C++中,若const修饰变量,则该变量变为常量,存储在符号表中,使用时在从符号表中取值,且编译器是不会为该常量分配内存,例如 const int a = 10;此时a的值固定为10,这类似于#define定义的宏;当需要对const常量进行取地址或extern操作时,编译器会为这个变量在内存中开辟一个临时空间,但const常量并不使用这块空间,取值依旧从符号表中取。
关于const与#define的区别
- 1.宏(define)是在预处理时进行的完全的文本替换操作,const是在编译时处理的;
- 2.const常量会做类型检测与作用域检测
- 3.const常量的作用域与变量相同,而宏(define)的作用域为从宏定义位置开始到文件结束或到撤销宏为止(undef)。
extern
- 1.当它与"C"一起连用时,如: extern “C” void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,这要看编译器的"脾气"了(不同的编译器采用的方法不一样),为什么这么做呢,因为C++支持函数的重载。
- 2.声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块或其他模块中使用
其声明的函数和变量可以在本模块或其他模块中使用,记住它是一个声明不是定义!
在A模块的头文件A.h中声明extern int a;然后在A.c中定义int a=10;
当B模块(编译单元)要是引用模块(编译单元)A中定义的全局变量a或函数时,它只要包含A模块的头文件即可,在编译阶段,模块B虽然找不到该函数或变量,但它不会报错,
它会在连接时从模块A生成的目标代码中找到此函数。
extern 变量
- 对于 extern 申明变量可
以多次,但定义只有一次。在我们的代码中你会看到看到这样的语句:
这个语句是申明 USART_RX_STA 变量在其他文件中已经定义了,在这里要使用到。所以,你肯定extern u16 USART_RX_STA;
可以找到在某个地方有变量定义的语句:u16 USART_RX_STA;
extern 函数
- 通常做法–在.c中定义,在.h中extern出来,那么其他编译单元include这个.h文件就可以使用这个变量
- 函数声明默认就是extern的,所以函数声明前的extern可以省略不加。
- 暗示这个函数可能在别的源文件里定义
- 在一些复杂的项目中,比较习惯在所有的函数声明前添加extern修饰,以防止遗漏包含头文件而导致的编译错误