为什么指针在 C 中打印两次?

Why does the pointer get printed twice in C?

如果我编译以下代码并 运行 它 gcc source.c && ./a.out:

#include <stdio.h>

int main(void) {
    char string[] = "My string";
    char m = string[0];
    printf("%s\n", &m);
}

我得到 MMy string 作为输出,但如果我这样做

#include <stdio.h>

int main(void) {
    char string[] = "My string";
    char m = string[0];
    printf("%s\n", &string[0]);
}

我只得到 My string 正如预期的那样。这里发生了什么?我注意到如果我将指针定义为变量,例如

#include <stdio.h>

int main(void) {
    char string[] = "My string";
    char *m = &string[0];
    printf("%s\n", m);
}

然后我又得到了预期的 My string。 为什么在第一个例子中指针的值被打印了两次?

第一个程序有未定义的行为。

表达式 &m 没有指向字符串的字符。它指向类型为 char

的单个对象
char string[] = "My string";
char m = string[0];

在对象m之后内存中可以有任何东西。就这样发生了,在对象m之后有一个没有任何间隙的数组string。

但转换说明符 %s 需要一个指向字符串的指针,该字符串指向以零字符“\0”结尾的字符序列。

在第二个程序中,指针m指向存储在数组string中的字符串的第一个字符。

char string[] = "My string";
char *m = &string[0];

所以第二个程序是正确的