关闭

C/C++中long long与__int64的区别

71人阅读 评论(0) 收藏 举报
分类:
在C99标准(详情请猛击:C语言的发展及其版本)中,增加了对64位长整型数据的支持,它的类型就是 long long,占用8个字节。

由于C99标准发布较晚,一些较老的C/C++编译器不支持,新编译器对C99的响应也没有想象地积极,导致当前主流的C/C++编译器对64位长整型的支持不统一,形态各异。

一般来说,64位整型的定义方式有 long long 和 __int64 两种(VC 6.0 只还支持__int64),而输出方式也有 printf(“%lld”, a)、printf(“%I64d”, a)、cout << a 三种。

这里讨论的是五种常用的C/C++编译器对64位整型的支持,它们分别是gcc(mingw32)、g++(mingw32)、gcc(linux i386)、g++(linux i386)、Microsoft Visual C++ 6.0。可惜的是,没有一种定义和输出方式的组合能同时兼容这五种编译器。如下表所示:
数据类型 输出方式 gcc
(mingw32)
g++
(mingw32)
gcc
(linux i386)
g++
(linux i386)
VC 6.0
long long “%lld” 错误 错误 正确 正确 无法编译
long long “%I64d” 正确 正确 错误 错误 无法编译
__int64 “lld” 错误 错误 无法编译 无法编译 错误
__int64 “%I64d” 正确 正确 无法编译 无法编译 正确
long long cout 非C++ 正确 非C++ 正确 无法编译
__int64 cout 非C++ 正确 非C++ 无法编译 无法编译
long long printint64() 正确 正确 正确 正确 无法编译
 
上表中,正确指编译通过,运行完全正确;错误指编译虽然通过,但运行结果有误;无法编译指编译器根本不能编译完成。

观察上表,我们可以发现以下几点:
  • long long 定义方式可以用于gcc/g++,不受平台限制,但不能用于 VC6.0。
  • __int64 是Win32平台编译器64位长整型的定义方式,不能用于Linux。
  • “%lld”用于Linux i386平台编译器,”%I64d”用于Win32平台编译器。
  • cout只能用于C++编译,在VC6.0中,cout不支持64位长整型。

表中最后一行输出方式中的printint64()是我自己写的一个函数,可以看出,它的兼容性要好于其他所有的输出方式,它是一段这样的代码:
  1. void printint64(long long a){
  2. if(a <= 100000000){
  3. printf("%d/n", a);
  4. }else{
  5. printf("%d", a/100000000);
  6. printf("%08d/n", a%100000000);
  7. }
  8. }
这种写法的本质是把较大的64位整型拆分为两个32位整型,然后依次输出,低位的部分要补0。看似很笨的写法,效果如何?

我把它和cout输出方式做了比较,因为它和cout都是C++支持跨平台的。首先printint64()和cout(不清空缓冲区)的运行结果是完全相同的,不会出现错误。我的试验是分别用两者输出1000000个随机数,实际结果是,printint64()在1.5s内跑完了程序,而cout需要2s。cout要稍慢一些,所以在输出大量数据时,要尽量避免使用。

对混乱情况的解释

首先要说的是,和Java等语言不同,C/C++本身并没有规定各数据类型的位数,只是限定了一个大小关系,也就是规定从所占的bit数来说,short <= int <= long <= long long。至于具体哪种类型占用多少位,是由你所用的开发平台的编译器决定的。

在现在的PC上一个通常的标准是,int和long同为32位,long long为64位。但是如果换到其它平台(如ARM)上,这个数字可能会有不同,类型所占的大小可以用sizeof()运算符查看。

long long是C99标准中新引进的数据类型,在古老的VC6.0中并没有这个类型,所以在VC6.0中用”long long”会发生编译错误。为了表示64位整数,VC6里采用的是微软自己搞出来的一个数据类型,叫做__int64,所以如果你是在VC6.0下编译的话,应该用__int64定义64位整型。

新版的Visual Studio已经支持long long了。GCC是支持long long的,我们在win系统中使用的其它IDE如Dev-Cpp, Code::Blocks等等大多是采用的MinGW编译环境,它是与GCC兼容的,所以也支持long long(另外为了与MS兼容,也支持__int64)。如果是在纯的linux下,就只能使用long long了。

关于使用printf的输入输出,这里就有一个更囧的情况。实际上只要记住,主要的区分在于操作系统:如果在win系统下,那么无论什么编译器,一律用%I64d;如果在linux系统,一律用%lld。这是因为MS提供的msvcrt.dll库里使用的就是%I64d的方式,尽管Dev-Cpp等在语法上支持标准,但也不得不使用MS提供的dll库来完成IO,所以就造成了这种情况。
0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:11197次
    • 积分:716
    • 等级:
    • 排名:千里之外
    • 原创:60篇
    • 转载:8篇
    • 译文:1篇
    • 评论:0条
    文章存档