C语言高频面试题——指针赋值字符串与定义一个数组赋值字符串有什么区别?
1. 定义方式
(1) 指针赋值字符串
char *str = "Hello, World!";
- 含义:
str
是一个指向常量字符串的指针。- 字符串
"Hello, World!"
被存储在只读的静态存储区(通常是程序的常量区),str
指向该字符串的首地址。
(2) 数组赋值字符串
char str[] = "Hello, World!";
- 含义:
str
是一个字符数组,大小为字符串长度加1(包括末尾的\0
空字符)。- 字符串
"Hello, World!"
被复制到数组中,存储在栈或全局/静态存储区(取决于定义位置)。
2. 内存分配
(1) 指针赋值字符串
- 存储位置:字符串存储在只读的静态存储区。
- 内存布局:
- 指针变量
str
存储在栈上(如果是在函数内部定义)。 - 字符串
"Hello, World!"
存储在只读区域,str
指向该区域。
- 指针变量
- 示意图:
+-------+ +-------------------------+ | str | ----> | "Hello, World!\0" | +-------+ +-------------------------+ (栈) (只读静态存储区)
(2) 数组赋值字符串
- 存储位置:字符串存储在数组中,数组可以位于栈、全局/静态存储区。
- 内存布局:
- 如果数组定义在函数内部,则数组存储在栈上。
- 如果数组定义在全局或静态作用域,则数组存储在全局/静态存储区。
- 示意图:
+-------------------------+ | "Hello, World!\0" | +-------------------------+ (栈或全局/静态存储区)
3. 可修改性
(1) 指针赋值字符串
- 不可修改:
- 字符串存储在只读区域,尝试修改会引发未定义行为(如运行时错误)。
char *str = "Hello, World!"; str[0] = 'h'; // 错误:试图修改只读区域的内容
- 用途:
- 适用于不需要修改字符串内容的场景,例如字符串常量或只读数据。
(2) 数组赋值字符串
- 可修改:
- 数组中的字符串存储在可写区域,可以自由修改。
char str[] = "Hello, World!"; str[0] = 'h'; // 正确:修改数组中的内容 printf("%s\n", str); // 输出 "hello, World!"
- 用途:
- 适用于需要修改字符串内容的场景。
4. 大小和灵活性
(1) 指针赋值字符串
- 大小:
- 指针变量本身占用固定大小(通常为4字节或8字节,取决于系统架构)。
- 字符串的实际大小与指针无关,存储在只读区域。
- 灵活性:
- 指针可以重新指向其他字符串。
char *str = "Hello"; str = "World"; // 指针重新指向新字符串
(2) 数组赋值字符串
- 大小:
- 数组的大小由字符串长度决定,包括末尾的
\0
。 - 数组大小在定义时固定,无法动态调整。
char str[] = "Hello"; // 数组大小为6(5个字符 + 1个'\0')
- 数组的大小由字符串长度决定,包括末尾的
- 灵活性:
- 数组无法重新指向其他字符串,但可以通过拷贝等方式更新内容。
char str[20] = "Hello"; strcpy(str, "World"); // 更新数组内容
5. 使用场景
(1) 指针赋值字符串
- 适用于:
- 不需要修改字符串内容的场景。
- 需要节省内存(只存储指针,不重复存储字符串)。
- 字符串常量(如错误信息、提示信息等)。
(2) 数组赋值字符串
- 适用于:
- 需要修改字符串内容的场景。
- 字符串长度较短且固定的场景。
- 需要将字符串作为局部变量使用的场景。
6. 示例对比
代码
#include <stdio.h>void test_pointer() {char *str = "Hello, World!";printf("Pointer: %s\n", str);// str[0] = 'h'; // 错误:试图修改只读区域
}void test_array() {char str[] = "Hello, World!";printf("Array before modification: %s\n", str);str[0] = 'h'; // 正确:修改数组内容printf("Array after modification: %s\n", str);
}int main() {test_pointer();test_array();return 0;
}
输出
Pointer: Hello, World!
Array before modification: Hello, World!
Array after modification: hello, World!
7. 总结
特性 | 指针赋值字符串 | 数组赋值字符串 |
---|---|---|
存储位置 | 字符串存储在只读静态存储区 | 字符串存储在栈或全局/静态存储区 |
可修改性 | 不可修改 | 可修改 |
大小 | 指针大小固定 | 数组大小由字符串长度决定 |
适用场景 | 不需要修改字符串内容的场景 | 需要修改字符串内容的场景 |