有没有办法写如下所示的内容:
int i = 0;
int *p1 = &(i++);
int *p2 = &(++i);
Run Code Online (Sandbox Code Playgroud)
在问“有没有办法”之前,我想我们必须问“这意味着什么?”
\n在C语言中,我们有“对象”与“值”的概念。基本上,对象是可以保存值的东西。所以像这样的变量
\nint a;\nRun Code Online (Sandbox Code Playgroud)\n显然是一个对象,因为它可以保存一个值 \xe2\x80\x94 也就是说,我们可以这样说
\na = 5;\nRun Code Online (Sandbox Code Playgroud)\n将值存储到a.
对象和值之间的主要区别在于对象具有位置。另一方面,值是我们计算出来的东西,它只是漂浮在空间中,如果我们很快找不到一个对象来存储它,它就会消失。
\n(旁注:您有时会遇到术语“左值”和“右值”,它们与我在这里使用的“对象”和“值”含义相同。左值是可以出现在赋值运算符位于左侧,而右值只能出现在右侧。)
\n我已经完成了这个冗长的背景介绍,这样我就可以指出这一点:您只能将地址运算符应用于对象,因为只有对象才有位置。 说得很有道理
\nint *p = &a;\nRun Code Online (Sandbox Code Playgroud)\n但这样说是没有意义的
\nint *p2 = &5; /* WRONG */\nRun Code Online (Sandbox Code Playgroud)\n或者
\nint *p3 = &(1 + 2); /* WRONG */\nRun Code Online (Sandbox Code Playgroud)\n所以写同样没有意义
\nint *p4 = &(a + 1); /* WRONG */\nRun Code Online (Sandbox Code Playgroud)\n变量a是一个对象,但是通过获取 的值并将其加 1 所得到的东西a显然只是一个值。当我们计算出该值时,该值计算的一部分涉及从对象中获取值并不重要(我们可能已经忘记了)a。
但随后我们会回答您的问题。假设你尝试写
\nint *p5 = &(i++); /* questionable */\nint *p6 = &(++i);\nRun Code Online (Sandbox Code Playgroud)\n该++运算符获取一个值并将其加 1,该值i + 1显然只是一个值,没有位置。但是,这是真的,i++并且++i意味着不仅仅是“ i + 1”\xe2\x80\x94,它们计算值i + 1 并将其存储回i. 所以你几乎可以说服自己,i++并且++i有位置 \xe2\x80\x94 但如果他们这样做,它只是变量的位置i。所以你也可能刚刚说过
int *p7 = &i;\nRun Code Online (Sandbox Code Playgroud)\n现在,您可能会问,“但是如果我想获取 的地址i,同时将其递增呢?” 答案是,您只需分两步即可完成:
int *p7 = &i;\ni++;\nRun Code Online (Sandbox Code Playgroud)\n是的,确实如此,i++and++i运算符很好,因为它们可以让你同时做两件事,比如
int x = array[i++];\nRun Code Online (Sandbox Code Playgroud)\n或者
\nint x = *p++;\nRun Code Online (Sandbox Code Playgroud)\n但这些都是有用的操作,因为当您使用数组时它们总是会出现。但需要说类似的话
\nint *p5 = &(i++);\nRun Code Online (Sandbox Code Playgroud)\n我认为,这种情况出现的频率要低得多,因此让它发挥作用并不是那么重要。(我,我已经用 C 语言编程了 40 年,我认为我从来没有感觉到有必要同时抓取一个指向它的指针i并对其进行递增。)++运算符是经常出现在循环,就像i在数组或其他东西中移动一样。但由于 的地址i不会改变,如果您需要指向它的指针,那么在循环(或其他)甚至开始之前只执行一次是有意义的。
最后,无论您是否同意我到目前为止的解释,C 标准明确表示++and--运算符的结果是右值,而不是左值。我刚刚尝试过的两个编译器给了我错误
error: cannot take the address of an rvalue of type 'int'\nRun Code Online (Sandbox Code Playgroud)\n和
\nerror: lvalue required as unary \xe2\x80\x98&\xe2\x80\x99 operand\nRun Code Online (Sandbox Code Playgroud)\n这些错误消息几乎讲述了我一直在讲的同样的故事。
\n不过,对于我一直在讲的这个故事来说,C++ 中的规则显然是不同的!你做不到&(i++),但你可以做&(++i)!我认为这是有充分理由的,但我不记得是什么了。