смешные ошибки в C/C++

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

смешные ошибки в C/C++

Непрочитанное сообщение Olej » 02 июл 2016, 21:19

Иногда возникают очень смешные ошибки в коде C/C++ ... обычно из-за механической ошибки (дребезг клавиатуры или проглоченный символ :shock: ).
Часто такие ошибки особо трудно диагностировать!
Некоторые я решил здесь коллекционировать (многие возникли из реальных задач и кодов).

Смешными будем называть ошибку, когда синтаксическая конструкция из-за описки или небрежности не становится синтаксической ошибкой (т.е. не диагностируется), но приобретает совершенно другой смысл.

Каждая задачка будет в 2 сообщения ... чтоб была возможность самостоятельно подумать:
- 1-е сообщение - формулировка задачи;
- 2-е сообщение - результат и объяснение;

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: смешные ошибки в C/C++

Непрочитанное сообщение Olej » 02 июл 2016, 21:22

Вот такая ошибка, которую только недавно мне пришлось разгребать в чужом коде...
Что выведет вот такая программа?

Код: Выделить всё

#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;
}

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: смешные ошибки в C/C++

Непрочитанное сообщение Olej » 02 июл 2016, 21:41

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, и цикл не выполняется ни одного раза.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: смешные ошибки в C/C++

Непрочитанное сообщение Olej » 02 июл 2016, 21:47

На предыдущем примере можно построит гораздо более замысловатый пример ... например в цикле сверху вниз:

Код: Выделить всё

#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. Попав в такую засаду, из неё можно долго выгребаться. :lol:

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: смешные ошибки в C/C++

Непрочитанное сообщение Olej » 02 июл 2016, 21:48

Olej писал(а): Очевидно, предполагается получить: 9, 8, 7, 6, 5, 4 ... элементы с [8] по [3]
Что получится на самом деле?

Код: Выделить всё

[olej@dell error]
$ ./logc2
9, 8, 7, 6, 5, 
i >> 2 - индекс цикла i численно сдвигается на 2 позиции вправо (делится на 4), при 8 ... 4 - это ещё не 0, но при i == 3 - это 0, который трактуется как логический false, и признак заканчивать цикл.
Вложения
error.tgz
(568 байт) 181 скачивание

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: смешные ошибки в C/C++

Непрочитанное сообщение Olej » 03 июл 2016, 19:27

Совсем уж традиционная ошибка, о которой везде предупреждают 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 - найден нулевой элемент в массиве.
Что будет на самом деле?

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: смешные ошибки в C/C++

Непрочитанное сообщение Olej » 03 июл 2016, 19:29

Olej писал(а):Предполагается, очевидно, что ожидается значение i == 2 - найден нулевой элемент в массиве.
Что будет на самом деле?

Код: Выделить всё

[olej@dell error]$ make eq
gcc -Wall -O0 -o eq  eq.c

[olej@dell error]$ ./eq
4

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 8 гостей