一、static关键字
这也是面试或编程中最常见的关键字之一了,作用:
-
修饰局部变量:使变量成为静态局部变量,存储在静态存储区,生命周期延长至整个程序运行期间
-
修饰全局变量:限制变量作用域仅在本文件内(内部链接)
-
修饰函数:限制函数作用域仅在本文件内(内部链接)
-
修饰类成员(C++中):属于类本身而非对象实例
其中static修饰类成员需要举例详细说说
cpp
#include <iostream>
using namespace std;
class Student {
public:
Student(string n) : name(n) {
count++; // 每创建一个学生对象,计数加1
}
~Student() {
count--; // 对象销毁时计数减1
}
// 静态成员函数 - 属于类本身
static int getCount() {
return count;
// 注意:静态成员函数不能访问非静态成员
// 错误:cout << name; // 不能访问非静态name
}
// 非静态成员函数
void display() {
cout << "姓名:" << name << endl;
cout << "当前学生总数:" << count << endl; // 可以访问静态成员
}
private:
string name; // 非静态成员 - 每个对象独有
static int count; // 静态成员 - 所有对象共享
};
// 静态成员必须在类外定义和初始化
int Student::count = 0;
int main() {
// 访问静态成员 - 不需要创建对象
cout << "初始学生数:" << Student::getCount() << endl;
// 创建对象
Student s1("张三");
Student s2("李四");
// 所有对象共享同一个静态成员
cout << "创建2个学生后:" << endl;
cout << "通过类名访问:" << Student::getCount() << endl;
cout << "通过对象s1访问:" << s1.getCount() << endl;
cout << "通过对象s2访问:" << s2.getCount() << endl;
cout << "\n每个学生的信息:" << endl;
s1.display();
s2.display();
{
Student s3("王五"); // 在作用域内创建第三个学生
cout << "\n创建第三个学生后:" << Student::getCount() << endl;
} // s3离开作用域被销毁
cout << "\ns3销毁后:" << Student::getCount() << endl;
return 0;
}
输出结果
cpp
初始学生数:0
创建2个学生后:
通过类名访问:2
通过对象s1访问:2
通过对象s2访问:2
每个学生的信息:
姓名:张三
当前学生总数:2
姓名:李四
当前学生总数:2
创建第三个学生后:3
s3销毁后:2
static类成员的特点:
1 共享性:所有对象共享同一份静态成员
2 内存分配:在程序的数据段分配内存,不依赖于对象存在
静态成员:程序启动时分配,程序结束时释放
非静态成员:对象创建时分配,对象销毁时释放
3 访问方式:
int num = Student::getCount(); // 通过类名访问(推荐)
4 初始化:必须在类外单独定义和初始化,类内声明
二、const关键字
指向整型常量的指针变量 const int *p;
指向整型变量的指针常量 int * const p;
const与#define的区别
| 特性 | const | #define |
|---|---|---|
| 类型检查 | 有类型检查 | 无类型检查,只是文本替换 |
| 作用域 | 遵守作用域规则 | 全局有效(除非#undef) |
| 调试 | 可调试,有变量名 | 编译时替换,无变量名 |
| 内存 | 分配内存 | 不分配内存,只是替换 |
| 复杂类型 | 可定义复杂类型 | 只能定义简单常量 |
三、volatile关键字
1. 作用
告诉编译器该变量可能会被意外修改,每次访问时都必须从内存中读取,不要做优化(如寄存器缓存)。
2. 使用场景
-
硬件寄存器:映射到内存的硬件寄存器
-
中断服务程序:被中断修改的全局变量
-
多线程:多个线程共享的变量
-
信号处理程序:被信号处理函数修改的变量
3. 编译阶段作用
-
volatile:编译阶段起作用,告诉编译器不要优化
-
extern:链接阶段起作用,声明外部定义
四、sizeof关键字
1. 作用
编译时一元操作符(不是函数),计算数据类型或表达式所占内存字节数。
2.sizeof与strlen的区别
| 特性 | sizeof | strlen |
|---|---|---|
| 性质 | 操作符/关键字 | 库函数 |
| 计算时机 | 编译时计算 | 运行时计算 |
| 参数 | 类型/变量 | 字符串指针 |
| '\0'处理 | 包含'\0' | 不包含'\0' |
| 数组退化为指针 | 数组名不退化 | 数组名退化为指针 |
五、register关键字
1. 作用
建议编译器将变量存储在CPU寄存器中,以提高访问速度。
2. 注意事项
-
只是建议:编译器可能忽略
-
不能取地址 :
®ister_var是非法的 -
有限数量:寄存器数量有限
-
现代编译器:通常自动优化,很少需要手动指定
-
适用类型:常用于循环计数器等频繁访问的变量