为什么 *str1 和 *(&str1),其中 str 是 C 中一个字符数组的名称,求值结果不同?
Why *str1 and *(&str1), with str being the name of a char array in C, do not evaluate to the same result?
代码很简单,但我就是不明白它是如何工作的。所有三个变量似乎都存储在同一地址,可能 str1 只是 str[0] 的别名,但是当我尝试取消引用它们时,我得到了不同的结果。
#include <stdio.h>
int main() {
char str1[] = "Hello";
printf("<========Addresses: =======> \n");
printf("%d\n", &str1[0]);
printf("%d\n", &str1);
printf("%d\n", str1);
printf("<========Values stored at the address(?!)=======> \n");
printf("%d\n", *(&str1[0]));
printf("%d\n", *(&str1));
printf("%d\n", *str1);
return 0;
}
这就是它打印的内容。
<========Addresses: =======>
6356458
6356458
6356458
<========Values> stored at the address=======>
72
6356458
72
首先让我们回顾一下您所拥有的指针:
&str1[0]
:这是指向数组第一个元素的指针。它的类型是char *
.
&str1
:这是指向数组本身的指针。它的类型是 char (*)[6]
(不要忘记 C 中的字符串是空终止的,终止符也需要 space)。
str1
:这将衰减指向数组第一个元素的指针,并且正好等于&str1[0]
(即第一个)。
现在我们知道第一个和第三个指针是指向数组中单个元素的指针(索引 0
处的第一个元素),很容易看出当我们用一元取消引用它时会发生什么*
运算符:我们获取指针指向的元素的值。即字母'H'
,在ASCII编码中的值为72
。
解释*(&str1)
的结果其实很简单,去掉括号就可以得到*&str1
。那么很容易看出取消引用和寻址运算符将相互抵消,留下 str1
。如上所述,str1
等于 &str1[0]
,即指向数组中第一个元素的指针。
代码很简单,但我就是不明白它是如何工作的。所有三个变量似乎都存储在同一地址,可能 str1 只是 str[0] 的别名,但是当我尝试取消引用它们时,我得到了不同的结果。
#include <stdio.h>
int main() {
char str1[] = "Hello";
printf("<========Addresses: =======> \n");
printf("%d\n", &str1[0]);
printf("%d\n", &str1);
printf("%d\n", str1);
printf("<========Values stored at the address(?!)=======> \n");
printf("%d\n", *(&str1[0]));
printf("%d\n", *(&str1));
printf("%d\n", *str1);
return 0;
}
这就是它打印的内容。
<========Addresses: =======>
6356458
6356458
6356458
<========Values> stored at the address=======>
72
6356458
72
首先让我们回顾一下您所拥有的指针:
&str1[0]
:这是指向数组第一个元素的指针。它的类型是char *
.&str1
:这是指向数组本身的指针。它的类型是char (*)[6]
(不要忘记 C 中的字符串是空终止的,终止符也需要 space)。str1
:这将衰减指向数组第一个元素的指针,并且正好等于&str1[0]
(即第一个)。
现在我们知道第一个和第三个指针是指向数组中单个元素的指针(索引 0
处的第一个元素),很容易看出当我们用一元取消引用它时会发生什么*
运算符:我们获取指针指向的元素的值。即字母'H'
,在ASCII编码中的值为72
。
解释*(&str1)
的结果其实很简单,去掉括号就可以得到*&str1
。那么很容易看出取消引用和寻址运算符将相互抵消,留下 str1
。如上所述,str1
等于 &str1[0]
,即指向数组中第一个元素的指针。