C语言:指向单个int变量的*p++=0是否为定义行为?array object解析
指向单个int变量时
*p++ = 0的行为分析 结论区分
- 若指针
p指向自动/静态声明的单个int变量(例如int x; int *p = &x;),执行*p++ = 0属于未定义行为。 - 若指针
p指向**malloc分配的单个int内存块**(例如int *p = malloc(sizeof(int));),执行*p++ = 0属于定义行为。
标准依据(C11/C23)
1. “array object”的定义
C标准中的array object包含两类:
- 显式声明为数组类型的对象(如
int arr[5];); - 通过
malloc等动态内存分配函数获取的连续内存块,这类内存会被视为一个元素个数为「总分配字节数 ÷ 单个元素字节数」的数组对象。
2. 指针算术的合法边界
C11标准(6.5.6 §8)对指针算术的合法范围做了明确限制:
指针的加减运算仅在以下场景下是定义行为:
- 指针指向数组对象的某个元素,运算结果指向该数组的其他元素,或是数组末尾的下一个位置;
- 指针指向非数组对象时,仅允许加减0(即指针始终指向原对象)。
具体场景解析
场景1:指向自动/静态单个int变量
单个标量变量不属于array object,此时p指向的是孤立的非数组对象。虽然*p = 0(给目标变量赋值)是合法操作,但p++会让指针偏移到原变量地址的下一个位置——这超出了指针算术的合法范围,因此整个表达式*p++ = 0的行为是未定义的。
场景2:指向malloc分配的单个int内存
malloc(sizeof(int))分配的内存被视为元素个数为1的array object,p初始指向该数组的唯一元素:
*p = 0是合法操作,对数组的唯一元素完成赋值;p++让指针指向数组末尾的下一个位置,完全符合标准允许的指针算术范围,运算结果是定义的。
因此整个表达式*p++ = 0的行为是完全合规的定义行为。
内容的提问来源于stack exchange,提问作者Kyle
相关产品推荐
相关产品推荐

