Багги-код в "A Tour of С++" или несоответствующий компилятор?
Я видел следующую функцию в "A Tour of С++", стр. 12:
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)
. Я был рад видеть эту ошибку, поскольку код не выглядел правильным для меня. Однако сейчас любопытно. Является ли код, предложенный в книге неправильным или не совместим с компилятором С++ 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;
}
Это заставило меня подумать дважды, прежде чем заключить, что это глючный код. Обе версии выглядят ошибками.
Ответы
Ответ 1
Это указано в Исправление для 2-ой печати A Tour of С++:
Глава 1:
стр. 11-12: Код для count_if() неверен (не выполняет то, что он утверждает to), но точки, касающиеся языка, верны.
Код во второй печати теперь читает:
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;
}
Существует аналогичный пример в Язык программирования С++ (4-е издание), на котором был основан A Tour of С++, но он не имеет этого ошибка.
Ответ 2
gcc имеет хорошую совместимость на 4.7.3, но вам нужно скомпилировать с -std = С++ 11. На веб-странице gnu есть диаграммы. Но да, это не стандартная вещь, этот указатель просто никогда не будет NULL, по крайней мере, пока он не переполнится, поэтому, если вы не выделили всю память выше char *, это будет segfault. Это просто ошибка.