使用GCC编译程序时,我收到以下警告:
format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int
现在只是通过玩耍我意识到%lo修复了警告。但是,我真的不明白我在做什么。
是否有命名约定来获取类型的简短形式?例如,int是%d,为什么??
谢谢!
答案 0 :(得分:22)
long unsigned int = unsigned long
您可以使用%lu
打印这些内容。
同样地,%llu
适用于unsigned long long
。
%d - int
%u - unsigned
%ld - long
%lld - long long
%lu - unsigned long
%llu - unsigned long long
答案 1 :(得分:3)
不,有惯例,你只需要look at the documentation。
格式化说明符不是与类型的1:1映射,它们控制输出格式(因此名称)。单个输入值类型可以有许多输出格式。
例如,%d
是“十进制”,因为它将整数打印为十进制数。还有%i
(“整数”)完全相同的事情。
对于unsigned int
值,您同时拥有%x
(以十六进制打印)和%u
(以八进制打印)。
答案 2 :(得分:3)
int,long等的定义特定于目标。如果int和long的大小匹配则为
printf("%d",var);
不会抱怨,但如果说长64位且int是32位,那么你将得到你描述的警告/错误。两种解决方案之一:
printf("%ld",var);
or
printf("%d",(int)var);
对于后者,当然你必须确保编译器将int与%d大小相关联,如果你得到另一个警告,则相应地进行调整。
编辑:
编译器试图帮助你,担心C库的东西,这不是编译器的业务。 printf()使用可变数量的参数,希望您正确匹配您的格式字符串。当printf在32位系统上看到%d时,它可能只会获取下一个32位参数。但是如果您将64位整数作为参数放入,则可以获取该整数的一半,并将另一半用作格式字符串中的下一项。例如
unsigned long ul;
float f;
f=3.4;
ul=0x3F9DF3B612345678;
...
printf("%X %f\n",ul,f);
根据您的系统,字节顺序等,如果上面的代码产生了这个输出,那么32位系统你根本不应该感到惊讶:
12345678 1.234000
因为这就是你告诉它的。你告诉它采取ul的低32位并打印为十六进制(%X)和ul的高32位并打印为float(%f)并将f放入函数调用是一种浪费你没有提供任何格式化以使用浮点值。
现在取决于特定日期目标系统上的编译器,您可以根据需要使用上述代码,取一个系统/编译器,其中unsigned long被解释为32位,%X被解释为32位,然后你得到关于64位赋值的警告,但printf更有意义。
由于这种痛苦,像gcc这样的编译器试图通过假设当你使用一个名为printf()的函数时使用标准的C函数来解决这些类型常见错误。
答案 3 :(得分:1)
但我真的不明白我在做什么。
您正在做的是告诉printf
函数如何显示您在格式字符串后面提供的数据。您可能会发现%lo
并未真正打印出您期望的结果 - 它会打印出正确的数据,但是采用八进制(基数为8)格式。
是否有命名约定来获取类型的简短形式?例如,int是%d,为什么??
“简短形式”称为格式说明符。没有任何约定可以让您派生适当的printf格式说明符。你只需要look them up in an appropriate reference。
答案 4 :(得分:0)
%lo =以八进制数字打印的无符号长整数。是的,docs是一个很好的起点..但是某些东西有一个模式,比如o表示八进制,x表示十六进制,l表示任何长度等等。习惯了许多这样的格式说明符可以帮助你在任何地方获得模式。 / p>