词法元素(四)
四、常量
C语言中常量(constant)包括整数常量(integer-constant)、浮点常量(floating-constant)、枚举常量(enumeration-constatn)、字符常量(character-constant)和预定义常量(predefined-constant)。每个常量都有一个类型,常量值应在其类型可表示的值域范围内,常量的类型由其形式和值共同决定。
(注:预定义常量是ISO/IEC 9899:2024标准新增的常量。)
1、整数常量
整数常量以数字开头,可能存在指定基数的前缀、指定类型的后缀以及数字分隔符(digit separator);但不存在小数点,也不存在指数部分。
十进制整数常量以非0数字开头,由一个十进制数字序列构成,例如:123。二进制整数常量由前缀0b或者0B,后跟二进制数字构成的序列组成,例如:0B110。八进制整数常量由前缀0,后跟由八进制数字构成的序列(可选)组成,例如:06。十六进制整数常量由前缀0x或者0X,后跟十六进制数字构成的序列组成,字符a至f(或者A至F)分别表示数值10至15,例如:0x2c。
十进制数字包括:0 1 2 3 4 5 6 7 8 9
二进制数字包括:0 1
八进制数字包括:0 1 2 3 4 5 6 7
十六进制数字包括:0 1 2 3 4 5 6 7 8 9
a b c d e f
A B C D E F
十进制整数常量值以10为基数计算;二进制整数常量值以2为基数计算;八进制整数常量值以8为基数计算;十六进制整数常量值以16为基数计算。以十进制整数常量24为例,其二进制、八进制、十六进制形式分别为0b11000、030、0x18。
数字分隔符是ISO/IEC 9899:2024标准新增内容,用于在整数常量或者浮点常量中分隔数字,符号是单引号字符(')。数字分隔符在整数常量中的语法格式如下所示:
decimal-constant 'opt digit //十进制。 binary-constant 'opt binary-digit //二进制。 octal-constant 'opt octal-digit //八进制。 hexadecimal-digit-sequence 'opt hexadecimal-digit //十六进制。
其中decimal-constant是十进制整数常量,opt表示可选,digit表示十进制数字;binary-constant是二进制整数常量,binary-digit是二进制数字;octal-constant是八进制整数常量,octal-digit是八进制数字;hexadecimal-digit-sequence是十六进制数字序列,hexadecimal-digit是十六进制数字。
确定常量值时数字分隔符会被忽略。
0B1100'1010 //0B1100'1010等价于0B11001010。 1'23'456'7890 //1'23'456'7890等价于1234567890。
数字分隔符仅用于分隔数字。
0X'FEDC //数字分隔符的使用非法。 '3'5 //'不是数字分隔符,'3'是字符常量,5是整数常量。
整数常量类型是下表对应表格中第一个可以表示其值的类型。
| 后缀 | 十进制整数常量 | 二进制、八进制、十六进制整数常量 |
| 无后缀 | int long int long long int |
int unsigned int long int unsigned long int long long int unsigned long long int |
| u或者U | unsigned int unsigned long int unsigned long long int |
unsigned int unsigned long int unsigned long long int |
| l或者L | long int long long int |
long int unsigned long int long long int unsigned long long int |
| ul或者UL | unsigned long int unsigned long long int |
unsigned long int unsigned long long int |
| ll或者LL | long long int | long long int unsigned long long int |
| ull或者ULL | unsigned long long int | unsigned long long int |
| wb或者WB | _BitInt(N)① | _BitInt(N)① |
| uwb或者UWB | unsigned _BitInt(N)② | unsigned _BitInt(N)② |
① 在能够容纳值位和符号位的情况下,N为大于1的最小整数值。
② 在能够容纳值位的情况下,N为大于0的最小整数值。
#define TYPE(x) _Generic((x), \ int: "int type", \ unsigned int: "unsigned int type", \ long int: "long int type", \ default: "unknown type" \ ) printf("%s\n", TYPE(2147483648)); //输出long int type。 printf("%s\n", TYPE(0x80000000)); //输出unsigned int type。
编译环境中int类型占4个字节,unsigned int类型占4个字节,long int类型占8个字节;宏INT_MAX、UINT_MAX、LONG_MAX值分别为2147483647、4294967295、9223372036854775807。整数常量2147483648和0x80000000值相同;但进制不同,一个是十进制,一个是十六进制。
整数常量2147483648按int → long int → long long int顺序确定类型,因为INT_MAX < 2147483648 < LONG_MAX,所以整数常量2147483648的类型为long int类型。
整数常量0x80000000按int → unsigned int → long int → unsigned long int → long long int → unsigned long long int顺序确定类型,因为INT_MAX < 0x80000000 < UINT_MAX,所以整数常量0x80000000的类型为unsigned int类型。
如果一个整数常量(该整数常量不存在wb、WB、uwb或者UWB后缀。)不能使用其列表中的任何类型表示,但可以使用扩展整数类型表示,则该整数常量具有扩展整数类型。如果整数常量列表中的所有类型都是有符号整数类型,则扩展整数类型应为有符号整数类型。如果整数常量列表中的所有类型都是无符号整数类型,则扩展整数类型应为无符号整数类型。如果列表中同时包含有符号整数类型和无符号整数类型,则扩展整数类型可以是有符号整数类型,也可以是无符号整数类型。如果一个整数常量不能使用其列表中的任何整数类型表示,也不存在扩展整数类型,则该整数常量没有类型。
位精确整数类型是ISO/IEC 9899:2024标准新增内容。整数常量如果存在wb、WB、uwb或者UWB后缀,该整数常量是位精确整数类型。wb和WB后缀对应的是_BitInt(N)类型;在能够容纳值位和符号位的情况下,N为大于1的最小整数值;即使整数常量是正值,N也应该包含符号位。uwb和UWB后缀对应的是unsigned _BitInt(N)类型;在能够容纳值位的情况下,N为大于0的最小整数值。
5WB //_BitInt(4)类型,1个符号位,3个值位。 -5WB //_BitInt(4)类型,1个符号位,3个值位。 0X5WB //_BitInt(4)类型,1个符号位,3个值位。 5UWB //unsigned _BitInt(3)类型,3个值位。