Не используйте устаревшие не прототипированные предварительные объявления устаревшего стиля:
float val(); /* This syntax should never be used */
float pow();
Когда вы объявляете функцию, объявляете ее полный прототип:
float val(float x, int n, float t);
float pow(float base, int exp);
Также рассмотрите возможность использованияdouble
, а не float
.
Как можно догадаться из первоначальных результатов, ваша программа продемонстрировала неопределенное поведение;в этом случае вы вызываете pow
с типом аргумента, несовместимым с его типом параметра.В устаревшем стиле объявления
float pow();
не указывается, какие типы параметров pow
или сколько их ожидают.По сути, он говорит компилятору: «Поверьте мне, я предоставлю аргументы правильного типа».
Но тогда выполнить это обещание невозможно, поскольку pow
ожидает float
в качестве егопервый аргумент, и компилятор выполняет продвижение по умолчанию для всех аргументов, переданных функциям, объявленным без прототипа.Одно из продвижений по умолчанию превращает float
в double
, поэтому невозможно предоставить аргумент float
.Если бы вы использовали double
с вместо float
с, вы бы не столкнулись с этой конкретной проблемой и, вероятно, продолжали бы использовать синтаксис, который не поощрялся в течение почти 30 лет.
Кстатиэта проблема не возникала в val
, потому что определение val
встречается до его использования.Разумеется, определение определяет типы параметров, которые заполняют информацию, опущенную в предварительном объявлении без прототипов.
Но нижняя строка - это простой совет, приведенный выше: не используйте объявления функций старого стиля,Каждая функция должна быть объявлена с полным прототипом, указывающим типы всех ее параметров.(Если вам нужно объявить функцию без параметров, используйте специальный список параметров (void)
вместо пустого списка параметров.)