整型常量需按进制规范书写:十进制不加前缀,超int_max须加l/ll;八进制以0开头且仅含0–7;十六进制用0x/0x,推荐大写字母;无符号数显式加u;char符号性不固定,应明确使用signed char或unsigned char;浮点数遵循ieee 754,比较时禁用==而用fabs(a-b)。

整型常量怎么写才不会被编译器当错?
整型常量写错最常见的是进制混淆和后缀缺失。比如 0123 看起来像一百二十三,实际是八进制(以 0 开头),值为 83;0xABC 没问题,但 0Xabc 在老编译器里可能报错(大小写敏感性不一);更大的数如 10000000000(100亿)在 32 位 int 上会溢出,必须加 LL 后缀变成 10000000000LL 才能进 long long。
实操建议:
立即学习“C语言免费学习笔记(深入)”;
-
十进制不加前缀,但超INT_MAX(通常是 2147483647)就得手动加L或LL -
八进制必须以0开头,且只含0–7,08、09直接编译失败 -
十六进制用0x或0X,字母推荐大写(0xFF比0xff更易读,也避开了某些嵌入式工具链的大小写处理 bug) - 带符号性要显式控制:无符号常量加
U,比如65535U强制进unsigned int,避免和负数比较时发生意外提升
char 类型到底是 signed 还是 unsigned?
这不是语言标准规定的,而是由编译器和平台决定的。GCC 在 x86_64 Linux 默认是 signed char,但 ARM Cortex-M 的裸机编译器(如 arm-none-eabi-gcc)常默认 unsigned char。这意味着同样一段代码:char c = 0xFF; printf("%d\n", c);,在前者输出 -1,后者输出 255。
实操建议:
立即学习“C语言免费学习笔记(深入)”;
- 绝不要依赖
char的默认符号性——需要小整数时,明确用signed char或unsigned char - 做字节操作(比如解析网络包、内存拷贝)一律用
unsigned char,避免高位为 1 时符号扩展污染计算 - 数组索引、计数器场景下,
unsigned char可多表示一个正数(0–255),但要注意u_char i = 0; i--;会绕回 255,不是 -1
float 和 double 在内存里长什么样?
C 标准只要求 float 至少 32 位、double 至少 64 位,但几乎所有现代平台都遵循 IEEE 754。这意味着 float 是 1-8-23 结构(符号-指数-尾数),double 是 1-11-52。关键点在于:它们存储的是二进制浮点,不是十进制——所以 0.1 + 0.2 != 0.3 是必然结果,不是 bug。
实操建议:
立即学习“C语言免费学习笔记(深入)”;
- 比较浮点数别用
==,用fabs(a - b) ,其中 <code>EPS要匹配类型:对float用1e-6F,double用1e-12 - 整数范围安全上限:能精确表示的连续整数,
float最高到16777216(2²⁴),double到9007199254740992(2⁵³);超过就“丢精度”,比如(float)16777217 == (float)16777216为真 - 结构体里混用
float和int时注意对齐:很多平台要求float4 字节对齐,double8 字节对齐,字段顺序不当会悄悄增加 padding
变量声明时加 const 和不加,存储位置真不一样?
不一定。加 const 只是告诉编译器“这个值不该被改”,不强制进只读段。比如 const int x = 5;,GCC 常把它优化成立即数,根本不出现在数据段;但 const int arr[] = {1,2,3}; 就大概率放进 .rodata,尝试 *(int*)&arr[0] = 99; 会在运行时报 Segmentation fault(取决于 OS 是否启用写保护)。
实操建议:
立即学习“C语言免费学习笔记(深入)”;
-
const本质是编译期契约,不是运行期保护。想真正防改,得靠链接脚本或__attribute__((section(".my_rodata")))配合 MMU 设置 - 全局
const变量默认有内部链接(static效果),如果要在多个文件用,得加extern const int X;声明 + 一个定义(不加extern) - 指针的
const位置很关键:const char *p表示内容不可改,char * const p表示指针地址不可改,const char * const p两者都不可改——漏掉任一const都可能让函数接口语义变弱
事情说清了就结束。最麻烦的其实是跨平台移植时,同一份代码在不同编译器下对 char 符号性、enum 底层类型、sizeof(long) 的处理差异——这些不会报错,但会让数值逻辑突然翻车。










