Страница 1 из 1
смешные ошибки в C/C++
Добавлено: 02 июл 2016, 21:19
Olej
Иногда возникают очень смешные ошибки в коде C/C++ ... обычно из-за механической ошибки (дребезг клавиатуры или проглоченный символ
).
Часто такие ошибки
особо трудно диагностировать!
Некоторые я решил здесь коллекционировать (многие возникли из реальных задач и кодов).
Смешными будем называть ошибку, когда синтаксическая конструкция из-за описки или небрежности
не становится синтаксической ошибкой (т.е. не диагностируется), но
приобретает совершенно другой смысл.
Каждая задачка будет в 2 сообщения ... чтоб была возможность самостоятельно подумать:
- 1-е сообщение - формулировка задачи;
- 2-е сообщение - результат и объяснение;
Re: смешные ошибки в C/C++
Добавлено: 02 июл 2016, 21:22
Olej
Вот такая ошибка, которую только недавно мне пришлось разгребать в чужом коде...
Что выведет вот такая программа?
Код: Выделить всё
#include <stdio.h>
int main() {
int i, arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
n = sizeof( arr ) / sizeof( arr[ 0 ] );
for( i = 0; i << n; i++ )
printf( "%d, ", arr[ i ] );
printf( "\n" );
return 0;
}
Re: смешные ошибки в C/C++
Добавлено: 02 июл 2016, 21:41
Olej
Olej писал(а):
Что выведет вот такая программа?
Очевидно, что предполагался вывод: 1, 2, 3, 4, 5, 6, 7, 8, 9
Но получим:
Код: Выделить всё
[olej@dell error]$ ./logc1
[olej@dell error]$
Выражение i << n не есть ошибка, а сдвиг i на n позиций влево (т.е. i * 2 ^ n), но поскольку начальное значение i это 0, то и
числовой результат 0, но он толкуется как
логическое значение false, и цикл не выполняется
ни одного раза.
Re: смешные ошибки в C/C++
Добавлено: 02 июл 2016, 21:47
Olej
На предыдущем примере можно построит гораздо более замысловатый пример ... например в цикле сверху вниз:
Код: Выделить всё
#include <stdio.h>
int main() {
int i, arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
n = sizeof( arr ) / sizeof( arr[ 0 ] );
for( i = n - 1; i >> 2; i-- )
printf( "%d, ", arr[ i ] );
printf( "\n" );
return 0;
}
Очевидно, предполагается получить: 9, 8, 7, 6, 5, 4 ... элементы с [8] по [3]
Что получится на самом деле?
P.S. Попав в такую засаду, из неё можно долго выгребаться.
Re: смешные ошибки в C/C++
Добавлено: 02 июл 2016, 21:48
Olej
Olej писал(а):
Очевидно, предполагается получить: 9, 8, 7, 6, 5, 4 ... элементы с [8] по [3]
Что получится на самом деле?
i >> 2 - индекс цикла i
численно сдвигается на 2 позиции вправо (делится на 4), при 8 ... 4 - это ещё не 0, но при i == 3 - это 0, который трактуется как
логический false, и признак заканчивать цикл.
Re: смешные ошибки в C/C++
Добавлено: 03 июл 2016, 19:27
Olej
Совсем уж традиционная ошибка, о которой везде предупреждают 100 раз ... и всё-равно на неё попадаются: когда в условии вместо == прописывают =
Код: Выделить всё
#include <stdio.h>
int main() {
int i = 0, arr[] = { 1, -1, 0, 2, -2, 0, 3, -3, 0 };
while( 1 ) {
if( ( arr[ i ] < -1 ) || ( arr[ i ] = 0 ) ) break;
i++;
}
printf( "%d\n", i );
return 0;
}
Предполагается, очевидно, что ожидается значение i == 2 - найден нулевой элемент в массиве.
Что будет на самом деле?
Re: смешные ошибки в C/C++
Добавлено: 03 июл 2016, 19:29
Olej
Olej писал(а):Предполагается, очевидно, что ожидается значение i == 2 - найден нулевой элемент в массиве.
Что будет на самом деле?
Код: Выделить всё
[olej@dell error]$ make eq
gcc -Wall -O0 -o eq eq.c
[olej@dell error]$ ./eq
4