C语言中哪些基本数据类型在类型提升机制下会发生怎样的转换?

摘要:本文介绍了 C 语言中的基本数据类型体系,包括整数类型、浮点类型以及字符类型,并对各类型的常见取值范围和使用特点进行了说明。在此基础上,进一步解释了 C 语言表达式计算中常见的类型提升机制,重点说明了 `char` 与 `short` 在运
一、基本整数类型   整数类型用于表示不带小数部分的数值。C语言是通过长度和符号两个维度来扩展整数类型。但是需要注意 C 标准只规定了最小位数,不规定具体大小,具体实现则由编译器和平台决定。下面按照常规情况说明整数类型: 类型常见大小 char 8 bit short 16 bit int 32 bit long 32 bit long long 64 bit (一)、有符号短整型(short)   short 是signed short的简写,其位宽至少有16位,常见的 short 范围是 -32768~32767,计算公式是 -2n-1 ~ 2n-1。 short a; signed short b; short int c;   但是这里要注意不要假设位宽一定是16位,只能假设 ≥16位。同时short在参与表达式计算时会发生整数提升,通常是被提升为 int。 (二)、无符号短整型(unsigned short)   unsigned short 是 short 的无符号版本,只能表示非负整数,其位宽与short相同,常见的范围是 0~65535,计算公式是 0 ~ (2n-1)。 unsigned short a; unsigned short int b; (三)、有符号整型(signed int)   int 是 signed int 的简写,C标准规定 int位宽 ≥ short位宽 ,在大多数32位系统中 int 位宽是 32bit,常见范围是-2147483648 ~ 2147483647。 int a; signed int b;   int 是C语言最常使用的整数类型。 (四)、无符号整型(unsigned int)   unsigned int 是 int 的无符号版本,只能表示非负整数,其位宽与 int 相同,常见范围是0 ~ 4294967295。 unsigned int a; (五)、有符号长整型(long)   long 是 signed long int 的简写,C标准规定 long位宽 ≥ int 位宽,但在大多数32位系统中,long位宽是32bit,常见范围是-2147483648 ~ 2147483647。 long a; signed long b; long int c; (六)、无符号长整型( unsigned long)   unsigned long 是 long 的无符号版本,只能表示非负整数,其位宽与 long 相同,常见范围是0 ~ 4294967295。 unsigned long a; (七)、有符号长长整型( long long)   long long 是 signed long long 的简写,其位宽是 64bit,常见的范围是-263 ~ 263 -1,也就是-9223372036854775808~9223372036854775807。 long long a; signed long long b; (八)、无符号长长整型(unsigned long long)   unsigned long long 是 long long 的无符号版本,只能表示非负整数,其位宽与 long long 相同,常见范围是0 ~ 264 - 1,也就是0 ~ 18446744073709551615。 unsigned long long a; (九)、字符整型(char)   char 在C语言中也是整数类型,并不是专门的“字符类型”。设计 char 的初衷是用于存储一个字节的数据,因此既可以表示字符,也可以表示小范围的整数。按照C标准规定 char = 1 byte ,通常在绝大多数系统中其位宽是 8bit。标准允许 byte ≥ 8bit,但是该情况仅为标准兼容设计,现实中所有主流平台(PC、嵌入式、MCU)的 1byte 均为 8bit。   signed char 的常见范围是 -128 ~ 127,unsigned char 的常见范围是 0 ~ 255,而 char 由编译器决定。 char a; signed char b; unsigned char c;   需要注意 char 是否带符号由编译器决定。比如在Keil ARMCC中 char 默认类型是 unsigned char ,但是在GCC中 char 默认类型是 signed char。 二、浮点数   浮点数用于表示带小数的数值。C语言提供了三种浮点类型: 类型精度常见大小 float 单精度 4字节 double 双精度 8字节 long double 扩展精度 8 / 16   这些类型通常遵循 IEEE-754 浮点标准进行存储。它们的主要区别在于存储精度和表示范围。在嵌入式系统中,double 和 long double 往往会退化为 float,因此在MCU开发中,最常使用的浮点类型通常是float。 (一)、单精度浮点数(float)   float 是单精度浮点数,通常占4字节(32bit),在IEEE-754标准中,其内部结构为 符号位 1bit 指数 8bit 尾数 23bit   float 可表示的有效十进制精度约为 6~7位,其常见范围是约±3.4×10³⁸。 float a = 3.3f;   在日常开发中需要注意,在使用 float 时,如果MCU没有 FPU(浮点运算单元),浮点运算会通过软件实现,计算速度会明显慢于整数运算。 (二)、双精度浮点数(double)   double 是双精度浮点数,在桌面系统中通常为8字节(64bit)。在IEEE-754标准中,其内部结构为 符号位 1bit 指数 11bit 尾数 52bit   double 可表示的有效十进制精度约为15位,其常见范围是 约1.7×10³⁰⁸。 double pi = 3.141592653589793; (三)、扩展精度浮点数(long double)   long double 用于提供比 double 更高的精度。C标准中只规定了 long double ≥ double,但具体实现依赖平台。常见情况如下: 平台long double大小 Windows MSVC 8 byte GCC x86 16 byte ARM嵌入式 8 byte 三、类型级别   在C语言表达式计算中,不同类型之间会发生类型提升(Type Promotion)。常见的类型顺序是 long double double float unsigned long long long long unsigned long long unsigned int int   这个也是类型的级别,从高到低排序,仅做参考。但是存在一个例外的情况就是当long和int的大小相同时,unsigned int 比 long 的级别高。这里之所以没有列出short和char类型,是因为它们已经被升级到int或unsigned int。   当不同类型参与运算时,低等级类型会提升为高等级类型,例如: short a = 10; int b = 20; int c = a + b;   在这里 short->int,这是因为C语言规定:short 和 char 在表达式中会自动提升为 int。这个过程被称为Integer Promotion(整数提升)。同时需要注意的是,整数类型之间并不存在一个简单的线性"等级顺序"。当不同整数类型参与运算时,编译器会根据类型宽度和符号属性 按规则选择合适的目标 类型,这一过程属于 Usual Arithmetic Conversions (常规算术转换)。   以上就是对C语言基本数据类型的介绍。在实际开发中,我们往往也需要根据基本数据类型的数据范围、存储空间以及计算效率等角度去选择合适的数据类型。