整数常量

来自cppreference.com
< c‎ | language

允许整数类型的值直接用于表达式。

语法

整数常量是拥有下列类型的非左值表达式

十进制常量 整数后缀(可选) (1)
八进制常量 整数后缀(可选) (2)
十六进制常量 整数后缀(可选) (3)
二进制常量 整数后缀(可选) (4) (C23 起)

其中

  • 十进制常量 是非零十进制数位( 123456789 ),跟随零个或更多十进制数字( 0123456789
  • 八进制常量 是数字零( 0 )跟随零个或更多八进制数位( 01234567
  • 十六进制常量 是字符序列 0x 或字符序列 0X 跟随一个或更多十六进制数位( 0123456789aAbBcCdDeEfF
  • 二进制常量 是字符序列 0b 或字符序列 0B 跟随一个或更多二进制数位( 01
  • 整数后缀 ,若提供则可包含下面一或两者,可以任何顺序出现:
  • 无符号后缀 (字符 u 或字符 U
  • 长后缀 (字符 l 或字符 L长长后缀 (字符序列 llLL (C99 起)

数位间可插入作为分隔符的可选的单引号(')。编译器会忽略它们。

(C23 起)

解释

1) 十进制整数常量(底 10 ,首位为最高位)。
2) 八进制整数常量(底 8 ,首位为最高位)。
3) 十六进制整数常量(底 16 ,首位为最高位,字母 'a' 到 'f' 表示十进制值 10 到 15 )。
4) 二进制整数常量(底 2 ,首位为最高位)。

下列对象被初始化为相同值:

int d = 42;
int o = 052;
int x = 0x2a;
int X = 0X2A;
int b = 0b101010; // C23

下列对象也被初始化为相同值:

unsigned long long l1 = 18446744073709550592ull; // C99
unsigned long long l2 = 18'446'744'073'709'550'592llu; // C23
unsigned long long l3 = 1844'6744'0737'0955'0592uLL; // C23
unsigned long long l4 = 184467'440737'0'95505'92LLU; // C23

整数常量的类型

整数常量类型是从依赖数字底和所用 整数后缀 的类型列表中,值所能吻合的首个类型。

允许的整数常量类型
后缀 十进制底 其他底
无后缀 int

long int
unsigned long int (C99 前)
long long int (C99 起)

int

unsigned int
long int
unsigned long int
long long int(C99 起)
unsigned long long int(C99 起)

uU unsigned int

unsigned long int
unsigned long long int(C99 起)

unsigned int

unsigned long int
unsigned long long int(C99 起)

lL long int

unsigned long int(C99 前)
long long int(C99 起)

long int

unsigned long int
long long int(C99 起)
unsigned long long int(C99 起)

l/Lu/U unsigned long int

unsigned long long int(C99 起)

unsigned long int

unsigned long long int(C99 起)

llLL long long int(C99 起) long long int(C99 起)

unsigned long long int(C99 起)

ll/LLu/U unsigned long long int(C99 起) unsigned long long int(C99 起)

若整数常量过大从而无法符合后缀/底结合所允许的任何类型,且编译器支持扩展整数类型(譬如 __int128 ),则常量可能以扩展整数类型给出;否则程序为谬构。

注解

整数常量中的字母无关大小写: 0xDeAdBaBeU0XdeadBABEu 表示同一个数(一个例外是 long-long-suffix ,必须是 llLL ,不能是 lLLl (C99 起)

没有负整数常量。如 -1 的表达式是将一元负运算符应用到常量所表示的值。

当用于 #if #elif 的控制表达式时,所有有符号整数常量都表现为如同拥有 intmax_t 类型,且所有无符号整数常量都表现为如同有 uintmax_t 类型。

(C99 起)

整数常量可用于整数常量表达式

由于最大吞噬规则,以 eE 结束的十六进制整数常量在后随运算符 +- 时,源码中必须以空白符或括号将它们与运算符分隔:

int x = 0xE+2;   // 错误
int y = 0xa+2;   // OK
int z = 0xE +2;  // OK
int q = (0xE)+2; // OK

否则形成一个非法的预处理数字记号,这会进一步导致分析失败。

示例

#include <stdio.h>
#include <inttypes.h>
int main(void)
{
    printf("123 = %d\n", 123);
    printf("0123 = %d\n", 0123);
    printf("0x123 = %d\n", 0x123);
    printf("12345678901234567890ull = %llu\n", 12345678901234567890ull);
    // 类型为 64 位类型( unsigned long long 或可能的 unsigned long )
    // 即使无 long 后缀
    printf("12345678901234567890u = %"PRIu64"\n", 12345678901234567890u );
 
//  printf("%lld\n", -9223372036854775808); // 错误
// 值 9223372036854775808 不能适合 signed long long ,
// 它是无后缀十进制整数常量所允许的最大值
 
    printf("%llu\n", -9223372036854775808ull );
    // 应用到无符号值的一元减将它从 2^64 减去
    // 这给出无符号 9223372036854775808 
 
    printf("%lld\n", -9223372036854775807ull - 1);
    // 组成有符号值 -9223372036854775808 的正确方式
}

输出:

123 = 123
0123 = 83
0x123 = 291
12345678901234567890ull = 12345678901234567890
12345678901234567890u = 12345678901234567890
9223372036854775808
-9223372036854775808

引用

  • C17 标准(ISO/IEC 9899:2018):
  • 6.4.4.1 Integer constants (第 45-46 页)
  • C11 标准(ISO/IEC 9899:2011):
  • 6.4.4.1 Integer constants (第 62-64 页)
  • C99 标准(ISO/IEC 9899:1999):
  • 6.4.4.1 Integer constants (第 54-56 页)
  • C89/C90 标准(ISO/IEC 9899:1990):
  • 3.1.3.2 Integer constants

参阅