c语言变量必须显式声明类型,无默认类型;typedef仅为类型别名,不提供类型安全;printf/scanf格式符须严格匹配实际类型;sizeof是编译期运算符,不能测动态内存大小。

变量声明必须显式指定类型,不能省略
C语言里没有“默认类型”这回事,int 不是可选的,更不是隐式的。写 a = 5; 直接报错——编译器根本不知道 a 是什么。声明必须带类型,比如 int a;、float x;、char flag;。
常见错误现象:error: 'xxx' undeclared (first use in this function),往往不是漏写了变量,而是压根没声明。
- 函数内部定义的变量,作用域仅限该函数,不能靠“先用后声明”蒙混过关
-
long long和short这类修饰词必须和基础类型(如int)连用,单独写long或short是非法的 - 全局变量虽会默认初始化为 0,但局部变量不初始化就是垃圾值——别指望它“大概率是 0”
typedef 不是创建新类型,只是给已有类型起别名
typedef 看起来像定义类型,实际只是 alias。比如 typedef int myint; 之后,myint x; 等价于 int x;,二者在 sizeof、函数参数传递、指针运算中完全一致。
容易踩的坑:typedef 容易让人误以为能绕过类型检查。例如:
立即学习“C语言免费学习笔记(深入)”;
typedef int status_t; typedef int error_t; status_t s = 0; error_t e = -1; s = e; // 合法!编译器根本不区分这两个名字
这不是类型安全,只是换了个名字。真要隔离语义,得用 struct 封装 + 函数接口,而不是靠 typedef。
-
typedef声明的别名不能用于声明数组长度或结构体成员位宽(比如typedef int len_t;后不能写char buf[len_t];) - 和
#define混用时尤其危险:#define INT int和typedef int INT;表面一样,但后者受作用域限制,前者全局替换,可能破坏后续声明
printf/scanf 的格式符必须和变量类型严格匹配
写 printf("%d", 3.14); 或 scanf("%f", &n);(n 是 int)不是“大概能跑”,而是未定义行为:可能输出乱码、崩溃、或者看似正常实则踩内存。
关键点在于:格式符描述的是“你告诉函数的数据类型”,不是“你希望它怎么解释”。%d 要求传入的是 int 对应的二进制比特,不是“一个整数概念”。
-
long用%ld,long long用%lld(Windows 下可能是%I64d,注意平台差异) - 指针地址统一用
%p,且必须传void*;直接传&x(x是int)没问题,但传(int*)&x就错 -
char变量用%hhd打印(%d会提升为int,可能显示负数异常),输入用%c读单字符,%s读字符串(注意缓冲区溢出)
sizeof 是编译期运算符,不是函数,括号只在必要时才加
sizeof 在编译阶段就确定结果,不产生运行时开销。写 sizeof(int) 或 sizeof x 都行,但 sizeof(x) 更易读,尤其当 x 是表达式时(如 sizeof arr[0])。
常见误解:以为 sizeof 能测动态分配内存大小。错。int *p = malloc(100); printf("%zu", sizeof(p)); 输出的是指针大小(通常是 8),不是 100。
- 数组名作为参数传给函数后退化为指针,
sizeof在函数内对其求值永远是指针大小,不是原数组长度 -
sizeof对void类型非法,但sizeof(void*)合法 - 结构体
sizeof结果包含填充字节,不能简单累加成员sizeof—— 对齐规则(如_Alignof)直接影响结果
类型对齐和填充是真正容易被忽略的复杂点。同一段结构体定义,在不同平台、不同编译器选项下,sizeof 可能不同,而你写的序列化或网络传输代码,很可能就卡在这里。










