对象 (Object)
1. 概念
执行环境中数据 (Data) 存储的一个区域,其内容可以表示值 (Value)。
在 C 语言语义里,对象不是“名字”,而是“那块存储本身”。同一个对象可以被不同表达式访问,也可以暂时没有可见标识符(例如通过指针间接访问,或在复合字面量中创建)。把“对象”和“标识符”分开理解,是后续学习作用域、生存期、链接属性和对象表示的前提。
2. 对象的关键属性
每个对象至少包含三组关键属性:类型、存储期和值。类型决定这段存储如何被解释,存储期决定它何时创建与销毁,值表示当前状态。后续章节会继续展开对齐、对象表示和限定符;在本节先建立一个简单原则:程序真正操作的是对象,而不是名字。
3. 对象与标识符
标识符是源代码中的记号;对象是执行期实体。二者常常一一对应,但并不总是如此。结构体成员并不是独立的顶层标识符,却仍然对应对象;malloc 返回的存储区在按某种类型访问后,也会纳入对象语义体系。
#include <stdio.h>
int main(void) {
int a = 10;
int *p = &a;
*p += 5;
printf("a = %d\n", a);
return 0;
}2
3
4
5
6
7
8
9
10
可能的输出(示例):
<输出与输入或平台相关,请以实际运行为准>
这段代码中,a 和 p 都是对象;a 与 *p 指向同一块整型存储。a、p 只是访问入口,真正变化的是对象内部状态。
4. 对象的创建与结束
自动存储期对象通常在进入块时创建、离开块时结束;静态存储期对象贯穿整个程序生命周期;线程存储期对象与线程同寿命;动态分配存储由 malloc 一族函数管理,并通过 free 显式释放。
#include <stdio.h>
#include <stdlib.h>
static int counter = 0;
void step(void) {
int local = 1;
int *heap = malloc(sizeof *heap);
if (heap == NULL) {
return;
}
*heap = 2;
counter += local + *heap;
printf("counter = %d\n", counter);
free(heap);
}
int main(void) {
step();
step();
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
可能的输出(示例):
<输出与输入或平台相关,请以实际运行为准>
local 每次调用 step 都会重新创建;counter 在程序结束前一直存在;heap 指向的存储必须配对释放。这个区分直接关系到内存安全与接口设计。
5. 对象状态与不确定值
对象创建后并不总是立即处于可读取状态。自动存储期对象若未初始化,读取其值通常没有语义保障;动态分配存储在写入前也不应被当作已有有效值。理解“对象已存在”不等于“对象已有可用状态”,是避免未定义行为的基础前提。
6. 从对象视角组织接口
当函数接口以对象为中心设计时,边界会更清晰:谁负责创建,谁负责释放,谁可以修改,谁只读访问。相比只看函数名,把这四个问题写清楚,模块协作会稳定很多。后续学习限定符、对齐和对象表示时,也都可以回到这个视角继续深化。