Skip to content
GitHub

C Number

int main(void) {
    short int short_int = 1;
    int normal_int = 2;
    long int long_int = 3;

    printf("size of short  int: %zu\n", sizeof(short_int));
    printf("size of normal int: %zu\n", sizeof(normal_int));
    printf("size of long   int: %zu\n", sizeof(long_int));
}

size of short int : 2
size of normal int: 4
size of long int  : 8

sizeof : 返回变量占用的存储大小(单位: 字节)

关键字signedunsigned
含义有符号(包含负数, 默认值)无符号(从 0 开始, 不包含负数)
int num = 2;                                     // 省略 signed, 默认有符号
signed num = 2;                                  // 省略 int, int 可以省略
signed int num = 2;                              // 全写, 与上述两种声明效果一致

unsigned short x;                                // unsigned short int; 省略 int
long y;                                          // unsigned long int; 省略 signed 和 int
类型大小范围
signed short int2 个字节 (16 位)-(2^15) ~ (2^15)-1
unsigned short int2 个字节 (16 位)0 ~ (2^16)-1
signed int4 个字节 (32 位)-(2^31) ~ (2^31)-1
unsigned int4 个字节 (32 位)0 ~ (2^32)-1
signed long int8 个字节 (64 位)-(2^63) ~ (2^63)-1
unsigned long int8 个字节 (64 位)0 ~ (2^64)-1

C 语言最值的定义 /usr/include/limits.h

/* Minimum and maximum values a `signed short int' can hold.  */
#  define SHRT_MIN      (-32768)
#  define SHRT_MAX      32767

/* Maximum value an `unsigned short int' can hold.  (Minimum is 0.)  */
#  define USHRT_MAX     65535

/* Minimum and maximum values a `signed int' can hold.  */
#  define INT_MIN       (-INT_MAX - 1)
#  define INT_MAX       2147483647

/* Maximum value an `unsigned int' can hold.  (Minimum is 0.)  */
#  define UINT_MAX      4294967295U

/* Minimum and maximum values a `signed long int' can hold.  */
#  if __WORDSIZE == 64
#   define LONG_MAX     9223372036854775807L
#  else
#   define LONG_MAX     2147483647L
#  endif
#  define LONG_MIN      (-LONG_MAX - 1L)

/* Maximum value an `unsigned long int' can hold.  (Minimum is 0.)  */
#  if __WORDSIZE == 64
#   define ULONG_MAX    18446744073709551615UL
#  else
#   define ULONG_MAX    4294967295UL
#  endif

引入头文件, 通过变量名使用最值

#include <limits.h>

printf("signed short int min  : %d \n", SHRT_MIN);
printf("signed short int max  : %d \n", SHRT_MAX);
printf("signed int min        : %d \n", INT_MIN);
printf("signed int max        : %d \n", INT_MAX);
printf("signed long int min   : %ld \n", LONG_MIN);
printf("signed long int max   : %ld \n", LONG_MAX);
printf("\n");
printf("unsigned short int max: %d \n", USHRT_MAX);
printf("unsigned int       max: %u \n", UINT_MAX);
printf("unsigned long int  max: %lu \n", ULONG_MAX);

> signed short int min  : -32768
> signed short int max  : 32767
> signed int min        : -2147483648            // 占位符对应类型,也有范围
> signed int max        : 2147483647             // 变量只超出占位符范围会溢出,打印错误值
> signed long int min   : -9223372036854775808   // long 超出 %d 范围,需要使用 long 整形占位符 %ld
> signed long int max   : 9223372036854775807    // %d 的范围即为 signed int 的范围

> unsigned short int max: 65535
> unsigned int       max: 4294967295             // 超出 signed 范围, 使用 %u 无符号整型
> unsigned long int  max: 18446744073709551615   // 超出 signed long 范围, 使用 %lu 无符号长整型
printf("long int: %d \n", LONG_MAX);             // long 范围超出 %d 范围
> long int: -1                                   // 溢出, 打印错误
int bin = 0b10;                                  // 二进制 (低版本编译器不支持)
int oct = 010;                                   // 八进制, 0 开头
int ten = 10;                                    // 十进制
int hex = 0x10;                                  // 十六进制

printf("    oct  dec  hex \n");
printf("bin %2o  %2d  %2x \n", bin, bin, bin);
printf("oct %2o  %2d  %2x \n", oct, oct, oct);   // %o  八进制形式打印
printf("dec %2o  %2d  %2x \n", ten, ten, ten);   // %d 十进制形式打印
printf("hex %2o  %2d  %2x \n", hex, hex, hex);   // %x 十六进制形式打印

>     oct  dec  hex
> bin  2   2   2
> oct 10   8   8
> dec 12  10   a
> hex 20  16  10

浮点数的存储方式与整数不一致,浮点数采用科学计数法存储浮点数

float = (+/-) (1 + 尾数) * (2^指数)

类型符号位指数位尾数
float1 位(31)8 位(23-30)23 位(0-22)
double1 位(63)11 位(52-62)52 位(0-52)

指数(8 位): 2 的指数(-128 ~ 127), 决定范围 尾数(23 位): 小数点后的数值(0 ~ 1), 决定精度

最大值(符号取正, 尾数接近 1, 指数 127): (+1)(1+1) 2^127 = 2^128 精度: 8388608(2^23), 共 7 位, 第 7 位未能覆盖, 所以仅能保证 6 位

float f = 3;
printf("float %f size: %zu \n", f, sizeof(f));
> float 3.000000 size: 4

printf("float %.20f \n", 0.1+0.2);               // 打印浮点数小数点后 20 位
> float 0.30000000000000004441                   // 浮点数精度问题, 0.1+0.2 != 0.3

数字类型之间可以互相转换, 转换的前后类型包含关系可能会导致精度损失或类型溢出

float e = 2.718;
int num = e;                                     // 浮点型转整形
printf("num: %d\n", num);
> num: 2                                         // 小数部分丢失

int num = 32768;
short s_num = num;                               // int 转 short int, signed short int (-32768, 32767)
printf("num: %d\n", s_num);
> num: -32768                                    // 数值溢出, 可能导致意想不到的问题

显式转换: (type)variable

int num = 3;
printf("num: %f\n", (float)num);                 // num 强制转为 float 类型
> num: 3.000000

C99 标准开始添加 stdbool.h 引入了 _Bool 类型 布尔类型本质还是 0 和 1

#define bool _Bool
#define true 1
#define false 0
bool normal;
bool flag = true;
printf("bool normal: %d \n", normal);
printf("bool flag  : %d \n", flag);

> bool normal: 0
> bool flag  : 1