7 типичных ошибок программирования

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

1) Использование необъявленных переменных

int main()
{
  cin >>  y;
  cout << y;
}

Допустим, вы написали этот код, компилируете программу и тут компилятор сообщает об ошибках. и тут у вас возникает вопрос: «Почему я получаю сообщение об ошибке?». Ответ предельно прост: «Ваш компилятор не знает, что означает y. И перед тем как использовать y, вы должны объявить его как переменную.» Ниже показан код, в котором исправлена данная ошибка.

int main()
{
  int y;
  cin >>  y;
  cout << y;
}

2) Использование неинициализированных переменных

int ct;
while(ct < 100)
{
  cout << ct;
}

Что можно ожидать от этого кода? Да все, что угодно. Мы объявили переменную ct, но не инициализировали начальным значением, значит там содержится какое-то значение — мусор. Оно может быть огромным или очень маленьким. Поэтому могут быть два случая:

  1. если значение ct меньше 100, то программа попадет в цикл;
  2. чаще всего ct огромное число, поэтому скорее всего программа не попадет в цикл.

И самое главное, вы не будете понимать почему это происходит. В C++ переменные неявно не инициализируются нулем, при объявлении. В приведенном выше фрагменте кода, количество может быть любое значение в диапазоне от типа данных int. Это может, например, быть 7631, в  таком случае, условие цикла никогда не будет истинным. Возможно, программа будет печатать цифры от -120 до 99, и это тоже признак ошибки. Поэтому, никогда не забывайте о начальной инициализации переменных.

3. Инициализация переменной мусорным значением

int num1, num2;
int sum = num1 + num2;
cout << "Введите два числа для суммирования: ";
cin >> num1;
cin >> num2;
cout << "Сумма = " << sum;

Когда запустите программу, вас может удивить результат, например, такой:

CppStudio.com
Введите два числа для суммирования: 5 5
Сумма = 32767

Хотите узнать почему сумма равна 32767 ?

Часто начинающие программисты считают, что переменные и выражения работ — это как уравнения — если присвоить переменной результат операции с несколькими другими переменными  (num1, num2, в данном примере), которые изменятся позже, предполагают, что  значение переменной тоже изменится. C++ не работает таким образом! В примере программы, num1 и num2 не инициализируются перед выполнением операции сложения, поэтому сумма будет равна случайному значению.

Чтобы исправить эту ошибку, переместите операцию суммирования после ввода num1 и num2.

int num1, num2;
cout << "Введите два числа для суммирования: ";
cin >> num1;
cin >> num2;
int sum = num1 + num2;
cout << "Сумма = " << sum;

А вот и результат, если не верите, проверьте сами.

CppStudio.com
Введите два числа для суммирования: 5 5
Сумма = 10

4. Использование одного знака равенства для проверки равенства

char ch = 'Y';
while(ch = 'Y')
{
  //какой-то код
  cout << "Продолжить? (Y/N)";
  cin >> ch;
}

«Почему никогда не заканчивается цикл?»

Если вы используете один знак равенства для проверки равенства, ваша программа будет вместо  сравнения, присваивать значение в правой части выражения, переменной в левой части. В этом случае, значение 'Y', которое рассматривается как истинное всегда будет присваиваться переменной ch. Таким образом, цикл никогда не закончится. Используйте == для проверки равенства, кроме того, чтобы избежать случайного присвоения, поменяйте местами переменную ch и значение 'Y'. Так, вы получите ошибку компиляции, если случайно использовали один знак равенства, поскольку вы не можете присвоить значение тому, что не является переменной.

char ch = 'Y';
while('Y' == ch)
{
  //какой-то код
  cout << "Продолжить? (Y/N)";
  cin >> ch;
}

4. Необъявленная функция

int main()
{
  print();
}
void print()
{
  //что-то печатаем
}

«Почему я получаю ошибку о том, что программе неизвестна функция print

Компилятор не знает, что такое print(), так как определение функции print выполнено после main и не объявлен прототип. Всегда помните, нужно указать либо прототип функции, либо все определение функции выше строки, в которой будет вызов этой функции.

void print();
int main()
{
  print();
}
void print()
{
  //что-то печатаем
}

 6) Лишние точка с запятой

int ix;
for(ix = 0; ix < 100; ix++);
  cout << ix;

«Почему вывод равен 3476?»

Все дело в том, что вы поставили дополнительные точку с запятой. Помните, что точка с запятой не ставится, после определения, циклов, или функций. Если вы случайно поставите точку с запятой в любом из этих мест, ваша программа будет работать некорректно.

int ix;
for(ix = 0; ix < 100; ix++)
  cout << ix;

7) Нарушение границ массива

int array[10];
//код...
for(int ix = 1; ix <= 10; ix++)
  cout << array[ix];

«Почему вывод программы содержит неправильные значения?»

Элементы массива индексируются, начиная с 0, а значит, общая длинна на 1 меньше. Например, если у вас есть десять элементов массива, первый элемент находится в положении нуля, а последний элемент в позиции 9.

int array[10];
//код...
for(int ix = 0; ix < 10; ix++)
  cout << array[ix];

В этом коде границы массива уже не нарушаются.

Автор: Marienko L.
Дата: 21.11.2012
Поделиться:

Комментарии

  1. S-trace

    «Почему вывод равен 3476?»

    И правда, почему?

    У меня на машине (G++ 7.2.0) код выводит 100, и это совершенно правильный ответ, ведь мы значение ix было инициализированно нулём в начале цикла, потом цикл прокрутился 100 раз, каждый раз увеличивая значение ix на единицу (и не важно что при этом он ничего не делал кроме этого — подобные циклы имеют право на жизнь к примеру на микроконтроллерах, когда нужно внести определённую задержку работы программы (хоть это и не совсем хорошее решение, но для мелких задержек годится), и затем финальное значение ix (100) один раз выводится в стандартный вывод.

    А вот почему у вас этот код выводит 3476 — мне очень интересно. Похоже, у вас на машине неисправна оперативная память, проверьте её.

  2. S-trace

    Возможно, программа будет печатать цифры от -120 до 99, и это тоже признак ошибки.

    Это будет ОЧЕНЬ странная ошибка. В коде примера нет нигде изменения значения переменной, и поэтому цикл должен бесконечно выводить одну и ту же цифру.

    А вот если значение переменной «поплывёт» без её модификации — это будет действительно странным поведением.

  3. Got .

    Разве при иницилизациии переменные не равны 0?

     

  4. Роман Павлов

    Как правильнее записать:

    int main()

    или

    void main()

    или это зависит от того, что я хочу получить в итоге?

  5. admin

    admin

    Пожалуйста. Для этого статью и писал, чтобы у новичков было как можно меньше ошибок.

    • gob842

      gob842

      Обращаю Ваше внимание на то, что тут по ошибке 2-ва, 4-х пункта стоит, вообщем один лишний перед 6-м)) А за памятку, огромное спасибо, очень полезная информация.

  6. kirkiness

    kirkiness

    спасибо, а то постоянно ошибаюсь.

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.