Изучение программирования и логики программ может оказаться не простой задачей, спросите любого, кто прошел этот этап, того, кто сделал это. К несчастью, одни и те же проблемы возникают снова и снова, особенно у новичков. В этой статье я постарался собрать одни из наиболее распространенных проблем, с которыми вы непременно столкнетесь, если станете программистом.
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
, но не инициализировали начальным значением, значит там содержится какое-то значение — мусор. Оно может быть огромным или очень маленьким. Поэтому могут быть два случая:
- если значение
ct
меньше 100, то программа попадет в цикл; - чаще всего
ct
огромное число, поэтому скорее всего программа не попадет в цикл.
И самое главное, вы не будете понимать почему это происходит. В C++ переменные неявно не инициализируются нулем, при объявлении. В приведенном выше фрагменте кода, количество может быть любое значение в диапазоне от типа данных int
. Это может, например, быть 7631, в таком случае, условие цикла никогда не будет истинным. Возможно, программа будет печатать цифры от -120 до 99, и это тоже признак ошибки. Поэтому, никогда не забывайте о начальной инициализации переменных.
3. Инициализация переменной мусорным значением
int num1, num2; int sum = num1 + num2; cout << "Введите два числа для суммирования: "; cin >> num1; cin >> num2; cout << "Сумма = " << sum;
Когда запустите программу, вас может удивить результат, например, такой:
Введите два числа для суммирования: 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;
А вот и результат, если не верите, проверьте сами.
Введите два числа для суммирования: 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];
В этом коде границы массива уже не нарушаются.
Комментарии
S-trace
И правда, почему?
У меня на машине (G++ 7.2.0) код выводит 100, и это совершенно правильный ответ, ведь мы значение ix было инициализированно нулём в начале цикла, потом цикл прокрутился 100 раз, каждый раз увеличивая значение ix на единицу (и не важно что при этом он ничего не делал кроме этого — подобные циклы имеют право на жизнь к примеру на микроконтроллерах, когда нужно внести определённую задержку работы программы (хоть это и не совсем хорошее решение, но для мелких задержек годится), и затем финальное значение ix (100) один раз выводится в стандартный вывод.
А вот почему у вас этот код выводит 3476 — мне очень интересно. Похоже, у вас на машине неисправна оперативная память, проверьте её.
S-trace
Это будет ОЧЕНЬ странная ошибка. В коде примера нет нигде изменения значения переменной, и поэтому цикл должен бесконечно выводить одну и ту же цифру.
А вот если значение переменной «поплывёт» без её модификации — это будет действительно странным поведением.
Got .
Разве при иницилизациии переменные не равны 0?
Роман Павлов
Как правильнее записать:
int main()
или
void main()
или это зависит от того, что я хочу получить в итоге?
admin
Пожалуйста. Для этого статью и писал, чтобы у новичков было как можно меньше ошибок.
gob842
Обращаю Ваше внимание на то, что тут по ошибке 2-ва, 4-х пункта стоит, вообщем один лишний перед 6-м)) А за памятку, огромное спасибо, очень полезная информация.
kirkiness
спасибо, а то постоянно ошибаюсь.