数据类型 / 编程语言 · 2023年 10月 6日 0

数据类型大小

46 次浏览

编译型语言数据类型大小比较确定,可能有多种,但具体在特定平台特定编译器,大小一定是确定的。解释型语言或脚本处理数据类型更自由,默认看成“字符串”,在做数值运算自动转换。本文不过多讨论脚本类语言,它们不太关心这么多细节。

以如下标准的数据类型为例:

  • char / short / int / long (long) / float / (long) double

sizeof

  • C/ObjC/C++/C# 都提供sizeof运算符计算类型大小,尽管如此,编译型语言类型大小不是完全统一,甚至完全不是预期。
  • C/ObjC/C++ sizeof既是关键字又是运算符,此运算符是编译器计算而非运行期计算。比较有意思的是,虽然是编译期可计算,它不能用于宏条件编译判断。
  • Java没有sizeof运算符,因为它认为所有数据类型大小都是确定的,依然可以用<TYPE>.SIZE得到类型的比特数。
    Integer.SIZE返回32.
  • Python用getsizeof获取变量大小,包括对象的其他内存开销,如下并不是等于4或者8.
    sys.getsizeof(1)
  • 结构体的大小不一定等于所有成员大小之和,对齐影响最终的大小。
  • 空类大小是0吗? C++不为0,为了避免不同对象在同一个地址。

char类型

  • C/ObjC/C++ char类型为1字节,wchar_t一般为2字节。
    • ObjC NSString字符串内部默认是UTF-16编码,一个字符是2字节。
  • Java/C# char类型默认是Unicode字符,2字节。
    C# char类型和ushort类型范围是一样的。
  • Go有两种字符类型,byte是以往的1字节字符,rune代表4字节Unicode字符(相当于int32类型)。
  • Swift用Character代表字符类型,Swift 5之前默认字符是UTF-16或ASCII码存储,即一个字符可能是1字节或2字节,Swift 5之后(包含)默认是UTF-8编码,根据字符所属范围长度不等。

short类型

  • Fortran支持的整形之一,kind = 2代表2字节。
  • C/C++不直接规定它的长度,要求不大于int类型,不小于char类型。具体实现一般为2字节。
  • Java/C#中short固定为2字节。

int类型

  • int类型代表计算机系统处理整形最自然的长度,一般和数据寄存器长度一样。
  • 和short类型,Fortran kind=4即代表常规意义的标准的整形。
  • 和short类似,C/ObjC/C++不直接规定它的长度,要求不大于long类型,不小于short类型。具体实现一般为4字节。
    • 一般而言,16位系统int是2字节,32位系统int为4字节,而64位系统并不一定是8字节,因为有long的存在。
  • Java/C#固定为4字节。
  • Rust isize和usize类型长度取决于目标平台,i32和i64是固定大小。
  • 仓颉Int32固定4字节,Int64固定8字节。

long类型

  • C/C++规定long类型只要不小于int类型即可。
  • Fortran kind=8代表8字节整形,有点类似于64位系统long的长度(一般而言)。
  • 32位编译器,int和long一般都设置为4字节,另外Windows 16位环境下long也是4字节。
  • 64位编译器,Linux平台long一般提升到8字节,int一般保持为4字节;Windows平台long和int保持为4字节,用long long表示8字节。这是由于Win64使用LLP64模型,Linux 64位使用LP64.
  • Java/C#固定为8字节。

long long类型

  • 大部分编译器认为它不小于long类型即可,在64位系统一般为8字节。因为目前没有广泛使用128位系统,long long一般不会超过16字节。

float类型

  • 一般float类型定义为4字节。

double类型

  • 一般double类型定义为8字节。

long double类型

  • 一般long double类型至少不小于double类型,不同编译器环境有差异。
  • 不一定是16字节,可能保持和double类型一样为8字节,也可能是10字节。
  • 32位的gcc比较特殊,long double长度为12字节。gcc也提供编译选项选择long double的长度,例如: -m128bit-long-double或-mlong-double-80等等.
  • 带复数的complex long double类型一般是long double的2倍。

char *类型

  • C/C++对char *类型的处理不能完全按指针,要根据上下文。
    • sizeof("hello")返回5,而不是指针的大小4或者8.
    • 数组变量的sizeof返回数组大小,而非数组的影子指针大小。
      • 总结起来,当编译器能知道它的大小,就按那个大小,不能确定大小,按指针大小。