目录
[一、const 的作用与区别](#一、const 的作用与区别)
[1. C语言中的 const](#1. C语言中的 const)
[2. C++中的 const](#2. C++中的 const)
[3. C vs C++ 中 const 的核心区别](#3. C vs C++ 中 const 的核心区别)
[二、static 的作用与区别](#二、static 的作用与区别)
[1. C语言中的 static](#1. C语言中的 static)
[2. C++中的 static](#2. C++中的 static)
[3. C vs C++ 中 static 的核心区别](#3. C vs C++ 中 static 的核心区别)
[三、#define 宏定义 vs const 常量](#define 宏定义 vs const 常量)
[1. #define 的特性](#define 的特性)
[2. const 的特性](#2. const 的特性)
[3. #define vs const 核心区别](#define vs const 核心区别)
[1. 同一语言内的对比](#1. 同一语言内的对比)
[2. 跨语言对比](#2. 跨语言对比)
一、const
的作用与区别
1. C语言中的 const
-
本质:修饰变量为"只读",但并非真正的编译时常量。
-
特点 :
- 存储分配:编译器可能为其分配内存(如取地址操作),也可能不分配(如优化为立即数)。取决于是否对其进行取地址:若未取地址,则为立即数;若取了地址,则分配了内存。
- 作用域 :默认具有外部链接属性 (类似
extern
),可通过extern const int var;
在其他文件访问。 - 常量性:不可作为编译期常量使用(如数组大小、枚举值)。
- 类型安全:弱类型检查,可通过指针强制修改值(未定义行为)。
-
示例 :
cppconst int C = 5; int arr[C]; // 错误!C语言不允许非常量表达式作为数组大小(除非C99 VLA)
2. C++中的 const
-
本质:真正的编译时常量(需初始化且值不可变)。
-
特点 :
- 存储分配:若用于常量表达式(如数组大小、模板参数),可能不分配内存(优化为立即数)。
- 作用域 :默认具有内部链接属性 (类似
static
),除非显式声明为extern
。 - 常量性:可直接作为编译期常量使用(如数组大小、模板参数)。
- 类型安全:严格的类型检查,禁止通过指针修改(否则编译错误或未定义行为)。
-
示例 :
cppconst int C = 5; int arr[C]; // 合法!C++允许编译时常量作为数组大小
3. C vs C++ 中 const
的核心区别
特性 | C语言 const |
C++ const |
---|---|---|
是否编译时常量 | 否 | 是(需初始化) |
默认链接属性 | 外部(extern ) |
内部(static ) |
是否允许作为数组大小 | 否(除非C99 VLA) | 是 |
类型检查 | 弱(可能通过指针修改) | 强(编译期类型安全) |
二、static
的作用与区别
1. C语言中的 static
- 局部静态变量 :
- 生命周期延长到程序结束,作用域仅限于定义它的函数。
- 示例:
cpp
void func() {
int a = 0; // 普通局部变量
static int b = 0; // 静态局部变量
a++;
b++;
printf("a = %d, b = %d\n", a, b);
}
int main() {
for (int i = 0; i < 3; i++) {
func();
}
return 0;
}
//a = 1, b = 1
//a = 1, b = 2
//a = 1, b = 3
-
全局静态变量/函数 :
- 限制作用域到当前文件(
internal linkage
),避免命名冲突。
- 限制作用域到当前文件(
-
示例 :
cppstatic int count = 0; // 文件作用域内可见 void func() { static int x = 0; // 静态局部变量,保留值 }
2. C++中的 static
-
继承C语言特性 :
- 静态局部变量、静态全局变量/函数的行为与C语言一致。
-
新增特性 :
- 类内静态成员 :
- 属于整个类,而非类的实例。
- 需在类外单独定义(除
constexpr
静态常量)。
- 静态成员函数 :
- 只能访问静态成员,无
this
指针。
- 只能访问静态成员,无
- 类内静态成员 :
-
示例 :
cppclass MyClass { public: static int x; // 静态成员变量 static void foo() { std::cout << x; } // 静态成员函数 }; int MyClass::x = 0; // 类外定义
3. C vs C++ 中 static
的核心区别
特性 | C语言 static |
C++ static |
---|---|---|
类内支持 | 不支持 | 支持(静态成员变量/函数) |
作用域控制 | 文件级、函数级 | 同C语言 + 类级 |
内存分配 | 全局静态区 | 全局静态区 |
三、#define
宏定义 vs const
常量
1. #define
的特性
-
预处理阶段:文本替换,无类型检查。
-
作用域:全局作用域,易引发命名冲突。
-
调试支持:不可调试(宏已被替换)。
-
常量表达式:可用于数组大小、条件编译等编译期场景。
-
潜在陷阱 :
cpp#define SQUARE(x) x*x int a = SQUARE(3 + 2); // 实际展开为 3+2*3+2 = 11(非预期)
2. const
的特性
-
编译阶段:类型安全检查,作用域可控。
-
C语言限制:不可作为编译期常量(如数组大小)。
-
C++优势:可直接用于编译期常量表达式。
-
示例 :
cppconst int N = 10; int arr[N]; // C++合法,C语言非法
3. #define
vs const
核心区别
特性 | #define |
const |
---|---|---|
处理阶段 | 预处理期(文本替换) | 编译期(类型安全检查) |
类型安全 | 无类型,易引发错误 | 有类型,编译器严格检查 |
调试支持 | 不可调试(已被替换) | 可调试 |
作用域控制 | 全局作用域,易命名冲突 | 有作用域限制(如局部/类内) |
常量表达式 | 可用于数组大小、模板参数等 | C++中支持,C语言中不支持 |
四、三者在C/C++中的综合对比
1. 同一语言内的对比
C语言
const
:仅表示只读变量,无法替代宏定义。static
:控制作用域和生命周期。#define
:唯一真正的编译期常量机制。- 推荐顺序 :
#define
>static
>const
(因const
限制较多)。
C++
const
:支持编译期常量(需初始化),类型安全。static
:作用域控制 + 类共享数据。#define
:仅用于复杂宏替换(如条件编译)。- 推荐顺序 :
const
/constexpr
>static
>#define
。
2. 跨语言对比
特性 | C语言 | C++ |
---|---|---|
const 是否编译期常量 |
否 | 是 |
const 默认链接属性 |
外部 | 内部 |
static 类内支持 |
不支持 | 支持 |
#define 类型安全 |
无 | 无 |
推荐常量机制 | #define |
const 或 constexpr |
五、现代C++的最佳实践
- 替代宏定义 :
- 使用
const
或constexpr
替代#define
常量(如constexpr int N = 10;
)。 - 使用
inline constexpr
(C++17)替代全局常量宏。
- 使用
static
的新用法 :- 类内静态成员变量 +
static_assert
验证编译期常量。
- 类内静态成员变量 +
- 类型安全保障 :
- 优先使用
const
和constexpr
提升代码安全性和可维护性。
- 优先使用