2010-02-09 42 views
7

字符串我感到困惑的驗證碼(http://www.joelonsoftware.com/articles/CollegeAdvice.html複製用C

while (*s++ = *t++); 

什麼是執行的順序? * s = * t首先完成,然後它們每個都增加了嗎?或以其他方式?

謝謝。

編輯:如果它是什麼:

while(*(s++) = *(t++)); 

while(++*s = ++*t); 
+1

我不知道Joel是否仍然會支持那篇5年前的文章...照顧評論Joel? – Hogan 2010-02-09 04:10:31

+0

我建議大家開始把分號放在下一行,而不是僅僅在循環條件之後,while循環中用body的空語句。我真的認爲它更清晰,更易於閱讀。 – 2010-02-09 05:02:43

回答

14
while (*s++ = *t++); 

precedence table你可以清楚地看到++是具有比*更高的優先級。但++在此處用作後增量運算符,因此增量發生在賦值表達式之後。所以*s = *t先發生,然後s和t遞增。

編輯:

while(*(s++) = *(t++)); 

同上。你使用括號更加明確。但是請記住++仍然是後增量。

while(++*s = ++*t); 

s旁邊只有一個操作符。因此,首先應用*,然後應用++,結果爲lvalue required錯誤。

while(*++s = *++t); 

再次只是運算符旁邊的s,t。所以增量先發生,然後複製。所以我們實際上將第一個字符從t拷貝到s。

+0

不是「優先」,而不是「precedance」?這可能是一些英國/美國的東西,所以我不想編輯... – 2010-02-09 04:58:50

2

增量是後遞增。發佈不僅僅是因爲它是在變量遞增之後發生的,而且還因爲它在評估表達式之後發生。因此,執行的順序是

*s = *t 

則s ++和T +

1

編輯::

@chrisgoyal

序執行的是一個含糊的字眼。這裏有兩個不同的東西。語法順序和表達式的語義。

在句法上,首先應用operator ++。如果第一次施加* S,那麼下面就等於什麼@Hogan說:

(*s)++ = (*t)++ 

這是非常從喬爾的樣本不同。

operator ++的語義是它在表達式之後執行。

希望澄清我的肉。


其實,s++t++首先應用。不要忘記在表達完成之後執行修復後操作符。基本上運營商++適用於兩個,然後*s = *t被執行。

+0

錯誤...之後的手段後權利。你描述了之前發生的增量。 – Hogan 2010-02-09 04:07:47

+0

@Hogan修復後操作符具有**更高的優先級**,所以它首先應用。表達完成後,應用後綴修飾符*的*語義*。 – AraK 2010-02-09 04:10:02

+0

你的答案說兩種不同的東西... – chrisgoyal 2010-02-09 04:13:02

4

你說得對。 * s = * t先完成,然後遞增。

0

在Post增量操作變量首先被使用,然後被修改後。

0

所以有增量

++s // increment before using value 
s++ // increment after using value 

兩種形式,以及這些的結果可以提領:

*++s // or... 
*s++ 

這種合作的很好的第一個機器一個用於C運行在PDP-11上,它有一個寄存器間接尋址模式,可以使寄存器遞增。下面的操作數在硬件是可利用的:

*--s // or 
*s++ 

你可以做任何

*x++ = *y++; // or 
*--x = *--y; // or some combination 

如果你這樣做了,整條生產線中的一條指令發生了。由於//註釋是由C99引入的,但是,您實際上無法脫離我的評論語法。

+0

您可以使用99%的C編譯器使用'''註釋。這不是一個好主意,但我懷疑它會殺死任何人。 – 2010-02-09 04:55:01

+0

像往常一樣,你是對的,我完全同意,但我猜測他們不會在PDP-11 C編譯器上工作...... – DigitalRoss 2010-02-09 05:08:06

0

代碼:(while *s++ = *t++);大致等同於:

while (*s = *t) { 
    ++s; 
    ++t; 
} 

第二個是完全一樣的 - 額外的括號不改變(在這種情況下)任何東西。對於人員做任何事情,他們必須是這樣的:while ((*s)++ = (*t)++);。這與你的第三個例子大致相同(在下面的段落中有介紹)。

最後一個例子:while(++*s = ++*t);是完全不同的。由於取消引用(*)更接近操作數,因此這會取消操作數的引用並增加取消引用的結果,這意味着它會增加指針指向AT的內容,而不是增加指針本身。結果,這會複製第一個字符,然後遞增該字符,然後檢查該字符是否爲非零並且繼續相同直到它爲零。結果將是源和目標都變爲空字符串(因爲兩者的第一個字符現在將爲零,用於終止字符串)。