C++ 中的 char[] 和 char*
在C++中,char*
(字符指针)和char[]
(字符数组)有以下主要区别:
1. 类型与内存分配
-
char*
是一个指针变量,存储的是地址,指向某个字符(或字符数组的首元素)。- 若指向字符串字面量(如
char* p = "hello"
),则数据存储在常量区,不可修改。 - 若指向动态分配的内存(如
char* p = new char[10]
),则数据在堆上,需手动释放(delete[]
)。
- 若指向字符串字面量(如
-
char[]
是数组变量,直接分配连续内存空间。- 若声明为局部变量(如
char arr[] = "hello"
),数据在栈上,自动分配和释放。 - 内容可修改(除非声明为
const
)。
- 若声明为局部变量(如
2. 初始化与赋值
-
char*
- 可直接指向字符串字面量(需注意常量性):
const char* p = "hello"; // C++11后推荐加const
- 可重新赋值以指向其他地址:
p = "world"; // 合法,但新地址可能为常量区
- 可直接指向字符串字面量(需注意常量性):
-
char[]
- 必须在声明时确定大小(或由初始化字符串自动推导):
char arr[] = "hello"; // 自动分配6字节(含'\0')
- 不能直接赋值给另一个数组:
char a[10]; a = "test"; // 错误!
- 必须在声明时确定大小(或由初始化字符串自动推导):
3. sizeof
操作符
char*
sizeof(p)
返回指针的大小(如4或8字节,取决于系统)。char[]
sizeof(arr)
返回数组总大小(字符数 + 终止符\0
)。
4. 函数参数传递
- 数组作为参数时退化为指针:
此时函数内无法通过void func(char arr[]); // 等价于 void func(char* arr);
sizeof
获取数组实际大小。
5. 可修改性
char*
指向字符串字面量
若未用const
修饰,尝试修改会导致未定义行为(UB):char* p = "hello"; p[0] = 'H'; // 运行时错误(UB)
char[]
数据可安全修改(因为是拷贝到栈上的数组):char arr[] = "hello"; arr[0] = 'H'; // 合法
6. 内存管理
char*
若指向动态内存,需手动释放:char* p = new char[10]; delete[] p; // 避免内存泄漏
char[]
无需手动管理(栈内存自动释放)。
总结表格
特性 | char* | char[] |
---|---|---|
类型 | 指针 | 数组 |
内存区域 | 可能为常量区或堆 | 栈(局部变量)或全局区(全局变量) |
可重新赋值 | 是(指向其他地址) | 否(数组名为常量指针) |
修改内容 | 若指向常量区则不可修改 | 可修改 |
sizeof | 返回指针大小 | 返回数组总大小 |
内存管理 | 需手动释放(若指向堆) | 自动管理 |
使用建议
- 若需动态内存或指向字符串字面量,用
const char*
(避免修改风险)。 - 若需局部可修改的字符串,用
char[]
。 - 避免混用二者(如将栈数组地址返回给函数外部)。