在 C 中使用格式说明符打印
Printing with format specifiers in C
在 class 测验中,我被要求编写以下代码片段的输出。
x = 1.234;
printf("x=%2d");
变量 x
包含点值,所以我假设它是 float/double 类型。
在论文中我回答说这段代码只是简单地在引号内打印语句(如 x=%2d
),因为在打印函数中它会按原样打印 " " 中的任何内容。
但后来我 运行 我的编译器中的代码找到了 x=4199232
的输出(虽然不同的编译器的数量不同)
(编辑-我在这里添加了编译代码)
#include <stdio.h>
int main() {
float x = 1.234;
printf("x=%2d");
return 0;
}
任何人都可以向我解释这里到底发生了什么。
该代码具有未定义的行为(这解释了为什么 不同编译器中的数字不同 ),因为您没有为转换提供 int
类型的参数 %2d
.
如果你写了这个:
x = 1.234;
printf("x=%2d", x);
输出将取决于 x
的类型,它没有出现在代码片段中。如果 x
定义为类型 int
或更小的整数类型,包括 _Bool
,则输出应为 x= 1
,但如果 x
具有任何其他算术类型,包括 float
和 double
,行为再次未定义,因为参数不具有 %d
.
的预期类型
另请注意,格式字符串中没有尾随 \n
,因此输出可能会延迟到程序结束,并且可能根本不会出现在某些不一致的系统上。
在您的示例代码中,由于缺少 printf
的参数,行为未定义,但您确实将 x
定义为 float
,这将被隐式转换为double
传递给 printf
时,对 %d
无效。
这是修改后的版本:
#include <stdio.h>
int main() {
double x = 1.234; // only use `float` when necessary
printf("x=%2d\n", (int)x); // outputs `x= 1`
printf("x=%2f\n", x); // outputs `x=1.234000`
printf("x=%2g\n", x); // outputs `x=1.234`
printf("x=%.2f\n", x); // outputs `x=1.23`
return 0;
}
在此声明中
printf("x=%2d");
您忘记为转换说明符指定参数 d
。所以程序将尝试输出存储在内存中第二个参数应该是的任何内容。
所以程序有未定义的行为。
如果你指定第二个参数,它也会有未定义的行为
printf("x=%2d", x );
因为对 float 类型的对象使用了无效的转换说明符。
只输出你应该写的格式字符串
printf("x=%%2d");
在 class 测验中,我被要求编写以下代码片段的输出。
x = 1.234;
printf("x=%2d");
变量 x
包含点值,所以我假设它是 float/double 类型。
在论文中我回答说这段代码只是简单地在引号内打印语句(如 x=%2d
),因为在打印函数中它会按原样打印 " " 中的任何内容。
但后来我 运行 我的编译器中的代码找到了 x=4199232
的输出(虽然不同的编译器的数量不同)
(编辑-我在这里添加了编译代码)
#include <stdio.h>
int main() {
float x = 1.234;
printf("x=%2d");
return 0;
}
任何人都可以向我解释这里到底发生了什么。
该代码具有未定义的行为(这解释了为什么 不同编译器中的数字不同 ),因为您没有为转换提供 int
类型的参数 %2d
.
如果你写了这个:
x = 1.234;
printf("x=%2d", x);
输出将取决于 x
的类型,它没有出现在代码片段中。如果 x
定义为类型 int
或更小的整数类型,包括 _Bool
,则输出应为 x= 1
,但如果 x
具有任何其他算术类型,包括 float
和 double
,行为再次未定义,因为参数不具有 %d
.
另请注意,格式字符串中没有尾随 \n
,因此输出可能会延迟到程序结束,并且可能根本不会出现在某些不一致的系统上。
在您的示例代码中,由于缺少 printf
的参数,行为未定义,但您确实将 x
定义为 float
,这将被隐式转换为double
传递给 printf
时,对 %d
无效。
这是修改后的版本:
#include <stdio.h>
int main() {
double x = 1.234; // only use `float` when necessary
printf("x=%2d\n", (int)x); // outputs `x= 1`
printf("x=%2f\n", x); // outputs `x=1.234000`
printf("x=%2g\n", x); // outputs `x=1.234`
printf("x=%.2f\n", x); // outputs `x=1.23`
return 0;
}
在此声明中
printf("x=%2d");
您忘记为转换说明符指定参数 d
。所以程序将尝试输出存储在内存中第二个参数应该是的任何内容。
所以程序有未定义的行为。
如果你指定第二个参数,它也会有未定义的行为
printf("x=%2d", x );
因为对 float 类型的对象使用了无效的转换说明符。
只输出你应该写的格式字符串
printf("x=%%2d");