2017-04-03 45 views
0

最近我看到了使用這樣的代碼的項目:C - Is * x ++ = * y ++定義良好?

while ((*dest++ = *src++) != '\0') 
    ... 

,我想知道的*dest++ = *src++行爲是否是明確界定?它會一直表現爲:

while((*dest = *src) != '\0') { 
    ++dest; 
    ++src; 

    ... 
} 

或者該代碼屬於a[i] = i++;的類別?

+0

標題中的表達是非法的。只要'dest'和'src'不是擴展到同一個變量的宏,就可以很好地定義正文中的一個。順便說一句..我沒有看到任何錯誤的'a [i] = i ++'... –

+1

@EugeneSh。你應該看看[這](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points?noredirect=1&lq=1) – user1542389

+0

是的。一件不明顯的事情。更好的解釋[這裏](http://stackoverflow.com/questions/11132236/why-does-increment-operation-like-ai-i-result-in-undefined-behavior?noredirect=1&lq=1)國際海事組織。 –

回答

2

該代碼與K & R的代碼幾乎相同,並且其行爲已被很好地定義。

沒有不確定的行爲的原因是,在該行的四次訪問是在三個不同的存儲單元完成:

  • dest++增量dest指針,
  • src++增量src指針,
  • *dest =分配dest
  • *src讀取指向的內容。

如果代碼試圖在沒有序列點的情況下多次訪問同一位置,例如, x += x++。這是未定義的行爲,因爲+++=正在修改相同的位置x

0

x++ = y++是非法的,因爲作業的左側必須是存儲引用,但x ++是一個值,而不是左值。

* dest ++ = * srC++是有效的,因爲在這種情況下,dest是一個指針(即++後遞增),但是賦值是指向dest的指針,因此是可分配的有效地址一個值。

如果你看的strcpy的實現,它使用這個結構:

char *strcpy(char *d, const char *s) 
{ 
    char *saved = d; 
    while (*s) 
    { 
     *d++ = *s++; 
    } 
    *d = 0; 
    return saved; 
} 
0

是。 Brian W. Kernighan和Dennis M. Ritchie的K & R給出了對此的解釋。

第二版,第104頁:

對於對比度,在這裏是一個版本的strcpy的具有指針:

/* strcpy: copy t to s; pointer version 1 */ 
void strcpy(char *s, char *t) 
{ 
    while((*s = *t) != '\0') 
    { 
     s ++; 
     t ++; 
    } 
} 

由於參數通過值通過,strcpy的可以使用參數s 和它以任何方式令人滿意。在這裏,他們很方便地初始化指針,這些指針一次沿着數組一個字符行進, ,直到終止t的'\ 0'被複制到s。

實際上,strcpy不會像我們上面顯示的那樣寫入。 有經驗的C語言程序員寧願

/* strcpy: copy t to s; pointer version 2 */ 
void strcpy(char *s, char *t) 
{ 
    while((*s++ = *t++) != '\0') 
     ; 
} 

這使s和t的增加進入循環的測試部分。 * t ++的值是t之前指向的字符是 遞增;在這個 字符被提取之後,後綴++不會改變t。以同樣的方式,在s遞增之前,角色被存儲在舊位置 。該字符也是 也是與'\ 0'比較來控制循環的值。淨效應是字符從t複製到s,最多可以包括終止'\ 0'和 。

作爲最後的縮寫,觀察與'\ 0'的比較是多餘的,因爲問題僅僅是表達式是否爲 零。因此函數很可能被寫爲

/* strcpy: cope t to s; pointer version 3 */ 
void strcpy(char *s, char *t) 
{ 
    while(*s++, *t++); 
} 
+1

是'while'在K&R報價的假設年底有'='在它的? – supercat

0

的構建體((* DST ++ = * SRC++)!= 0)或 '\ 0',這是相同的0 既是良好定義的並且是一個常見的習慣用法,特別是在早期的C代碼中。它將指針類型的一個值從src複製到dest,並定位src和dst指針以將下一個相鄰的src值複製到下一個相鄰的dst位置。

這之類的東西strcpy的實現中使用。

0

是的,它似乎是明確的。我剛纔拿C,但是我會說指針* dest和* src指向dest和src的內存地址。如果您嘗試使用++運算符來增加dest和src變量本身的值,那很好。我希望這是有道理的。

相關問題