Skip to content

对象属性、对象分配

可修改左值是从我们程序员的视角看的, 但内存是否会修改是另一回事, 有可能是未定义行为

对象属性: 物理属性

截屏2025-10-15 20.41.04

  • 对象类型 (Object Type): T
  • 对象名称 (Object Name): O
    • 有名称的对象被称为具名对象, 反之则是匿名对象 (Unnamed Object)
  • 大小 (size):
    • 连续字节的个数, 通过 sizeof(T) 获得
    • 假设常用类型大小为: char 1, short 2, int 4, float 4, double 8, pointer type 4
  • 地址 (Address) 和对齐要求 (Alignment):
    • 对象地址由系统确定
    • 地址要满足对齐要求, 即 alignof(T)
  • 对象值和对象表示: 映射

分配对象: 对象定义

[!summary] 分配对象的方法: 1. 对象定义 2. String Literal (字符串) 3. Compound Literal 4. 内存管理函数 (malloc)

Storage-class specifiers T O = initializer;

截屏2025-10-15 20.43.52

  • 分配了一个 T 类型的对象, T 要看成整体
  • 声明一个对象标识符 O , 让 O 与这个对象关联起来
  • initializer 初始化这个对象的对象表示. 如果没有 initializer, 则不构成对象定义
  • Storage-class specifiers 指定对象存储周期

TT[N]T*

截屏2025-10-15 20.47.52

比如:

int b[10] = {0};
int *c = NULL;

一次定义多个对象

截屏2025-10-15 20.51.26

  • T 需要是整体

一次定义多个 const 类型对象:

截屏2025-10-15 20.56.15

标量类型对象的 initializer

标量类型:

截屏2025-10-15 21.00.55

initializer:

截屏2025-10-15 21.02.09

  • {} 将对象的值设置成该类型的缺省值 (0, 空指针)
  • {exp} 表达式求值之后的右值用来初始化对象表示
    • 很神奇, 居然可以这样
int a = {1+2};
printf("%d\n", a);

完整的 initializer 就是对象的对象值 (Object Value)

数组类型对象的 initializer

截屏2025-10-15 21.05.09

  • 当数组是普通数组, 可以: {[constant-expression-i]=initializer-i, ...} 设定第 i 个元素的值
    • 试了一下会报错呀?
  • N 不存在: 截屏2025-10-15 21.06.31

  • 当数组是变长数组:

    截屏2025-10-15 21.06.59

若没有 initializer

int a 这个问题和 scope 的 linkage 有关:

  1. 在某些情况下, int a 是一个对象定义, 且值是确定的
  2. 在某些情况下, int a 是一个对象定义, 但值不确定
  3. 在某些情况下, int a 不是一个对象定义, 只是一个标识符声明

此时的 Object Value ?

1
2
3
4
int main() {
    int a;
    return 0;
}
  • 这里对象 a 的对象表示被称为 indeterminate representation
  • 对象 a 的对象值也可称为 indeterminate 不确定的
  • (其实从硬件角度上是确定的, 就是 0 或 1, 但是我们程序员不知道)

对象属性: 逻辑属性

截屏2025-10-15 21.17.23

表示值表示值类型:

截屏2025-10-15 21.19.40

获取规则:

截屏2025-10-15 21.20.57

对象七元组模型

截屏2025-10-15 21.24.39

分配对象: 通过 String Literal

String Literal: 编码前缀 + 双引号引导的字符序列

  • 5 种编码前缀: 无编码、u8、u、U、L. 例如: "hello" u8"hello" u"hello" U"hello" L"hello"
  • 所有 String Literal 具有静态存储周期 (有效期覆盖整个程序运行时间, 可初始化为缺省值)

C语言定义了 4 种对象存储周期 - static, automatic, allocated, thread - automatic 相当于栈, allocated 相当于堆 - 存储周期决定了对象的有效期

"hello" 分配对象

截屏2025-10-15 21.40.06

其他前缀

截屏2025-10-15 21.45.20

  • 有中文一定要前缀, 否则存在跨平台问题

String Literal 和 String

String 的 "" 内不能有 \0