2013-09-27 4 views
2

У меня есть вопрос о предупреждении от компилятора gcc. Предупреждающее сообщение возникает, когда аргумент scanf не является указателем на переменную, которая должна нести пользовательский ввод.gcc scanf warning считает, что float double

#include <stdio.h> 

int main(int argc, const char *argv[]) { 
    float number; 
    scanf("%f", number); /* the value of 'number' is passed, instead of the adress to it */ 
    return 0; 
} 

gcc выдаст следующее предупреждение при компиляции программы.

scanf-problem.c: In function 'main': 
scanf-problem.c:5:5: warning: format '%f' expects argument of type 'float *', but argument 2 has type 'double' [-Wformat=] 
    scanf("%f", number); 
    ^

Как ожидается, GCC хочет второй аргумент зсапЕ иметь тип «поплавок *» (указатель на поплавок). Что меня беспокоит, так это то, что gcc полагает, что второй аргумент имеет тип «double», когда он действительно имеет тип «float».

Это приводит меня к вопросу, почему gcc полагает, что второй аргумент scanf является двойным, когда он фактически является поплавком?

Я сделал некоторые исследования по этой теме, чтобы получить ответ, но каждый ответ, который я нахожу, касается того, как избавиться от предупреждения (напишите '& номер' вместо 'number').

+3

Это в основном зсапЕ принимает адрес, как поплавок *, и вы прошли число которых составляет 8 байт, вы на ПК 64 бит? – Ishmeet

+0

Это объясняет многое. Действительно, я на 64-битном ПК. – oscfri

ответ

4

Это приводит меня к вопросу, почему gcc полагает, что второй аргумент of scanf является двойным, когда он фактически является поплавком?

Поскольку float повышен до double, как указано в C Стандартный

6.5.2.2 Функция вызывает

[# 6] ... аргументы , которые имеют тип поплавка повышено вдвое. Это , называемые рекламными акциями по умолчанию.

[# 7] ... Обозначение многоточия в прототипе функции декларатор вызывает преобразование типа аргумента для остановки после последнего объявленного параметра . По умолчанию аргументы по умолчанию выполняются по завершающим аргументам.

3

Вы уже знаете, что вы передаете неправильные вещи (как указано в комментарии) к scanf Так просто сообщая вам причину предупреждения является float аргумент, что вы предоставите сначала повышен до double.

3

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

1

[Редактировать] Кроме публикации прототипа scanf(), теперь я вижу ответ эхо @chill.
"имитация - это самая искренняя форма лести."


Проверить прототип scanf()

int scanf(const char * restrict format, ...); 

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

char, short - int.

C11 6.5.2.2 6

«... целые акции выполняются по каждому аргументу, и аргументы, которые имеют типа поплавка повышено в два раза. Это называется аргументом по умолчанию акции. ...»

1

Сообщение об ошибке вводит в заблуждение, scanf ожидает адрес переменной, чтобы вернуть данные обратно, и вы передали значение, а при поиске scanf в этом адресе он обнаружил, что он отличается от того, что было предложено при формировании «% f "

вы можете изменить его на

scanf("%f", &number); // &number instead of number 

, и он будет работать нормально

+0

Вопрос не в том, как решить предупреждение. Я спросил, почему gcc считает, что мой float является двойным в распечатке ошибок. – oscfri

+0

представьте себе это float a; float * pointerToA = a; // значение a вместо адреса scanf («% f», pointerToA) теперь он будет искать в памяти произвольный индекс, но значение a, которое может быть чем угодно –

Смежные вопросы