Неожиданный результат в C-программе - PullRequest
9 голосов
/ 23 марта 2011

Не могли бы вы объяснить выход этой программы на C?Я предполагаю, что проблема заключается в повреждении стека во время вызова функции printf("%d\n",t);, потому что я нажимаю float, но читаю int.Я не уверен.

#include <stdio.h>

int main() 
{ 
    long x; 
    float t; 
    scanf("%f",&t); 
    printf("%d\n",t); 
    x=30;
    printf("%f\n",x); 
    { 
        x=9;
        printf("%f\n",x); 
        { 
            x=10;
            printf("%f\n",x); 
        } 
        printf("%f\n",x); 
    } 
    x==9;
    printf("%f\n",x); 

}

И вывод

$ ./a.out 
20.39
0
20.389999
20.389999
20.389999
20.389999
20.389999
$

Ответы [ 4 ]

9 голосов
/ 23 марта 2011

Что происходит, когда вы лжете компилятору ... сначала вы говорите, что собираетесь отправить int в printf, но вместо этого отправляете float, а затем говорите, что отправите double но вместо этого вы отправляете long.

Не делайте этого.Не лгите компилятору.

Вы вызвали Неопределенное поведение .Все может случиться.Ваша программа может повредить стек;это может привести к тому, что вы ожидаете;это может привести к выходу лимонного сока из USB-порта;это может заставить демонов вылететь из вашего носа ;...

1 голос
/ 23 марта 2011

Что на самом деле происходит:

  • Ваш float равен 4 байта, ваш long равен 4 байта, ваш double равен 8 байтов.
  • Вы передаете float через многоточие - оно преобразуется в double. 8 байтов в стеке.
  • Вы передаете long через многоточие - 4 байта в стеке.
  • printf анализирует 8 байтов в стеке (спецификатор float) как double. Этот double будет состоять из «важной» части старого double в стеке и небольшого изменения в наименее значимой части (ваша long).
  • По умолчанию %f вывод усекает значение, вы не видите отклонения.

Измените все свои %f на например. %.20f чтобы увидеть, как long влияет на double.

1 голос
/ 23 марта 2011

Вы используете неверный спецификатор формата, чтобы печатать долго. Вместо этого используйте спецификатор формата %ld. Результаты

printf("%f\n",x);
     // ^ change this to %ld 
0 голосов
/ 23 марта 2011

printf("%d\n",t);

Использование неверного спецификатора формата в printf вызывает неопределенное поведение.

Используйте %f для печати float и double и %ld для печати длинной

C99 четко говорит (относительно printf и fprintf)

Если спецификация преобразования неверна, поведение не определено.Если какой-либо аргумент не является правильным типом для соответствующей спецификации преобразования, поведение не определено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...