问题是Reek之前提到的手册的一部分。 我有变量:
h under 1080 address with value 1020
i under 1020 address with value 1080.
在将L-value
和R-value
视为h
至i
时,评估表达式** h的pointers
和integers
。
我的答案是R:1020 L:1080
,但是教师指南说:R:1080, L:1020
。
谁对谁谁错了?
Step by step:
R-value first:
h=1020
*h=*(1020)=1080
**h=*(*h)=*(1080)=1020
L-value:
same, but value is address of value 1020, so 1080.
好的,这是应该工作的代码。如果它按计划工作,它证明** h在这种情况下= h。
#include <stdio.h>
int main(void)
{
unsigned int * h;
unsigned int *i;
unsigned int ans=0;
h=&i;
i=&h;
printf("h=%u &h=%u i=%u &i=%u\n", h, &h, i, &i);
ans=*(unsigned int *)*h;
printf("**h=%u\n", ans);
*(unsigned int *)*h=1;
printf("h=%u &h=%u i=%u &i=%u\n", h, &h, i, &i);
return 0;
}
在这里'输出我得到:
h=3214580856 &h=3214580852 i=3214580852 &i=3214580856
**h=3214580856
h=1 &h=3214580852 i=3214580852 &i=3214580856
在最后一行我做了** h = 1;
答案 0 :(得分:3)
addr | value
... | ...
1020 | 1080 <-- i
... | ...
1080 | 1020 <-- h
代码看起来如下:
int* h;
int* i;
h = &i; // h pointing to the address of i (= 1020)
i = &h; // i pointing to the address of h (= 1080)
所以**h
等于*i
,现在真正的问题是:“评估表达式”*i
的R值意味着什么? ......在这种情况下,l值和r值之间有什么区别?
MSDN's article on "L-Value and R-Value Expressions"状态:“如果标识符引用内存位置,则标识符是可修改的l值...如果ptr
是指向存储区域的指针,则{{1是一个可修改的l值,用于指定*ptr
指向的存储区域。“〜换句话说:如果将表达式ptr
看作l值,它是与直接使用*i
一样。 〜&GT;值h
== 1020。
它还指出:“术语”r值“有时用于描述表达式的值并将其与l值区分开来。所有l值都是r值但不是全部r -values是l值。“〜换句话说(我对这种情况的解释):如果你将h
视为r值,你不应该把它看作变量的别名*i
而是表达式本身的价值。 〜&GT;解释为什么h
可以被视为*i
。
答案 1 :(得分:0)
事实证明这是一个没有实际意义的点,因为如果“我所指示的”所有变量都是指向整数的指针“,表达式** h是非法的。双重间接仅对指向整数指针的指针是合法的。这是我的错。早期的C编译器对变量的强类型不那么挑剔,并且会为这个表达式生成代码。然而,经验告诉C世界,这不是一个好主意,所以强大的打字成为常态。但现在假设我们改变了表达式
** h到**(int **)h
h的R值是1020(存储在那里的值)。 * h的R值是存储在1020的值,即1080.然后** h的值将是存储在1080的值,即1020.L值将是该最终结果的地址,即1080所以你是对的,我搞砸了。好抓。