C上的指针需要简单的验证

时间:2013-09-03 13:25:22

标签: c pointer-arithmetic

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

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

在将L-valueR-value视为hi时,评估表达式** h的pointersintegers。 我的答案是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;

2 个答案:

答案 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所以你是对的,我搞砸了。好抓。