Array 和 Array[0] 混淆

Array and Array[0] confusion

在以下 C 代码中:

char test[] ={'T','e','s','t'};

printf("%d\n",test == &test[0]); // Returns 1 - Okay as array varaible holds address of first element

所以下面的不应该打印相同的吗?:

printf("value of test %c\n", test); // prints - '|' not even in the array
printf("value of test[0] %c\n", test[0]); // prints - 'T'

不仅如此,甚至这些打印出不同的值:

printf("value of test %p\n", test); // contains a address 0x7ffee9b22b7c
printf("value of test[0] %p\n", test[0]); // also conatains 0x100

发生了什么事?

谢谢

您在第一个示例中回答了您自己的问题:

test == &test[0]

test != test[0] // otherwise, test[0] would have to be equal to &test[0]

test(解释为指针)等于test[0]地址。因此,您的以下示例不可能是真的,因为这意味着对于其中任何一个,它的值都将等于它自己的地址,这没有意义!

(注:以下地址当然是示例。)

Expression Type Value interpreted as character %c Value interpreted as pointer %p
test char* nonsensical 0x1000
&test char** nonsensical 0x2000
test[0] char T nonsensical
&test[0] char* nonsensical 0x1000
test[1] char e nonsensical
&test[1] char* nonsensical 0x1001
test[2] char s nonsensical
&test[2] char* nonsensical 0x1002
test[3] char t nonsensical
&test[3] char* nonsensical 0x1003

注意:为了理解您最初的问题,可以将 test 视为 char*,因此将 &test 视为 char**。然而,实际上它有点复杂, test 实际上是 char(*)[4] 类型。例如,这与 sizeof 不同。

指针衰减

虽然指针和数组是不同类型的变量,但数组变量通常被隐式转换为指向其第一个元素的指针。这叫做array to pointer decay

这就是您在 test&test[0] 之间进行比较时发生的情况:test 衰减为可以与 &test[0] 进行比较的指针,并且它们值相等

您的 printf 通话中发生了什么?

printf("value of test %c\n", test); // prints - '|' not even in the array
printf("value of test[0] %c\n", test[0]); // prints - 'T'

第一个带有转换说明符 %c 的将参数转换为 unsigned char 并打印字符。 在第一行打印 test 作为字符,在第二行打印 test[0] 作为字符。

test[0] 的类型确实是 char,因此打印出正确的字符(T)。但是 test 的类型是 char 的数组,在这种情况下,它也衰减为指针。在您执行测试时,该指针恰好具有 0x7ffee9b22b7c 的值。然后这个值被转换为 unsigned char 所以你的指针的最后一个字节被保留,在这种情况下是 7c 恰好是字符 | 的 ASCII 代码。

请注意,由于它取决于指针的值,因此每次 运行 程序时很可能会打印出不同的字符(其中一些甚至可能不是可打印字符)。

两个结果不同,因为它们是不同的东西:一个是字符,另一个是指针(在本例中是指向字符的指针)。

test[0] 是数组开头 包含的 值,而 test 被评估为指向第一个元素的指针(并且然后强行转换为字符)。正如您之前提到的,test 等同于 &test[0] 而不是 等同于 test[0].

test[0] 等同于 *test(或 *(test + 0))。通常在数组中,array[i] 将等同于 *(array +i).

您可能对自己的打印方式感到困惑。试试这个,看看它是否更容易理解。

#include <stdio.h>


int main(){

    char test[] = "Test\n[=10=]"; // an array that contains char values
    char *testptr; // a pointer that can point to a place in memory that contains a char value


    printf(test); // by default it will print all of the char values starting with test[0]

    testptr = &test[2]; // the pointer now points to the third position in the char array

    printf(testptr); // print the test array starting with the pointers position

}