前言
C/C++程序也写了有几年了,但被问起详细的C/C++数据类型,所占内存空间,以及数据类型隐式/显示转换时,有些还是模棱两可,本文做深入的探讨。
基本数据类型
在之前写MCU程序时经常会用到char、short、unsigned short、int等类型,在后面写Linux程序时,用到int、long、long long、float、double等类型、以为C/C++有这么多基本数据类型,仔细研究才发现,其实C/C++的基本数据类型就3种:
-
字符型char:
在 C 语言中,char 是基本的字符类型,用于存储单个字符,通常占 1 个字节,实际上它存储的是字符对应的 ASCII 码值,可以像整数一样参与运算,例如 char c = ‘A’。 -
整型int:
上面说的short、unsigned short、signed、unsigned、int、long、long long都是整形,例如short其实是short int简写为short,long其实是long int简写为long,其他同理,后面都跟一个int,所以都是int类型。 -
浮点型float/double:
浮点型分为float(单精度浮点型)和double(双精度浮点型)还有long double(长双精度浮点型),浮点型用于表示带有小数部分的数值以及进行科学计数法形式的数值运算等情况。
特别说明:上面所说的int类型中signed, unsigned都隐含了int, 等价于signed int, unsigned int,但注意char没有这种默认等价性。char不和signed char或者unsigned char其中任何一个等价。如果用于文本,则使用未加限定的char, 是类似于 ‘a’, '0’的类型, 或是组成C字符串"abcde"的类型。它也可以是一个值,但是是当做无符号还是有符号数没有指定。 如果用于数字,那么: signed char, 范围 -128 到 127,unsigned char, 范围 0 ~ 255。char的默认类型不确定,有可能是unsigned,也有可能是signed,主要更具编译器而定。
数据类型长度
C/C++ 中不同目标平台下各数据类型长度是不同的,数据类型的实际长度由编译器在编译期间通过编译参数指定目标平台而确定的。 short int,int,long int 的字节数都是随编译器指定的目标平台而异,但是在ANSI/ISO指定:无论什么平台都要保证long型占用字节数不小于int型, int型不小于short型,即:
- sizeof(short int) <= sizeof(int)
- sizeof(int) <= sizeof(long int)
- sizeof(short int) >= 16 bit (2 Byte)
- sizeof(long int) >= 32 bit (4 Byte)
16bit 编译器:
类型 | 长度 | 范围 |
---|---|---|
char | 1 Byte | - |
unsigned char | 1 Byte | 0~255 |
signed char | 1 Byte | -128~127 |
unsigned short int / unsigned short | 2 Byte | 0~65535 |
signed short int / short int / short | 2 Byte | -32768~32767 |
unsigned int / unsigned | 2 Byte | 0~65535 |
signed int / signed / int | 2 Byte | -32768~32767 |
unsigned long int / unsigned long | 4 Byte | 0~4294967295 |
signed long int / signed long / long | 4 Byte | -2147483648~2147483647 |
signed long long int / signed long long / long long | 8 Byte | -9223372036854775808~9223372036854775807 |
unsigned long long int / unsigned long long | 8 Byte | 0~18446744073709551615 |
float | 4 Byte | 1.17549e-38 ~ 3.40282e+38 |
double | 8 Byte | 2.22507e-308 ~ 1.79769e+308 |
32bit 编译器:
类型 | 长度 | 范围 |
---|---|---|
char | 1 Byte | - |
unsigned char | 1 Byte | 0~255 |
signed char | 1 Byte | -128~127 |
unsigned short int / unsigned short | 2 Byte | 0~65535 |
signed short int / short int / short | 2 Byte | -32768~32767 |
unsigned int / unsigned | 4 Byte | 0~4294967295 |
signed int / signed / int | 4 Byte | -2147483648~2147483647 |
unsigned long int / unsigned long | 4 Byte | 0~4294967295 |
signed long int / signed long / long | 4 Byte | -2147483648~2147483647 |
signed long long int / signed long long / long long | 8 Byte | -9223372036854775808~9223372036854775807 |
unsigned long long int / unsigned long long | 8 Byte | 0~18446744073709551615 |
float | 4 Byte | 1.17549e-38 ~ 3.40282e+38 |
double | 8 Byte | 2.22507e-308 ~ 1.79769e+308 |
64bit 编译器:
类型 | 长度 | 范围 |
---|---|---|
char | 1 Byte | - |
unsigned char | 1 Byte | 0~255 |
signed char | 1 Byte | -128~127 |
unsigned short int / unsigned short | 2 Byte | 0~65535 |
signed short int / short int / short | 2 Byte | -32768~32767 |
unsigned int / unsigned | 4 Byte | 0~4294967295 |
signed int / signed / int | 4 Byte | -2147483648~2147483647 |
unsigned long int / unsigned long | 8 Byte | 0~18446744073709551615 |
signed long int / signed long / long | 8 Byte | -9223372036854775808~9223372036854775807 |
signed long long int / signed long long / long long | 8 Byte | -9223372036854775808~9223372036854775807 |
unsigned long long int / unsigned long long | 8 Byte | 0~18446744073709551615 |
float | 4 Byte | 1.17549e-38 ~ 3.40282e+38 |
double | 8 Byte | 2.22507e-308 ~ 1.79769e+308 |
指针变量
指针变量所占字节数是根据编译器的寻址空间决定宽度的:
16 bit编译器寻址空间为16 bit,所以指针变量宽度为2 Byte
32 bit编译器寻址空间为32 bit,所以指针变量宽度为4 Byte
64 bit编译器寻址空间为64 bit,所以指针变量宽度为8 Byte
补充
在C里面经常看到size_t的数据类型,这是一种自定义的数据类型。size_t是标准C库中定义的,在64位系统中为long unsigned int,非64位系统中为 unsigned int。
关于数据类型转换,可查看另一篇文章:C/C++数据类型转换