[英]Pointers on C, need simple verification
问题是Reek先前提到的手册的一部分。 我得到了变量:
h under 1080 address with value 1020
i under 1020 address with value 1080.
将h
和i
视为integers
pointers
时,请评估表达式** h的L-value
和R-value
。 我的回答是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;
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
,现在真正的问题是:“评估表达式的R值” *i
是什么意思? ...在这种情况下,左值和右值有什么区别?
MSDN关于“ L值和R值表达式”的文章指出: “如果标识符指向内存位置,则标识符是可修改的L值...如果ptr
是指向存储区域的指针,则*ptr
是可修改的l值,指定ptr
指向的存储区域。” 〜换句话说:如果将表达式*i
视为l值,则与直接使用h
相同。 〜> h
值== 1020。
它还指出: “术语“ r值”有时用于描述表达式的值并将其与l值区分开。所有l值都是r值,但并非所有r值都是l值”。 〜换句话说(对于这种情况,我的解释是):如果将*i
视为r值,则不应将其视为变量h
的别名,而应将其视为表达式本身的值。 〜>解释为什么*i
可以被视为&h
。
事实证明,这是有争议的,因为如果按照我的指示,“所有变量都是指向整数的指针”,则表达式** h是非法的。 双重间接寻址仅在指向整数的指针上合法。 这是我的错 早期的C编译器对变量的强类型化不太挑剔,并且会为此表达式生成代码。 但是,经验告诉C世界,这不是一个好主意,因此强类型化成为常态。 但是现在假设我们更改表达式
** h至**(int **)h
h的R值为1020(存储在其中的值)。 * h的R值是存储在1020的值,即1080。那么** h的值将是存储在1080的值,即1020。L值是此最终结果的地址,即1080所以你是正确的,我搞砸了。 接得好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.