После открытия пишет "прекращена работа программы"
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Нужно ввести количество оценок (по 12-бальной шкале) за какой-то период, после чего найти среднее значение. Затем нужно разбить результат на 4 группы. Например, если среднее значение 4,5, то нужно вывести на экран «2». Компилирует нормально, но после запуска пишет «прекращена работа программы». В чем проблема? Я тут новичок.
Urgantvirus3871, врёшь! Не компилируется оно у тебя.
Cranium, вот скрин
Urgantvirus3871, извини, на счёт врёшь — погорячился. Однако, программа содержит одну ошибку не совместимую с жизнью и минимум 4 предупреждения. Я очень удивлён, что хвалёный GCC с дефолтными настройками компиляции даже предупреждений не даёт ((
Ошибка:
По стандарту языка при объявлении массива в квадратных скобках должно быть указано константное выражение интегрального типа большее 0. Т.е. во время компиляции размер массива должен быть известен. На основе известного размера массива и типа элементов массива компилятор генерирует команды для выделения места под массив. В данном случае, вопреки стандарту, GCC выделяет какой-то объём памяти под массив с неизвестным ему размером. Если при работе с этим массивом ты выйдешь за его границу, которую ты не знаешь, то почти 100%-но получишь крах программы. Что, видимо, ты и наблюдаешь.
Лечение. Использовать для массива динамическое выделение/освобождение памяти. Или использовать один из контейнеров STL, например
vector
.Предупреждения:
Эта конструкция не будет работать ожидаемым тобой образом. Обычно компиляторы на такие вещи выдают предупреждения. В
if
написанное тобой условие эквивалентно следующему:Т.е. сначала выполняется сравнение
avg
с первым числом. Результат булевского типа неявно приводится к типуint
(тип второго операнда второй операции сравнения). Результатом приведения к целому будет 0 дляfalse
и 1 дляtrue
. Затем выполняется второе сравнение с очевидным результатом.Лечение.
Ещё настоятельно рекомендую в настройках проекта в IDE выставить разрешение вывода всех предупреждений. От граблей оно тебя не избавит, но хотя бы к ним будет флажок привязан ))
Cranium, благодарю, ошибку понял, исправил, все работает))
Отщеплен новый топик «Помогите найти ошибку в программе».
Cranium, это не баг GCC, а фича. Плюс ко всему, стандарт C99 допускает автоматическое выделение памяти под массив переменной длины.
https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
Угу... только с помощью этой фичи нога отстреливается по самые гланды. Что ТС и испытал.
Кстати, про отсутствие бага я бы поспорил. Стандарт C99 мне искать лениво, но в доке по GCC во всех примерах в рантайме размер массива таки вычисляется. Здесь же переменная
n
объявляется без инициализации. Если уж есть такая фича, то компилятор должен был хотя бы предупреждение выдать, что переменная неинициализирована. А так, какого размера массив выделяется?Вообще-то говоря, все фичи в компиляторах — от Лукавого. Есть Стандарт. Компилятор обязан ему следовать. Если я хочу использовать какую-то фичу конкретного компилятора, то я должен каким-то образом явно это указать (ключом, прагмой и т.п.). Именно так, а не наоборот, как это реализовано в GCC: есть фичи, но что бы по стандарту, необходимо указать соотв. ключ. Кроме того, использование фичей компилятора делает код непереносимым.
В стандартах есть такие понятия, как неопределенное и допустимое поведение.
То, как такие вещи реализуются — дело того, кто это реализует.
В стандарте C++11 (ISO/IEC 14882:2011 п. 8.3.4) про размер в объявлении массива совершенно чётко сказано
без всяких оговорок на implementation dependent.
То, что в C99 можно объявлять массивы с неконстантным размером, здесь неприменимо. Это другой язык.
При компиляции с флагом
-pedantic
компилятор выдает предупреждение.В C++ 14, кстати массивы переменной длины будут поддерживаться.
Я думаю, что по умолчанию эту опцию оставили включенной как расширение как раз из-за сохранения совместимости со старым кодом.
Но я согласен с тобой в целом, что реализация нестандартизированных инструменто-зависимых фич, а тем более их использовании в потенциально кроссплатформенных программах — не лучшая идея.