#c
#c
Вопрос:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int a = 5;
float b = 10;
double c = 15;
printf("%d %f %lfn", a, a, a);
printf("%d %f %lfn", b, b, b);
printf("%fn", b);
printf("%d %f %lfn", c, c, c);
printf("%lfn", c);
}
Вывод:
5 0.000000 0.000000
0 0.000000 0.000000
10.000000
0 0.000000 0.000000
15.000000
Я не понимаю, почему в первом случае выводится 0 для b и c, даже для соответствующего спецификатора формата?
Я использую Visual Studio.
Ответ №1:
Вы должны знать, что компилятор C недостаточно умен, чтобы понимать строку формата и правильно приводить следующие аргументы. Поэтому ваши аргументы, вероятно, будут обработаны неправильно; для printf
это всего лишь несколько байтов в стеке. Представление a double
со значением 15.0, скорее всего, содержит несколько байтов 0 в стеке, которые printf
читаются как int
s, потому что вы сказали ему сделать это в строке формата.
Ответ №2:
Использование неправильной спецификации преобразования вызывает неопределенное поведение. Вы можете получить ожидаемый или неожиданный результат или даже сбой программы.
C11: 7.21.6 Форматированные функции ввода / вывода:
Если спецификация преобразования недействительна, поведение не определено.
Комментарии:
1. Верно, но довольно бессмысленно для того, кто пытается понять, что происходит.
2. Более того, можно даже получить 42!
3. @luk32; Или даже сбой жесткого диска!
4. @haccks Я подумал, что компилятор, который намеренно выводит 42 в UB, был бы забавной вещью. Но ваша идея полностью затмевает это =).
5. @luk32; Мне нравится портить ВЕСЕЛЬЕ! 😛
Ответ №3:
Да, вы используете правильный спецификатор формата в части строки формата, но поскольку вы уже ранее использовали неправильный спецификатор формата в строке формата, вы уже вызвали весь ад, чтобы вырваться на свободу.
В частности, printf
к моменту замены бит %f
и %lf
уже «не соответствует» вашим аргументам данных.