簡體   English   中英

需要左值作為增量操作數 - + 一元運算符

[英]lvalue required as increment operand - + unary operator

有人可以解釋一下嗎:

#include <stdio.h>
#include <stdlib.h>

int main (void) {

   int i = 0,j;
   j=(+i)++;

   return 0;
}

應該是

將左值轉換為右值示例

據此: C 中的一元加號 (+) 運算符的目的是什么? , 並給出錯誤: lvalue required as increment operand +一元運算符如何工作?

我在這個網站上發現的另一種用法:

 little known: The unary plus operator can be used as an "decay
 operator": Given int a[10]; int b(void);, then +a is an int pointer
 and +b is a function pointer. Useful if you want to pass it to a
 template accepting a reference

有人也可以解釋一下嗎?

+ 一元運算符如何工作?

我相信一元-更容易理解,因為它實際上“做了”一些“可見”的事情。 我的意思是,讓int k = 5 then -k很簡單——它將正值5變成負值-5 一元- “計算”它的操作數的負數。

內置的一元+只返回其操作數的值。 結束。 它什么也不做。 但是,應用一元運算符會對其參數執行標准中指定的提升 cppreference 運營商

內置的一元加號運算符返回其操作數的值。 它不是空操作的唯一情況是當操作數具有整數類型或無作用域枚舉類型時,這會通過整數提升來更改,例如,它將 char 轉換為 int 或者如果操作數受制於左值到右值,數組到指針或函數到指針的轉換。

所以short值被提升為int 左值更改為右值。 數組類型衰減為指針。 並且 function 類型衰減為 function 指針。 Cppreference 值轉換

Lvalue(“左值”)是您可以分配的東西。 在您的代碼中i是一個變量,您可以i = 1將值1分配給i 並且2 + 2是一個值為4的右值(“正確的值”) - 你不能“分配”任何東西給2 + 2 ,它已經有了一個值。
+i是應用於i的一元+的結果 - i經歷了 integer 提升和左值到右值轉換,並且在這些轉換之后,一元+操作的結果與i具有相同的值和類型。

摘自C11 第 6.5.3.3 段 - 第 2 項:

一元+運算符的結果是其(提升的)操作數的值。 對操作數執行 integer 提升,結果具有提升類型。

所以基本上,效果幾乎總是無操作,除了對其操作數的int類型提升。 例如,

char a = 6;

size_t size_pre_promotion = sizeof(a);
size_t size_post_promotion = sizeof(+a);

由於從charinttype提升,操作數a大小1增長到4 操作數的,原封不動地返回。

來自評論: “將左值變成右值”,這就是我不明白的......

(+1)周圍加括號的效果

int j = (+i)++;  

在這個表達式(+i)++中,括號()強制執行i (從表達式+ilvaluervalue的轉換,在詞法上緊隨其后的是++運算符嘗試增加i的值。 (從lexically ,因為這個表達式永遠不會超過編譯時進入運行時。)此時, i不再是左值,因此它不再是可賦值的,因此不能接受如果操作數是通常會發生的遞增操作仍然是一個左值。

有趣的是,通過說明,以下表達式是完全合法的:

int j = (+i);//Not attempting to assign value (increment) the operand
             //so the _value_ returned from the operand is successfully assigned
             //to the lvalue `j`;


int j = +i++;//Assigns the i + 1 to j
        //in this case the `++` adds `1` to the operand, then the `+` unary operator returns the incremented value (essentially a no-op at this point),  which in turn is assigned to the _lvalue_ `j`.  

一元運算符+lvalue轉換為rvalue
這些術語基本上可以分別被認為是可轉讓的和不可轉讓的。

這些表達式也表明:

int j;
&j; //address of an lvalue

是合法的。 但:

&(+j);//cannot _take_ the address of an rvalue

不是。

左值是可能指定 object(內存中的字節)的表達式。 左值最常見的形式只是一個名稱:給定int xfloat ychar z[10] ,則xyz是左值。 左值的另一種形式是一元*的結果:給定double *p; , 那么*p是一個左值。 1

當我們使用左值來計算表達式時,它們被轉換為它們的對象的值: x+3x中的任何值多產生三個。 在這個表達式中, x用於它的 相反,在x = 7; , x直接用作它的左值; 7 被寫入 memory 中的字節,無論它們先前包含什么值。

由於 C 標准必須指定編譯器在技術細節中的行為方式,因此它規定,當在表達式中我們想要其值的地方使用左值時,該左值將轉換為值。 為了強調這個結果只是一個數字或類似的東西,不再是對 memory 的引用,它可能被稱為rvalue

一元+是一個運算符。 當應用於算術值時,它會產生相同的值。 但是,它只產生一個值,而不是一個左值。 因此,將+應用於左值會產生右值。

腳注

1這就是左值可能指定 object 的原因: *p是左值,在編譯期間被視為左值,但是,當程序執行時, p可能設置為 null 指針,因此*p實際上不會是 ZA8CFFDE6331BD59B26696C . 那將是程序中的錯誤,但它是運行時錯誤。

++運算符期望它的操作數是一個左值- 基本上,一個可以指定 object 的表達式(在 C 意義上,一塊 memory 可以用來存儲一個值)。

然而,一元+運算符的結果不是左值。 在這種情況下, +i的結果就是值0 ,所以表達式相當於寫成0++ 您不能像不能寫0 = 1一樣將++運算符應用於0 - 您不能將值分配給值,只能通過左值將值分配給 object。

請注意,以下將起作用:

j = +(i++); // or just +i++, precedence is the same

您將+運算符應用於i++的結果,即0 (后綴++計算為i當前值,並且作為副作用遞增i )。 i++的結果也不是左值,但+並不要求其操作數是左值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM