-1

问题是 Reek 前面提到的手册的一部分。我有变量:

h under 1080 address with value 1020
i under 1020 address with value 1080.

L-value当将and视为时,计算R-value表达式 **h 的hand 。我的回答是,但是教练指南说:。谁对谁错?ipointersintegersR:1020 L:1080R: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;

4

2 回答 2

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)

so**h等于*i,现在真正的问题是:“评估表达式的 R 值”是什么意思*i?...在这种情况下,左值和右值有什么区别?

MSDN 关于“L-Value and R-Value Expressions”的文章指出:“一个标识符是一个可修改的左值,如果它指的是一个内存位置……如果ptr是一个指向存储区域的指针,那么*ptr它就是一个可修改的左值指定ptr指向的存储区域。” ~ 换句话说:如果您将表达式*i视为左值,则与h直接使用相同。~> h== 1020 的值。

它还指出:“术语“右值”有时用于描述表达式的值并将其与左值区分开来。所有左值都是右值,但并非所有右值都是左值。” ~ 换句话说(我对这种情况的解释):如果您将*i其视为 r 值,则不应将其视为变量的别名,h而应将其视为表达式本身的值。~> 解释为什么*i可以考虑&h

于 2013-09-03T14:12:11.560 回答
0

事实证明,这是一个有争议的问题,因为如果按照我的指示“所有变量都是指向整数的指针”,则表达式 **h 是非法的。双重间接仅在指向整数指针的指针上是合法的。这是我的错误。早期的 C 编译器对变量的强类型不太挑剔,并且会为这个表达式生成代码。然而,经验告诉 C 世界这不是一个好主意,所以强类型化成为常态。但是现在假设我们改变表达式

**h 到 **(int **)h

h 的 R 值为 1020(存储在那里的值)。*h的R值就是存储在1020的值,即1080。那么**h的值就是存储在1080的值,即1020。L值就是这个最终结果的地址,即1080 .所以你是对的,我搞砸了。接得好。

于 2018-03-10T00:28:12.103 回答