Неявное преобразование функции для двойного аргумента в параметр int

#include <stdio.h>
int main() { 
 foo(22.3);

return 0;
}

void foo(int x) {
 printf("%d", x);
}

Печатает 1. Почему вместо этого не печатается 22? Я считаю, что когда я вызываю foo без объявления явного прототипа, c генерирует неявный прототип, который преобразует short и char в int, а float в double в аргументах функции. Таким образом, 22.3 не затрагивается при вызове foo(22.3), а затем в вызываемой функции параметру int x присваивается значение 22.3: int x = 22.3, что приводит к числовому преобразованию, при котором дробная часть отбрасывается, и в x остается только 22. Так почему же он не печатает 22 вместо 1?

Я думаю, что ошибся в том, что происходит, когда вызывающий вызывает вызываемый с несовпадающими типами параметров?

Отвечает ли это на ваш вопрос? Передача float функции с аргументом int (заранее не объявленным)

OldProgrammer 12.12.2020 00:42

Сделайте себе одолжение: включите предупреждения в своем компиляторе (какой бы широкой категории он ни обладал, например, «все» или «большинство», поэтому -Wmost или -Wall в командной строке для Clang или GCC), настройте его на обработку предупреждений как ошибок (-Werror ) и настройте его на использование последней версии стандарта C, который он поддерживает (для GCC или Clang используйте -std=c17, -std=c11 или -std=c99). Это отключит использование функций без прототипов и выдаст вам ошибки из-за несоответствия аргументов. Сначала вы можете получить больше ошибок, но в конечном итоге вы будете страдать меньше от горя.

Eric Postpischil 12.12.2020 00:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
156
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы вызываете функцию с параметрами, несовместимыми с аргументами. Поскольку у функции нет прототипа, преобразование double в int не происходит. Это приводит к неопределенному поведению.

Если бы вы передали int или меньший целочисленный тип, который был бы повышен до int, то функция работала бы.

Итак, что я получаю из этого, так это то, что когда вы вызываете функцию с аргументами, которые не могут быть неявно преобразованы, чтобы соответствовать параметрам функции, и которые не получают дальнейшего преобразования сгенерированным неявным прототипом ( двойное не будет продвигаться удвоить, потому что он уже удвоился), это приводит к неопределенному поведению? Если бы я вызвал foo('a'), по правилам неявных преобразований прототипов, аргумент 'a' был бы повышен до int, совместимого с параметрами функции, так что в итоге все заработало бы, я могу предположить.

User626468 12.12.2020 00:50

Вы забыли про прототип функции:

#include <stdio.h>

void foo(int); // <--- here!

int main() { 
 foo(22.3);

 return 0;
}

void foo(int x) {
 printf("%d", x);
}

Без этого компилятор, вероятно, берет байты с начала вашего значения с плавающей запятой 22.3 и обрабатывает их как целочисленное значение.

Другие вопросы по теме