今天友人和我討論了一段代碼,是HDU的OJ上一道題目的解,代碼如下
#include<stdio.h> { int a,b; while(~scanf("%d%d",&a,&b)) { printf("%d\n",a+b); } return 0; }
起初,我以為代碼中while語句里的按位取反運算符寫錯了,應該是邏輯非運算符。
這時我在Quora上找到了類似的問題,我對其中一篇答案做了修改和翻譯:
查閱scanf函數的man手冊,關於返回值的說明如下
函數返回按照格式成功匹配並讀入的輸入項數量,並且可能會返回一個小於輸入項總數的數字,而在匹配失敗的情況下,甚至可能返回0。
如果在第一次成功讀入或者發生匹配錯誤之前收到輸入結束信號,將會返回EOF。在遇到讀入錯誤的時候,也會返回EOF。
在上面的代碼里,scanf的返回值可能是0,1,2或者EOF。
對0,1,2進行按位取反得到的都是非零值,此時while循環會繼續執行。
在大多數環境里,EOF被定義為值為-1的常量,進行按位取反后得到的值為0.此時while循環將會結束。
綜上所述,這個while語句可以不斷從輸入流讀入數據,直到輸入流結束,循環也就結束。
值得一提的是,這種用法僅僅在EOF被定義為-1的環境下有效,而且可讀性很差。所以應該盡量避免使用它。
在Linux和OS X里,你可以通過Ctrl+D來發送一個輸入結束信號,在Windows里你需要使用Ctrl+Z。
參考資料: