电脑爱好者,提供IT资讯信息及各类编程知识文章介绍,欢迎大家来本站学习电脑知识。 最近更新 | 联系我们 RSS订阅本站最新文章
电脑爱好者
站内搜索: 
当前位置:首页>> C++/VC>>Dev-C++下关于long long类型的实验:

Dev-C++下关于long long类型的实验

来源:www.cncfan.com | 2006-4-28 | (有5562人读过)

kingwei 2005.3.10

实验环境: Dev-C++ 4.9.6.0 (gcc/mingw32), 使用-Wall编译选项


#include <stdio.h>

int main()
{
signed long long int v_signed_long_long_int;
unsigned long long int v_unsigned_long_long_int;

/* PART1:USE %I64d AND %I64u */

/* [-2^63, 2^63-1] ==> [-9223372036854775808, 9223372036854775807] */
scanf("%I64d", &v_signed_long_long_int);
printf("%I64d\n", v_signed_long_long_int);

/* [0, 2^64-1] ==> [0, 18446744073709551615] */
scanf("%I64u", &v_unsigned_long_long_int);
printf("%I64u\n", v_unsigned_long_long_int);

/* PART2:USE %lld AND %llu */

/* [-2^63, 2^63-1] ==> [-9223372036854775808, 9223372036854775807] */
scanf("%lld", &v_signed_long_long_int);
printf("%lld\n", v_signed_long_long_int);

/* [0, 2^64-1] ==> [0, 18446744073709551615] */
scanf("%llu", &v_unsigned_long_long_int);
printf("%llu\n", v_unsigned_long_long_int);

return 0;
}


这个程序在Dev-C++下编译会有一系列Warning:

D:\Dev-C++下关于long long类型的实验\llint_format.cpp [Warning] In function `int main()':
14 D:\Dev-C++下关于long long类型的实验\llint_format.cpp [Warning] unknown conversion type character `I' in format
14 D:\Dev-C++下关于long long类型的实验\llint_format.cpp [Warning] too many arguments for format
15 D:\Dev-C++下关于long long类型的实验\llint_format.cpp [Warning] unknown conversion type character `I' in format
15 D:\Dev-C++下关于long long类型的实验\llint_format.cpp [Warning] too many arguments for format
18 D:\Dev-C++下关于long long类型的实验\llint_format.cpp [Warning] unknown conversion type character `I' in format
18 D:\Dev-C++下关于long long类型的实验\llint_format.cpp [Warning] too many arguments for format
19 D:\Dev-C++下关于long long类型的实验\llint_format.cpp [Warning] unknown conversion type character `I' in format
19 D:\Dev-C++下关于long long类型的实验\llint_format.cpp [Warning] too many arguments for format

可以看到,Warning都是因为PART1中使用了格式符%I,而产生的。PART2则一切正常,编译器没有给出任何警告信息。

但是——请看测试结果:


----- test case #1: 下界 -----

-9223372036854775808
0
-9223372036854775808
0

output:

-9223372036854775808
0
0
0


----- test case #2: 上界 -----

9223372036854775807
18446744073709551615
9223372036854775807
18446744073709551615

output:

9223372036854775807
18446744073709551615
-1
4294967295


----- test case #3: 下溢 -----

-9223372036854775809
-1
-9223372036854775809
-1

output:

9223372036854775807
18446744073709551615
-1
4294967295


----- test case #4: 上溢 -----

9223372036854775808
18446744073709551616
9223372036854775808
18446744073709551616

output:

-9223372036854775808
0
0
0


结果恰恰相反,PART1的工作完全正常,PART2却产生了问题.
为什么呢?我是这样猜想的:


"%lld"和"%llu"是linux下gcc/g++用于long long int类型(64 bits)输入输出的格式符。

而"%I64d"和"%I64u"则是Microsoft VC++库里用于输入输出__int64类型的格式说明。

问题就出在:Dev-C++使用的编译器是Mingw32,Mingw32是x86-win32 gcc子项目之一,编译器核心还是linux下的gcc。

进行函数参数类型检查的是在编译阶段,gcc编译器对这段代码进行检查,显然它不认得"%I64d",
所以给出了警告“unknown conversion type character `I' in format”,它不认为这是一个格式说明符。
接着,gcc发现整个格式字符串里没有合法的说明符,但传给printf/scanf的除了格式字符串,还有数据参数,
于是它又给出了第二个警告“too many arguments for format”。

对于"%lld"和"%llu",gcc理所当然地接受了。悲剧就此埋下了伏笔。

Mingw32在编译期间使用gcc的规则检查语法,在连接和运行时使用的却是Microsoft库。
这个库里的printf和scanf函数当然不认识linux gcc下"%lld"和"%llu",对"%I64d"和"%I64u",它则是乐意接受的。

——于是就出现了上面的结果。


C++/VC热门文章排行
网站赞助商
购买此位置

 

关于我们 | 网站地图 | 文档一览 | 友情链接| 联系我们

Copyright © 2003-2021 电脑爱好者 版权所有 备案号:鲁ICP备09059398号