字符数组与字符指针
[[C]] [[传参限制]]
但是注意如果这里是==字符数组的话就不能直接对字符数组二次赋值==
#include <stdio.h>
int main()
{
char * str = "Helloworld";
printf("%s\n", str);
str = "fuck the world";
printf("%s", str);
return 0;
}
这段代码是合法的,因为它利用了C语言中字符串字面量的特性和指针的行为。以下是详细的解释:
1. 字符串字面量的存储
- 字符串字面量(如
"Helloworld"
和"fuck the world"
)在编译时会被存储在程序的只读数据段(通常是.rodata
段)。 - 它们在内存中有明确的存储位置,并且以
\0
结尾。
2. 指针的赋值
char *str
是一个指向字符的指针。- 当将字符串字面量赋值给
str
时,str
实际上指向的是字符串字面量的首地址。c char *str = "Helloworld"; // str 指向 "Helloworld" 的首地址
- 字符串字面量的地址是编译器自动分配的,因此不需要显式分配内存。
3. 代码的执行过程
- 第一次赋值:
c char *str = "Helloworld";
str
指向字符串字面量"Helloworld"
的首地址。- 第一次打印:
c printf("%s\n", str); // 输出 "Helloworld"
printf
从str
指向的地址开始,逐个字符输出,直到遇到\0
。- 第二次赋值:
c str = "fuck the world";
str
现在指向字符串字面量"fuck the world"
的首地址。- 第二次打印:
c printf("%s", str); // 输出 "fuck the world"
printf
从str
指向的地址开始,逐个字符输出,直到遇到\0
。
4. 为什么不需要分配内存?
- 字符串字面量在编译时已经存储在只读数据段中,因此不需要在运行时动态分配内存。
char *str
只是一个指针,它存储的是字符串字面量的地址,而不是字符串本身的内容。
5. 注意事项
- ==字符串字面量是不可修改的,因此以下操作是非法的:==
c char *str = "Helloworld"; str[0] = 'h'; // 错误:试图修改只读内存
- ==如果需要修改字符串内容,应该使用字符数组:==
c char str[] = "Helloworld"; str[0] = 'h'; // 合法:字符数组存储在栈上,可修改
6. 总结
这段代码是合法的,因为它利用了字符串字面量的特性和指针的行为:
- 字符串字面量在编译时存储在只读数据段中,不需要显式分配内存。
- char *str
是一个指针,它存储的是字符串字面量的地址。
- 字符串字面量是不可修改的,但指针可以重新指向其他字符串字面量。
#include <stdio.h>
int main()
{
char str[100] = "HelloWorld";
printf("%s", str);
str = "fuckTHEWORLD";
printf("%s", str);
return 0;
}
在这段示例当中,这样是跑不通的,因为这样就改变了字符数组(地址)的值