指向 char 类型数组的指针可以用来显示数组的内容而无需解引用运算符?

Pointer pointing to char type array can be used to show the content of the array without a dereference operator?

int main(int argc, char *argv[])
{
  
  char b[]="Among Us";
  char* string2 = &b[0];
  
  printf("Print address of b\t\t=  %p\n", &b[0]);
  
  printf("Print content of string2\t=  %p\n", string2);
  printf("Print content of string2\t=  %s\n", string2); // why ???
  
  system("PAUSE");  
  return 0;
}

为什么最后的printf给我们显示的是b的内容?它不是应该向我们显示 b 的地址,而是以 %s 格式显示吗?

我认为printf("Print content of string2\t= %s\n", *string2);是通过string2打印b内容的正确方法,但显然这是错误的方法。

printf("Print content of string2\t= %s\n", string2);

即使在 string2 之前没有引用运算符,也会打印整个字符串,因为 %s,按照标准定义,需要一个 char *,即地址。 Refer here

Why does the last printf show us the content of b?

数组中第一个元素的地址是数组本身的地址。 => 您也可以将 string2 用作 b

Variable names don't exist anymore after the compiler runs , program care address of variable

参考这个:How are variable names stored in memory in C?

你最好重温你的 C 书的内存地址 & 指针 章节。

假设你是运行一个32位系统,它使用4字节寻址内存&内存状态您的代码是:

// char array "b"
address   value
=======   =====
aaaa:0001 A // hex value 41
aaaa:0002 m // hex value 6d
aaaa:0003 o // hex value 6f
aaaa:0004 n // hex value 6e
aaaa:0005 g
aaaa:0006   // that's a "space" char, hex value 20
aaaa:0007 U
aaaa:0008 s
aaaa:0009 0 // that's a zero, hex value 00

// pointer "string2"
// pointing to "aaaa:0001"
// in reverse order
// depending on endianness of your system
address   value
=======   =====
ffff:0001 01
ffff:0002 00
ffff:0003 aa
ffff:0004 aa
  1. 您的第一个 printf 将打印 aaaa:0001 为十六进制;即数组 b.
  2. 的内存地址
  3. 你的第二个 printf 将打印 aaaa:0001 为十六进制;即存储在地址 ffff:0001ffff:0004 中的值。从格式说明符 %p,编译器将知道它将打印一个内存地址并读取 4 个字节并在打印前还原它们。
  4. 您的第三个 printf 将打印 Among Us;从格式说明符 %s 中,编译器将知道它将打印一个字符数组并打印字符 它指向的地址 ,直到 printf到达一个字符串终止符,它是 0.

说明符 %p%s 都需要一个指针。

%p 将打印指针的 value

但是%s使用指针来打印一个C字符串,即由'[=15=]'分隔的char数组。

如果你给出*string2,它不是指针。它是指针指向的对象的值,在您的例子中是 char.

将编译器的警告级别提高到最大,希望它足够聪明,可以识别格式字符串并检查参数。