【发布时间】:2021-06-29 04:28:09
【问题描述】:
我是 C 编程的新手,我在函数 printf 的参数中使用以下占位符规范时发现了这种奇怪的行为。在使用在线 C 编译器 (OnlineGDB) 和带有 gcc 终端编译的 VSCode 时,我得到了两个不同的结果。
那是sn-p:
#include <stdio.h>
int main()
{
printf("%lld", 4);
return 0;
}
正如 Wiki 所说,“ll 长度字段占位符是为整数类型制作的,并导致 printf 期待一个 long long-sized 整数参数”。 在在线编译器中我得到了这个:
main.c:13:16:警告:格式“%lld”需要“long long int”类型的参数,但参数 2 的类型为“int”[-Wformat= ]
4
所以它在警告后打印 4。
VSCode中的结果完全不同????:
15621861207441412
没有警告,但这个数字是从哪里来的?
为什么在如此“简单”的情况下会有如此不同的行为?值 4 不也是一个 ll 整数吗?我的猜测是第二个期望更大的值,因此它在该间隔内向我发送了一个相当随机的值。另外,我必须为大学考试学习C,你能推荐我在编译示例项目时应该使用哪个编译器吗? 非常感谢您的宝贵时间。
【问题讨论】:
-
警告是正确的。
4是int文字。如您所说,要拥有long long文字,您需要编写4LL。另外,您在 VSCode、MSVC 中使用的是哪个编译器?您是否尝试过启用所有警告?我没有使用过 MSVC,但如果你这样做,它应该会发出警告。您的在线编译器可能正在使用 GCC 或 clang。 -
编译器没有义务警告可变参数函数的参数。从本质上讲,编译器不知道它们的使用,但在
printf的情况下,一个有用的编译器会分析格式字符串并检查参数是否正确。 MSVC 对printf()和fprintf()和sprintf()执行此操作,但不是它自己的cprintf()函数。注意4默认是int类型,试试4LL。 -
printf()函数信任您已将符合格式规范的数据放入堆栈。如果格式需要 8 个字节,那么无论 为什么 它们在堆栈上,都会使用 8 个字节。在您的一个环境中,其他 4 个字节恰好是 0。 -
@mediocrevegetable1 详细信息:C 将
4指定为常量,而不是literal。 C 指定了 2 个文字:string 和 compound。与常量不同,这些文字可以获取它们的地址。关于警告的要点。
标签: c gcc compilation format-string