[英]C int datatype and its variations
问候,今天再一次,当我尝试使用C99标准的C语言时,遇到了一个我无法理解的问题,需要专家的帮助。
编码:
#include <stdio.h>
int main(void)
{
int Fnum = 256; /* The First number to be printed out */
printf("The number %d in long long specifier is %lld\n" , Fnum , Fnum);
return 0;
}
问题:
1.)当我尝试运行此代码时,此代码向我提示警告消息。
2)但奇怪的是,当我尝试将说明符%lld
更改为%hd
或%ld
,警告消息未在执行期间显示,并且控制台上打印的值是正确的数字256 ,似乎也一切即使我尝试使用%u
, %hu
和%lu
也是正常的。总之,警告消息和数字的错误打印仅在使用long long说明符的变体时发生。
3.)为什么会发生这种情况?我认为很长的内存容量足以容纳256值,但是为什么不能将其用于打印适当的值呢?
警告消息:(对于以上源代码)
C:\Users\Sam\Documents\Pelles C Projects\Test1\Test.c(7): warning #2234: Argument 3 to 'printf' does not match the format string; expected 'long long int' but found 'int'.
感谢您花时间阅读我的问题。上帝保佑。
您正在将Fnum
变量传递给类型为int
printf,但是期望long long
。 这与long long是否可以容纳256无关,只是您选择的变量类型为int
。
如果你只想打印256,你可以得到多数民众赞成键入一个常数unsigned long long
,如下所示:
printf("The number %d in long long specifier is %lld\n" ,256 , 256ULL);
或演员:
printf("The number %d in long long specifier is %lld\n" , Fnum , (long long int)Fnum);
这里发生了三件事。
printf
采用可变数量的参数。 这意味着编译器不知道参数(除了格式字符串)应该是什么类型。 因此它无法将它们转换为适当的类型。 int
整数类型在传递给变量参数列表时会被“提升”为int
。 int
和long
的大小也相同(这在Microsoft方面是故意违反C89的做法–实际上,他们强制在C99中更改标准以使其“正常”)。 所有这些的结果是:不允许编译器将int
转换为long long
仅仅是因为您在参数列表中使用了%lld
。 (由于警告超出了标准行为,因此可以警告您忘记了%lld
。)因此,使用%lld
,您的程序将无法运行。 但是,如果使用任何其他大小说明符,则printf
结束时会寻找与int
大小相同的参数,并且该参数有效。
在处理可变参数函数时,调用方和被调用方需要某种方式来同意变量参数的类型。 对于printf,这是通过格式字符串完成的。 GCC非常聪明,可以读取格式字符串本身,并确定printf是否将以与实际提供的方式相同的方式解释参数。
在某些情况下,您可以忽略略有不同类型的参数。 例如,如果传递一个short,那么它将被隐式转换为int。 当sizeof(int)== sizeof(long int)时,也没有区别。 但是sizeof(int)!= sizeof(long long int),因此在这种情况下参数无法匹配格式字符串。
这是由于varargs在C中的工作方式所致。与普通函数不同, printf()
可以接受任意数量的参数。 程序员可以通过提供正确的格式字符串来告诉printf()
期望什么。
在内部, printf()
使用格式说明符来访问与输入参数对应的原始内存。 如果指定%lld
,它将尝试访问64位内存块(在Windows上)并将其找到的内容解释为long long int
。 但是,您仅提供了32位参数,因此结果将是不确定的(它将32位int
与堆栈中接下来会出现的任何随机垃圾组合)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.