2014-03-06 26 views
15

我在「A巡迴賽的C++」,第12頁看到了以下功能:「C++遊覽」或非兼容編譯器中的Buggy代碼?

int count_x(char const* p, char x) 
{ 
    int count = 0; 
    while (p) 
    { 
     if (*p == x) ++count; 
     ++p; 
    } 
    return count; 
} 

while (p)不好聽我的權利。我認爲它應該是while (*p)。然而,不想太過放縱,我用下面的代碼測試了這個函數。

int main(int argc, char** argv) 
{ 
    char* p = argv[1]; 
    char x = argv[2][0]; 
    int count = count_x(p, x); 

    std::cout 
     << "Number of occurences of " 
     << x << " in " << p << ": " << count << std::endl; 
    return 0; 
} 

當我運行程序時,它退出了Segmentation fault (core dumped)。我很高興看到這個錯誤,因爲代碼對我來說並不合適。但是,現在我很好奇。本書中提出的代碼是否錯誤或編譯器不符合C++ 11標準?編譯器是g ++(GCC)4.7.3。

count_x代碼的奇怪之處在於,作者Bjarne Stroustrup從以下實現開始,然後完成我首先寫的代碼。

int count_x(char const* p, char x) 
{ 
    if(p==nullptr) return 0; 
    int count = 0; 
    for (; p!=nullptr; ++p) 
    { 
     if (*p == x) 
     ++count; 
    } 
    return count; 
} 

這讓我三思而後結論這是越野車代碼。兩個版本似乎都是越野車。

+2

這段代碼絕對看起來很奇怪。是否有任何理由懷疑編譯器不符合C++ 11標準? (另外,它們展示的代碼絕對不是很好的C++代碼 - 它應該使用'std :: string'和'std :: count'算法〜) – templatetypedef

+0

@templatetypedef,我將很難指向一個手指在C++的父親的一本書中的代碼中,並將其稱爲越野車,但沒有確保幾次,我沒有失去我的想法:) :) –

+0

@templatetypedef,該函數出現在本書的第一章,基礎知識。有意義的是,他不會跳入'std :: string'和'std :: count'。 –

回答

5

此列在Errata for 2nd printing of A Tour of C++

第1章:

頁11-12:對於count_if()的代碼是錯誤的(沒有做什麼它聲稱 到),但關於該語言的觀點是正確的。

在第一次印刷的代碼,原先爲:

int count_x(char* p, char x) 
    // count the number of occurences of x in p[] 
    // p is assumed to point to a zero-terminated array of char (or to nothing) 
{ 
    if (p==nullptr) return 0; 
    int count = 0; 
    while(*p) { 
     if(*p==x) 
      ++count; 
     ++p; 
    } 
    return count; 
} 

有在The C++ Programming Language (4th Edition)一個類似的例子在這是基於的C++一遊,但它並沒有這個bug。

+0

好笑。該代碼表示​​'count_x',文本和勘誤表示'count_if()'。你認爲他們會在下一個版本中解決這個問題嗎? –

3

gcc在4.7.3具有良好的兼容性,但是您必須使用-std = C++ 11進行編譯。有gnu webpage的圖表。但是,這不是一個標準的事情,指針永遠不會是NULL,至少在它溢出之前是這樣的,所以除非你已經將所有的內存分配在char *之上,否則就會發生segfault。這只是一個錯誤。

+0

你如何告訴C++的父親他的書中的代碼是越野車? –

+0

@RSahu提交錯誤報告。 – user26347