只想知道这段用 C 编写的代码是如何工作的

Just want to know how this code written in C works

#include <stdio.h>

int main(){
    char *name;
    printf("Enter a name: ");
    scanf("%[^\n]s", &name);
    printf("%s", &name);
    return 0;
}

在这里,我创建了一个悬挂指针,即不指向任何地址,我尝试将一个字符串存储到其中,我发现在指针之前使用一个符号对 I-O 有效,但我只是不知道为什么。我刚刚开始使用 C.

输出结果如下

Enter a name: Joseph Tribbiani
Joseph Tribbiani

&name表示“使用指针变量'name'的地址”作为scanf的目标。

scanf 正在使用指针变量地址(分配 4 或 8 个字节,具体取决于体系结构)并破坏堆栈(假设输入的字符超过 3 或 7 个)- 这对一个简单的主程序。 (为什么多于 3 或 7?因为 scanf 添加了一个空终止符。)

编译器警告可能显示为:

main.c:20:14: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]

此程序显示损坏:

int main()
{
    char s[20] = "Hello World\n";  // the storage for 's' is corrupted by the scanf
    char *name;

    printf("%s",s);    
    printf("Enter a name: ");
    scanf("%[^\n]s", &name);
    printf("%s\n", &name);
    printf("%s",s);    
}

产生:

Hello World
Enter a name: its a small world
its a small world
all world

通过使用符号 &name,您实际上是在获取变量 name 的地址,它是一个指向 char 的指针。是的,name 没有指向任何地址,但它仍然是一个变量,它占用 space 来存储它的值,就像 int 变量一样。根据您的体系结构,name 占用 4 或 8 个字节。这意味着您可以将字节存储到这个 name 变量中,就像您存储任何其他变量一样。

您的代码有效,因为您使用变量 name 作为字符数组来存储您的输入。您 scanf 字符串并将其存储到 name 然后 printf 出来。在用完 name 的大小之前,您可以输入 4 个或 8 个单字节字符。 (UPD:感谢 Andy 的评论,因为 scanf 添加了一个空终止字节,它实际上是 3 或 7 个字符。我完全忘记了:p)

在我的 64 位 Ubuntu 20.10 和 gcc 10.3.0 上,我得到 stack smashing error if I input more than 8 chars. However, if I input abcdefgh and print out the value of name (not &name) using printf("%p", name), I will get 0x6867666564636261. Recall that the ASCII code for the character a is 97, aka 0x61. And since my pc uses Little Endian Byte Order0x6867666564636261 的最低有效字节只是 0x61。这意味着 'a' 存储在 name 的第一个字节,然后是 'b''c' ...,就像 char 数组一样。