C++关键字详解
const
const
关键字用于声明常量或修饰指针指向的对象不可被修改。其主要有以下几种用法:
声明常量变量
const int age = 30; // age 是一个常量,其值不能被改变
修饰指针指向的对象不可变
int value = 100;
const int *ptr = &value; // ptr 是一个指向常量的指针,不能通过 ptr 修改 value
*ptr = 200; // 错误:试图通过 const 指针修改其指向的对象
修饰指针本身不可变
int value1 = 10, value2 = 20;
int *const ptr = &value1; // ptr 是一个常量指针,其指向不能被改变
ptr = &value2; // 错误:试图改变 const 指针的指向
修饰指针指向的对象及其指针本身均不可变
const int value = 30;
const int *const ptr = &value; // ptr 是一个指向常量的常量指针,既不能通过 ptr 修改 value,也不能改变 ptr 的指向
static
static
关键字在 C++ 中有多种用途,主要包括:
静态局部变量
在函数内部声明为 static
的变量为静态局部变量,其生命周期从程序开始运行持续到程序结束,且每次函数调用时保持其值不变。
void func() {
static int count = 0; // 静态局部变量 count
++count;
cout << "Function call: " << count << endl;
}
int main() {
func(); // 输出: Function call: 1
func(); // 输出: Function call: 2
return 0;
}
静态成员变量
在类中声明为 static
的成员变量为静态成员变量,属于整个类所有,不属于任何一个类实例,通过类名或对象名访问。
class MyClass {
public:
static int sharedCount; // 静态成员变量
};
int MyClass::sharedCount = 0;
int main() {
MyClass obj1, obj2;
MyClass::sharedCount++; // 通过类名访问
obj1.sharedCount++; // 通过对象名访问
cout << MyClass::sharedCount << endl; // 输出: 2
return 0;
}
静态函数
类中的 static
成员函数不依赖于类的任何实例,可以直接通过类名调用,不能访问非静态成员变量和非静态成员函数。
class MyClass {
public:
static void printMessage() {
cout << "Static function called" << endl;
}
};
int main() {
MyClass::printMessage(); // 直接通过类名调用静态函数
return 0;
}
auto
, register
, extern
auto
auto
关键字用于自动推断变量的类型,根据初始化表达式确定。
auto num = 10; // num 类型为 int
auto str = "Hello"; // C++11 及以后版本,str 类型为 const char*
register
register
关键字用于建议编译器将变量存储在寄存器中以提高访问速度,但并非强制要求,且现代编译器通常会自行优化,因此在现代 C++ 中使用较少。
register int fastVar = 100; // 建议编译器将 fastVar 存储在寄存器中
extern
extern
关键字用于声明变量或函数在其他文件中已经定义,提供链接时的符号可见性。
// file1.cpp
int globalVar = 100; // 定义全局变量
// file2.cpp
extern int globalVar; // 声明 globalVar 已在其他文件中定义
int main() {
std::cout << globalVar << std::endl; // 输出: 100
return 0;
}
volatile
volatile
关键字用于告知编译器该变量的值可能在程序未知的时间点被外部因素(如硬件、操作系统、中断服务程序等)改变,禁止编译器对其进行优化,确保每次访问都从内存中读取最新值。
volatile int a; // 声明 a 为 volatile 变量
void readIO() {
// 读取 I/O 空间 0x100 端口的内容
a = inword(0x100); // 编译器不会优化这里的多次读取,确保每次都从 I/O 空间读取实际值
int b = a;
a = inword(0x100);
int c = a;
}
示例代码
uint16_t x;
uint16_t * const cpi = &x; // 常量指针
uint16_t * const * pcpi; // 指向常量指针的指针
const uint16_t * * ppci; // 指向指针的常量指针
uint16_t * * ppi; // 指向普通变量的指针
const uint16_t * pci; // 指向常量的指针
volatile uint16_t * pvi; // volatile 类型指针
uint16_t * pi;
pi = cpi; // 允许:无类型转换,无需显式类型转换
pi = (uint16_t *)pci; // 不允许:类型不匹配,需要显式类型转换
pi = (uint16_t *)pvi; // 不允许:类型不匹配,需要显式类型转换
ppi = (uint16_t *)pcpi; // 不允许:类型不匹配,需要显式类型转换
ppi = (uint16_t *)ppci; // 不允许:类型不匹配,需要显式类型转换