首页 > 解决方案 > 在 C 或 C++ 中,有没有办法获取 i++ 或 ++i 的地址(i 是 int 类型)?

问题描述

有没有办法写如下:

int i = 0;
int *p1 = &(i++);
int *p2 = &(++i);

标签: c++c

解决方案


在问“有没有办法”之前,我想我们必须问,“这意味着什么?”

在 C 中,我们有“对象”与“值”的概念。基本上,对象是可以保存值的东西。所以一个变量像

int a;

显然是一个对象,因为它可以保存一个值——也就是说,我们可以这样说

a = 5;

将值存储到a.

对象和值之间的主要区别在于对象具有位置。另一方面,一个值是我们计算出来的东西,它只是在空间中浮动,如果我们很快没有找到一个对象来存储它,它就会消失。

(旁注:您有时会遇到术语“左值”和“右值”,这与我在这里使用的“对象”和“值”的含义相同。左值是可以出现在赋值运算符的左侧,而右值只能出现在右侧。)

我已经完成了这个冗长的背景介绍,只是为了说明这一点:您只能将 address-of 运算符应用于对象,因为只有对象才有位置。 说起来完全有道理

int *p = &a;

但是说出来就没意思了

int *p2 = &5;            /* WRONG */

或者

int *p3 = &(1 + 2);      /* WRONG */

所以写同样没有意义

int *p4 = &(a + 1);      /* WRONG */

变量a是一个对象,但是通过获取a的值并将其加 1 得到的东西显然只是一个值。当我们计算出该值时,该值的计算的一部分涉及从 object 获取值并不重要(我们可能已经忘记了)a

但随后我们会回答您的问题。假设你尝试写

int *p5 = &(i++);        /* questionable */
int *p6 = &(++i);

运算符取一个值加++1,这个值i + 1显然只是一个值,没有位置。但是,它是真的,i++而且++i不仅仅意味着“ i + 1”——它们计算值i + 1 并将其存储回i. 因此,您几乎可以说服自己i++++i拥有位置 - 但如果他们这样做了,那将只是变量的位置i。所以你还不如说

int *p7 = &i;

现在,您可能会问,“但是,如果我想获取 的地址i,同时增加它的值怎么办?” 答案是,您只需分两步完成:

int *p7 = &i;
i++;

是的,这是真的,i++and++i运算符很好,因为它们可以让你同时做两件事,比如

int x = array[i++];

或者

int x = *p++;

但这些都是有用的操作,因为当您使用数组时它们总是会出现。但是有必要说一下

int *p5 = &(i++);

我认为出现的频率要低得多,因此让它发挥作用并不是那么重要。(我,我已经用 C 编程了 40 年,我认为我从来没有觉得需要同时获取一个指针i并递增它。)++操作符是经常出现的东西一个循环,就像i在一个数组或其他东西中移动一样。但是由于地址i不会改变,如果你需要一个指向它的指针,那么在循环(或其他任何东西)开始之前只做一次是有意义的。

最后,不管你是否同意我到目前为止的解释,C 标准明确指出++and--运算符的结果是右值,而不是左值。我刚刚尝试过的两个编译器给了我错误

error: cannot take the address of an rvalue of type 'int'

error: lvalue required as unary ‘&’ operand

这些错误信息与我一直在讲述的故事几乎相同。

虽然,为了在我一直讲的这个故事中投入一个相当大的活​​动扳手,C++ 中的规则显然不同!你做不到&(i++),但你可以做到&(++i)!我认为这是有充分理由的,但我不记得它是什么。


推荐阅读