应根据场景选择整型:int平台相关,需确定大小时用int32_t等;char是1字节整型,二进制数据优先unsigned char;浮点数存在精度问题,金融计算禁用,比较需用误差范围而非==。

整型怎么选:int、short、long 不是随便写的
选错整型最直接的后果是溢出或浪费内存,比如用 int 存年龄没问题,但存 Unix 时间戳(2038 年后)在 32 位系统上就会翻车;又比如嵌入式里反复定义 long long 而不必要,会拖慢寄存器操作。
-
int是“平台友好型”——它不固定占 4 字节,C 标准只要求 ≥16 位;实际中多数编译器给 32 位,但不能硬编码假设 - 需要确定大小时,优先用
int32_t、uint16_t(需#include <stdint.h></stdint.h>),而不是靠long猜 -
char本质是 1 字节整型,可参与算术运算;unsigned char处理二进制数据(如图像像素、网络包)更安全,避免符号扩展
浮点型不是“小数万能解”,精度和比较要小心
float 和 double 的底层是 IEEE 754 表示,很多十进制小数根本无法精确存储,比如 0.1 + 0.2 != 0.3 是常态,不是 bug。
- 金融计算别用浮点——该用整型 cents 存,或引入定点数库
- 比较两个浮点数是否“相等”,永远别写
a == b,改用fabs(a - b) (<code>EPS通常取1e-6或1e-9,视量级而定) -
double在 x86-64 上通常比float快(FPU 寄存器原生双精度),除非显式做float向量化或内存受限
void 类型不是“没类型”,而是“类型未指定”的契约
void 本身不能定义变量(void x; 非法),它的意义全在接口契约里:函数返回值为 void 表示不返回;参数为 void 表示不接受任何参数(func(void) ≠ func());void* 是通用指针,但解引用前必须强转。
-
malloc返回void*,在 C 中可直接赋给任意指针(如int* p = malloc(4);),但 C++ 不行——这是常见跨语言移植坑 - 函数声明写成
func()表示参数个数不确定(类似printf),而func(void)才真表示“一个参数都不接受” - 把
void*当作“万能容器”传参时,调用方必须知道原始类型,否则强转错误不会报编译错误,只会在运行时崩
字符型常被当成“字符串”,但 char[] 和 char* 语义完全不同
char 是整型,char* 是地址,char[] 是连续内存块——三者混用是缓冲区溢出、野指针、字符串截断的根源。
立即学习“C语言免费学习笔记(深入)”;
- 字面量
"hello"是 constchar[6],存在只读段;把它赋给char* p = "hello";后再p[0] = 'H'会触发段错误 - 用
strcpy前必须确保目标空间足够,且源以'\0'结尾;更安全用strncpy或 C11 的strcpy_s(需定义__STDC_WANT_LIB_EXT1__) - 处理单字节 ASCII 没问题,但中文等多字节字符要用
unsigned char+ UTF-8 编码逻辑,别拿char直接当字符串遍历
类型不是语法装饰,是内存布局、ABI 兼容性和边界行为的总和。哪怕只是改一个 int 成 size_t,也可能让 64 位系统上的 malloc 参数溢出静默失效。










