目录
编译器可以设定int和long的长度吗?
以long为例,虽然大部分64位C语言编译器long长度是8,依然有选项可以将long的长度设定为4.
- gcc -m32选项可以让GCC生成32位目标代码,sizeof(int)和sizeof(long)也就变成4.
- 需注意,gcc -m64选项可以让GCC生成64位目标代码,sizeof(int)依然保持4.
- man gcc看到形如-mint64, -mlong32之类的设定,值得注意的是:在某些GCC版本很可能不支持,不能认为这些选项一定有效!
int类型的长度为什么不统一?
以C语言为例,它为了支持不同硬件平台,在计算机早期,硬件资源包括内存资源非常紧张,C语言标准不能直接规定int类型就是16位或者32位,这样会造成其它平台不能运行。故,标准做了取舍,不规定int类型的确切长度,但规定了与它相关的整型类型长度的大小关系,以此既支持不同平台,又避免不同平台带来类型长度出现long比int还小的混乱。但,不得不说,在不同平台、不同编译器下,C语言类型长度产生的问题一直存在。
- Swift/Go/Rust都有通用整型和确定长度的整型两种,据情况选择。
- 仓颉明确区分出Int32和Int64类型。
64位编译器int类型依然是32位?
- 32位编译器,int和long一般都设置为4字节。
例如i686-w64-mingw32-gcc.exe. - 64位编译器,Linux平台long一般提升到8字节,int一般保持为4字节;Windows平台long和int保持为4字节,用long long表示8字节。这是由于Win64使用LLP64模型,Linux 64位使用LP64.
- 关于Windows 64位LLP64模型,可参考: Why did the Win64 team choose the LLP64 model?
Ubuntu 22.04 64位系统默认gcc是64位,可执行文件在/usr/bin/x86_64-linux-gnu-gcc,Windows 10 64位Cygwin gcc.exe同样也是64位,编译代码printf("%d %d\n", sizeof(int), sizeof(long))会得到"4 8". 如果换成上面提到的i686-w64-mingw32-gcc.exe编译,得到"4 4".
int和long的区别
作为基本类型,一般而言,编译器对于int和long的大小设计是不同的。尤其是16位系统演变成32位系统和32位系统演变成64位系统,差异尤为明显。编译器为32位系统一般定义int为4字节,long同样为4字节。对于64位系统,long会提升为64位以与寄存器长度一致。
long long类型
C99引入long long类型,标准规定至少64位,以此对long类型进行扩展。C++11看到C语言引入long long也跟风引入,同样规定至少64位。不过,在1995年就曾经有人提议将long long加入C++98,只不过被C++委员会以C语言没有此类型给拒绝了。
整型是一等公民?
大部分编程语言都将整型int(64位对应long)作为一等公民,从硬件的角度,int或者long也与寄存器位数一致(至少可兼容),这样访问起来方便快捷有效。
你还想知道:有符号和无符号数 基本数据类型 int和long的区别
%l %h和%d %o %u %x
C语言%d对应整形,%hd和%ld对应短整形和长整形,%lld代表long long int,%o代表八进制输出,%u是%d的无符号版本,格式串解析是在libc完成。
- 不能有独立的%h或%l格式串,会和上面的组合格式产生冲突。
- VS2019编译C代码只有%h格式符: 编译警告:
格式字符串“%h”未终止
- VS2019编译C代码只有%h格式符: 编译警告:
- %d/%o/%u/%x和%h或%l可以组合,比如%ho, %hu, %lo, %lx, %ld等。
- 不能用大写模式,比如%L或者%LL, libc不识别
%h数值可能不是预期
在C语言中,假设short是2字节,%hd只会获取2个字节数据。如下第二句输出结果会变成-32768.
- printf("%hd\n", 200);
- printf("%hd\n", 32768);
无符号版本
- 注意,%o和%x输出格式是无符号版本。
%ld和%d的区别
%d默认是int格式,%ld的l代表long, 表示long int格式。如果int和long长度不同,二者有天差地别,因为libc会抓取的字节长度不同,最终数值也不同。类似的,%li, %lx, %lf同样也比base类型多了long,字节长度也可能有差异。
编程语言的短整型和长整型
- C/ObjC/C++/C#
数值字面量后缀l或者L,如果是long long, 后缀是ll或LL- 例如12l, 100LL
- C#没有long long类型。
- Kotlin
- Long类型变量必须有后缀L (不能是小写l)
不建议用小写的l
- 小写的l和数字1很像,建议用大写L.
若文章对您有帮助,欢迎关注 程序员小迷 。助您在编程路上越走越好!
微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。
我是 程序员小迷 (致力于C、C++、C#、Android、iOS、Java、Kotlin、Objective-C、Swift、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。