簡體   English   中英

具有增量和減量運算符的指針

[英]Pointers with increment and decrement operators

通常,當賦值運算符存在時,左操作數應該是變量而不是表達式,但是當我使用指針使左側成為表達式時,代碼不會產生任何錯誤。

Jdoodle在線編譯器/ C

它應該拋出一個錯誤,但是編譯成功了。

https://www.jdoodle.com/c-online-compiler

#include <stdio.h>

int main()
{
    int x = 30, *y, *z;

    y = &x; // Assume address of x is 1000 and integer is 4 byte size */
    z = y;
    *y++ = *z++;
    x++;
    return 0;
}

賦值的左操作數不必是變量。 例如,以下分配應該並且確實可以很好地工作(我假設您知道這一點,並且只是弄錯了):

array[index] = value;
*ptr = value;

我認為*y++ = *z++;讓您感到困惑*y++ = *z++; 是您認為它是分配給增量操作的結果,的確沒有任何意義。 但這不是該表達式的優先級: *y++等效於*(y++) ,而不是(*y)++ 因此,您要取消引用y++的結果,然后將一個值分配給該已取消引用的內存位置,就像您編寫了一樣:

int *ptr = y++;
*ptr = *z++;

通常,當賦值運算符存在時,左操作數應為變量而不是表達式...

賦值運算符的左操作數始終是一個表達式。 限制是它必須是lvalue ,它是(簡化一點)指定對象的表達式。

左值的最簡單情況是聲明的對象/變量的名稱,例如:

int n;
n = 42;

n是一個表達式,特別是一個左值,它指定名為n的對象。

在您的示例中,您具有:

*y++ = *z++;

運算符優先級表示++運算符比*運算符綁定更緊密,因此等效於:

*(y++) = *(z++);

y++z++不是值-它們是產生指針值的表達式,但它們不指定任何對象。 但是,即使其操作數不是左值,一元*運算符也會為您提供左值。 y++產生一個指針值, *(y++)為您提供該指針指向的對象。

在這種意義上,C標准不使用術語“變量”。 它討論對象 ,可以使用簡單名稱聲明對象,也可以不使用簡單名稱聲明對象。 an_object*pointer_valuearray[index]structure_object.member均引用對象,並且可以出現在分配的左側。

左操作數應該是一個變量而不是一個表達

這是一個誤會。 您正在尋找的期限為左值 這是源自術語“左側值”的C標准亂碼。 左值的定義大致是:一個指定對象的表達式。

這里討論的各種運營商的規則是:

  • 賦值運算符的左操作數必須始終為左值。
  • 一元*運算符的結果被定義為始終為左值,因此您可以將其用作對象,然后將其賦值。
  • 但是,++運算符的結果不是左值,因此不能用作賦值的左操作數。

例子:

int x; int* y;

x = 5;   // Here x is both an object and an lvalue, so the code is valid
y = &x;  // y is both a (pointer) object and an lvalue, code is valid.
*y = 0;  // *y is an lvalue designating the object y, code is valid
y++ = 1; // y++ is not an lvalue, the code is invalid

至於*y++為何起作用,這只是運算符優先級的問題。 首先應用++,但是由於它是后綴,因此直到表達式末尾才進行更改。 因此, *應用於y ,結果是左值。

你寫過++*y = 0; 則運算符的關聯性導致*首先執行* ,結果*y為左值。 然后,當您對該左值使用++時, ++的結果不是左值,因此代碼無效。 ++*y本身是有效的代碼,但不能是賦值的左操作數。

假設x地址為1000並且sizeof(int) = 4 (對於32-bit編譯器),則在計算表達式時:

 *y++=*z++;

z的地址遞增

(因為,后遞增(x ++)的優先級高於(* x))

但在該右值之前,即由z存儲的地址分配給指針y 之后,僅進行地址增加和取消引用。

*y++的情況類似,第一個地址被分配,后遞增發生,然后被取消引用。 如果您對左值是變量感到困惑,則沒有必要,例如:用有效地址初始化指針后,在代碼中添加一條語句

*y++;

也是正確的,不會標記任何錯誤。

暫無
暫無

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

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