2013-02-11 58 views
-6

我試圖從編碼網站解決方案中瞭解代碼,但無法弄清楚很多事情。我能理解的BIT和分域的一部分,但無論如何我不明白我在下面寫下來的:
這段代碼的來源是http://www.codechef.com/viewsolution/1816336
這將是真正有用的,如果有人解釋,而不是使用標準中定義的概念輸入輸出功能,爲什麼我們往往會使用這些:
瞭解C++程序的代碼

char ioSpace[500000 * 17 + 128]; 
unsigned popcnt(unsigned x) 
{ 
    #ifndef ONLINE_JUDGE 
    return __builtin_popcount(x); 
    #else 
    unsigned ret; 
    asm("popcntl %1, %0;":"=r"(ret) :"r"(x)); 
    return ret; 
    #endif 
} 

unsigned readUInt(char*& readPos) 
{ 
    unsigned num = 0; 
    unsigned c; 
    while ((c = *readPos++) >= '0') 
    num = num * 10 + (c - '0'); 
    return num; 
} 

template<unsigned D> 
void writeDigit(char*& writePos, unsigned& advance, unsigned& num) 
{ 
    unsigned digit = num/D; 
    num %= D; 
    if (digit) 
    advance = 1; 
    *writePos = digit + '0'; 
    writePos += advance; 
} 

void writeUInt(char*& writePos, unsigned num) 
{ 
    unsigned advance = 0; 
    writeDigit<100000>(writePos, advance, num); 
    writeDigit<10000>(writePos, advance, num); 
    writeDigit<1000>(writePos, advance, num); 
    writeDigit<100>(writePos, advance, num); 
    writeDigit<10>(writePos, advance, num); 
    advance = 1; // for zero number 
    writeDigit<1>(writePos, advance, num); 
    *writePos++ = '\n'; 
} 

然後在主要輸入功能:

read(STDIN_FILENO, ioSpace, sizeof(ioSpace)); 

燦有人向我解釋整個過程,因爲我一直在試圖將這些樣式融入到我的C++編程中,並且由於缺乏理解而不可避免地失敗了。

+0

我認爲自己是一個相當能幹的程序員(畢竟,我已經做了30多年的編程工作)。我完全不知道這個代碼是要解決什麼問題。這可能是完美的解決方案,但我懷疑它。 – 2013-02-11 14:11:05

回答

1

首先,我沒有看到證據表明這個代碼是一個很好的範例,值得你的研究。完全缺乏任何評論本身使我不信任代碼。如果你真的想要在調試器中逐步瞭解它,你就不會說你在哪裏停留在這個代碼中,它應該變得清晰。爲了讓你開始,一些關於閱讀的觀察。

它似乎很清楚,readUint()和writeUint()方法正在對一個緩衝,想必是ioSpace,雖然你不顯示的實際調用,所以我們不能肯定,但你的

read(STDIN_FILENO, ioSpace, sizeof(ioSpace)); 

顯示iospace從STDIN獲取日期。如果文件大於iospace,那麼會發生什麼情況並不明確。也不是什麼錯誤處理完成。

爲readUint代碼()雲:

while ((c = *readPos++) >= '0') 

哪個抓住下一個字符,並增加readPosition。當我們看到我們應該立即懷疑我們什麼時候停止。在這種情況下,當字符c不

>= '0' 
換句話說

,當我們看到這個字符低於ASCII碼「0」,這樣可以是任何字符,這樣的「&」或「#」,但可能是作者期待換行符'\ n',因爲這似乎是他們用writeUint()終止了數字 - 請參閱我的意思是關於缺少評論?然後

c - '0' 

產生的字符的數字值 '9' - '0' 爲9的ASCII碼少爲0的ASCII碼,57 - 48,這當然是9.

while ((c = *readPos++) >= '0') 
    num = num * 10 + (c - '0'); 

然後,我們通過將10乘以10並添加最近讀取的值來構建小數值。

此代碼容易受到包含字母的文件的影響。看看,如果你有一條線,如

23A4\n 

所以,你需要有一定的道理,如果你正在使用此代碼來信任你的輸入會發生什麼。

寫入只是通過調用writedigit()函數獲取數字中的個別數字。

0

Hmmmn ...我很確定readUInt函數用於將字符串數字轉換爲實際數字,即等同於atoi()函數。我認爲WriteDigit是相反的,但我不確定。