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
}
在以下 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
}