c语言基本类型大小不固定,char必为1字节但位宽可变,int仅规定范围;指针算术按所指类型大小缩放;枚举底层类型由编译器自选;typedef与struct标签名独立,匿名struct不可递归引用。

基本类型到底有哪些,char 和 int 的实际大小为什么不能硬记
标准只规定了最小取值范围,没规定具体字节数。比如 char 必须是 1 字节,但 1 字节不一定是 8 位(极少数嵌入式平台是 9 位);int 只要求不小于 short、不大于 long,常见是 4 字节,但在某些 16 位单片机上可能是 2 字节。
实操建议:
- 用
sizeof查实际大小,别依赖经验或文档截图 - 跨平台项目里,优先用
stdint.h中的int32_t、uint8_t等确定宽度的类型 -
char是唯一被标准明确定义为 1 字节的类型,可安全用于内存操作和字节计数
指针算术为什么总出错,int* 和 char* 移动 1 步差多少
指针加减整数时,编译器会按它所指类型的大小自动缩放步长。对 int* 来说,p + 1 实际偏移 sizeof(int) 字节;而 char* 加 1 就是加 1 字节 —— 这是 memcpy、memset 内部能逐字节操作的根本原因。
常见错误现象:
立即学习“C语言免费学习笔记(深入)”;
创想C2C商城系统,系统功能仿照淘宝设计,采用模块标签技术和静态html生成技术 基于Asp.Net/C#+SQL的开发的创想多用户商城系统,具有智能化、高扩展、稳定安全等特性,后台可自由添加频道,自由修改界面风格,商品无限级 分类,支持在线支付整合,通过安装和使用创想C2C商城系统,就可以轻松建立起专业大型的网上交易平台。创想C2C多用户商城系统5.6.3.8版本升级功能1.网站地区设置功能的增
- 把
void*直接做算术(C 标准不允许),GCC/Clang 会警告pointer of type 'void *' used in arithmetic - 误以为
int arr[5]; &arr[0] + 1和(char*)&arr[0] + 1偏移相同 - 结构体成员地址计算时,忽略对齐填充导致偏移量与预期不符
枚举值默认从 0 开始,但 enum 的底层类型到底是什么
标准只要求枚举类型能表示所有枚举常量,编译器可自由选择底层整型(int、unsigned int,甚至 short)。GCC 默认用 int,但若所有值都在 int16_t 范围内,可能优化为更小类型以节省空间。
实操建议:
- 需要控制大小或跨平台一致时,显式指定底层类型:C11 起支持
enum : uint16_t { A, B }; - 避免把枚举值直接当数组下标用,除非确认其值在合法范围内且无负数
- 调试时看到枚举变量显示为数字而非名称,多半是因为调试信息未启用或符号被 strip
typedef 和 struct 结合时,struct tag 和 typedef_name 是两个独立符号
写 typedef struct { int x; } point; 后,point 是类型名,但匿名 struct 本身没有标签名,无法在内部递归引用(比如定义链表节点)。而 typedef struct node { int val; struct node* next; } node; 中,struct node 和 node 是两个名字,指向同一类型,前者可在定义体内使用。
容易踩的坑:
- 只写
typedef struct { ... } name;,然后试图在结构体内写name* next;—— 编译失败,因为name在定义完成前不可见 - 重复定义同名
struct tag和typedef,在 C 中是允许的,但某些头文件保护不当会导致重定义警告 - 在头文件中用
typedef隐藏结构体实现(opaque pointer)时,必须确保声明和定义分离,否则用户无法sizeof或栈上分配
复杂点在于:类型系统不跟踪“怎么来的”,只认最终布局。同一个 struct 用不同 typedef 名声明多次,仍是同一类型;但哪怕字段完全一样,两个独立 struct 定义在 C 里也互不兼容。









