打印存储指向C中数组的指针的地址

Print the address that stores the pointer points to an array in C

这个问题可能看起来很重复;不过我确实在这个网站上认真调查过,还是不太明白。

    char str[] = "test";
    printf("%p\n", str);
    printf("%p\n", &str);

我知道str本身就是一个指针,指向存储“t”的起始位置。因此我希望 printf("%p\n", str); 显示此地址(比如 000000FFE94FFC34)。接下来,我想知道在我的 OS 中,存储确切信息的内存位置 000000FFE94FFC34。 (即 str 本身的地址。)

然而,第三行的输出与上一行相同。这似乎是一种很奇怪的行为。我怎样才能找出 str 本身的地址?我想这可以通过使用另一个指向我想要的指针的新指针来实现,即 char **super_pointer = str; 但我认为这是一种不必要的复杂方式。

让我们用添加的指针将其绘制出来,希望它更容易理解:

+--------+--------+--------+--------+--------+
| str[0] | str[1] | str[2] | str[3] | str[4] |
+--------+--------+--------+--------+--------+
^
|
&str[0]
|
&str

如您所见,指向第一个元素的指针(&str[0] 是普通 str 衰减到的)指向与数组本身相同的位置 (&str)。

但是(而且很重要但是):类型很不一样!

&str[0]的类型是char *

&str的类型是char (*)[5]


在另一张纸条上你说

... str itself is a pointer...

这是错误的str 本身就是数组,它可以衰减 到指向其第一个元素的指针。

I know str itself is a pointer which points to the starting location that stores "t".

正如您所说,“str 本身”不是一个指针,而是一个数组。但在表达式中使用的数组指示符在极少数情况下被转换为指向其第一个元素的指针。

来自 C 标准(6.3.2.1 左值、数组和函数指示符)

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

在本次通话中

printf("%p\n", str);

用作参数表达式的数组指示符 str 被转换为指向其第一个元素的指针。实际上这个调用相当于

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

即本次调用输出数组占用内存范围的起始地址

这次通话

printf("%p\n", &str);

最好写成和前面的调用一样

printf("%p\n", ( void * )&str);

同时输出数组占用内存范围的起始地址

有什么区别?

调用 printf 时使用的表达式 str 的类型为 char * 而表达式 &str 的类型为 char ( * )[5].

调用将这两个表达式解释为 void *.

类型的表达式

为了更清楚地考虑二维数组

char str[2][6] = { "test1", "test2" };

整个数组的地址与其第一个“行”的地址以及第一个“行”的第一个字符的地址重合。

即具有 char ( * )[2][6] 类型的表达式 &sgtr 和具有 char ( * )[6] 类型的表达式 &str[0] 以及具有 &str[0][0] 的表达式类型 char * 产生相同的值:hhe 数组占用的内存范围的起始地址..