Skip to content

字符数组与字符指针

[[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"
  • printfstr 指向的地址开始,逐个字符输出,直到遇到 \0
  • 第二次赋值c str = "fuck the world";
  • str 现在指向字符串字面量 "fuck the world" 的首地址。
  • 第二次打印c printf("%s", str); // 输出 "fuck the world"
  • printfstr 指向的地址开始,逐个字符输出,直到遇到 \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;
}

在这段示例当中,这样是跑不通的,因为这样就改变了字符数组(地址)的值