[英]Post-increment in a while loop
以下代碼讓我有點困惑:
char * strcpy(char * p, const char * q) {
while (*p++=*q++);
//return
}
這是strcpy
函數的精簡實現。 從這段代碼中,我們看到指針p
和q
遞增然后解除引用, q
被賦值給p
直到達到\\0
char。
我想有人解釋while循環的第一次迭代。
因為++
在變量之后,所以在評估表達式之前它們不會遞增。 這就是為什么它是后增量運算符; 預增量是前綴( ++p
)。 *++p
將寫入第二個點, *p++
寫入第一個。
p++
是指針p
后遞增。 因此,在p
遞增之前,由deference運算符*
操作p
的當前值。
如果while
循環編寫如下,那么你的推理是正確的:
while (*++p=*++q);
在這種情況下,增量將在解除引用之前發生。
不,增量發生在賦值之后。
如果它是*(++p)
,則指針p
將遞增並在指定之后遞增。
表達式x++
和++x
同時具有結果 (值)和副作用 。
該表達式的結果 x++
是的當前值x
。 副作用是x
的內容增加1。
表達式++x
的結果是x
加1的當前值。 副作用與上面相同。
請注意,在評估表達式后不必立即應用副作用; 它只需要在下一個序列點之前應用。 例如,給定代碼
x = 1;
y = 2;
z = ++x + y++;
不能保證在計算表達式y++
之前,甚至在將++x + y++
的結果賦給z
之前修改x
的內容( =
nor +
運算符都不會引入序列點)。 表達式 ++x
計算結果為2,但是在分配z
之前,變量x
可能不包含值2。
重要的是要記住,像x++ + x++
這樣的表達式的行為是由語言標准明確定義的; 沒有(好的)方法來預測表達式的結果是什么,或者在評估之后x
將包含什么值。
Postfix運算符的優先級高於一元運算符,因此像*p++
這樣的表達式被解析為*(p++)
(即,您將*
運算符應用於表達式p++
的結果)。 同樣,表達式的結果p++
是的當前值p
,因此while (*p++=*q++);
不會跳過第一個元素。
請注意,自動遞增/遞減運算符的操作數必須是左值 (實質上是一個引用內存位置的表達式,以便可以讀取或修改內存)。 表達式x++
或++x
的結果不是左值,因此您不能編寫類似++x++
或(x++)++
或++(++x)
。 你可以編寫類似++(*p++)
( p++
不是左值,但*p++
是),盡管這可能會讓你被閱讀代碼的人打耳光。
表達式(* q ++)的右側將在* p ++之前進行計算,並且兩者僅在賦值發生后遞增。
從右到左閱讀語句,並記住在行中的其他所有內容解析后發生后增量(q ++而不是++ q)。
*q --> dereference q
= --> assign the value
*p --> to p
增加兩者。
這樣做直到qp取q的元素= 0,這是當它到達空終止符時。
這是strcpy函數的剝離實現。 從這段代碼中,我們看到指針p和q是增加的,而不是取消引用,q被賦值給p,直到達到\\ 0 char。
它反過來發生了。 *p
的值設置為*q
,然后兩個指針都遞增。
當你有int foo = bar++
,增量發生在foo設置之后。 為了讓它首先發生你會做int foo = ++bar
q++
的值是q
++q
的值是q+1
while
循環的條件是執行后增量。 等價的:
while (true) {
char* old_p = p;
const char* old_q = q;
++p; // or p++;
++q; // or q++;
*old_p = *old_q;
if (*old_p == '\0')
break;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.