为什么打印指向 char 的指针的指针的第一个元素会打印字符串的内容?

Why does printing the first element of a pointer to pointer to a char print the contents of a string?

示例代码

int main() {

char *s = "kut";
char **p = &s;
printf("*s:     %c\n", *s);
printf("s:      %p\n", s);
printf("&s[0]:  %p\n", &s[0]);
printf("p:      %p\n", p);
printf("*p:     %p\n", *p);
printf("**p:    %c\n", **p);
printf("p[0]:   %s\n", p[0]);
printf("&p[0]:  %p\n", &p[0]);

return 0;
}

输出:

*s:     k
s:      0x1043acf46
&s[0]:  0x1043acf46
p:      0x7ffeeb853670
*p:     0x1043acf46
**p:    k
p[0]:   kut
&p[0]:  0x7ffeeb853670

&p[0]p[0] 的地址)怎么会打印出字符串kut?输出显示 p[0] 的地址与 p 相同(因为 p 只是指向数组第一个元素的常量指针)。

对于任何指针或数组 p 和索引 i,表达式 p[i] 正好 等于 *(p + i)

如果 i == 0 那么我们有 p[0] 等于 *(p + 0) 又等于 *(p)*p 相同。

在您的情况下 *ps 相同。

printf("%s", p[0]) 表示您要打印从位置 p[0] 或 (*p) 开始并在到达 [=11=] 字符时结束的字符串。

让我们从变量之间如何相互关联的图表开始:

   char **       char *     char
   +---+         +---+      +---+---+---+---+
p: |   |----> s: |   |----> |'k'|'u'|'t'| 0 |
   +---+         +---+      +---+---+---+---+

p存储s的地址,s存储字符串字面量"kut"中第一个字符的地址,存储为[的数组=19=] 内存中某处。

鉴于此,以下关系都是正确的:

  p == &s
 *p ==  s == &"kut"[0]           // believe it or not, this is legal - you 
**p == *s ==  "kut"[0] == 'k'    // can index into a string literal

鉴于a[i]定义为*(a + i),这也意味着

*p == *(p + 0) == p[0] == s

&p[0] == &(*(p + 0)) == &(*p) == p;

*p[0] == *(*(p + 0)) == *(*p) == **p 

How does it come that &p[0] (address of p[0]) does print out the string kut?

首先你错了。这个说法

printf("&p[0]:  %p\n", &p[0]);

输出指针的地址s

&p[0]:  0x7ffeeb853670

看来你指的是这个调用的输出

printf("p[0]:   %s\n", p[0]);

确实在控制台上显示了字符串文字

p[0]:   kut

函数 printf 中使用的转换说明符 %s 需要指向字符串第一个字符的指针。

例如printf的这个调用

printf("s:      %p\n", s);

输出整个字符串文字 "kut".

指针p声明为

char **p = &s;

并指向指针s

因此取消对指针的引用,如 p[0]*p(相同)会产生指针的值 s。即 p[0] 等于 s。所以这个调用

printf("p[0]:   %s\n", p[0]);

与此调用效果相同

printf("s:      %p\n", s);

因为调用的秒参数具有相同的类型和值。

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    char *s = "kut";
    char **p = &s;
    
    printf( "p[0] == s is %s\n", p[0] == s ? "true" : "false" );
    
    return 0;
}

它的输出是

p[0] == s is true