Week 1

C语言中的对象

一个对象一般有一个对象类型,标记为Type-name

完全对象类型:大小可知,分配后大小确定。
不完全对象类型:大小未知,分配后大小也确定。

所有对象类型在语义上都是整体的,对象类型在语法上不一定是整体的,如果一个Type-name在语法上整体,标记为T

对象各个bit组成的二进制串是这个对象的对象表示(Object Representation),对象的值和对象表示可以通过对象类型进行映射。

对象的值一样,对象表示不一定一样:bit包括Value Bits和若干无意义的Padding Bits,由对象类型决定。

sizeof(Type-name)
alignof(Type-name)规定了一个类型的确省对其要求

类型

Type

  • Arithmetic Type 算数类型
  • Derived Type 派生类型
  • Type-name with Qualifier 限定符修饰类型

对于语法上整体的类型T,typedef T Alias,Alias在语法上是一个整体。

数组派生:typedef typeof(int[5]) AINT; -> int[10][5] <==> AINT[10]

例:int[10][] & int[][10]
int[10][]中的元素类型是int[]不完全累对象类型,不合法。
int[][10]中元素类型T是int[10]。其本身是一个不完全对象类型,不能继续派生数组类型。

指针派生:typedef typeof(int[5]) AINT -> typeof(int[5])* <==> int(*)[5]

例:int(*[10])[5]是一个长度为10的数组,其中每个元素是一个指向长度为5的数组的指针。
其对应的指针类型是int(*(*)[10])[5]

例:int*(**(*)[])[4][5]?

限定符

  • _Atomic
  • const
  • volatile
  • restrict(只能限定对象指针类型,或其构成的多维数组类型)

给定一个类型T,给定一个限定符Q,其限定修饰类型为Q TT Q,语法上也是整体。

T和Q T(T Q)是两种不同的Type,但大小,表示值,对齐方式一样。

_Atomic限定修饰类型是原子类型,其他三种限定修饰类型统称为限定类型,都有称为原子限定类型。

对于语法上整体呈现的类型T:

  • Q T 等价于 T Q
  • Q T[N]:数组类型,N个Q T;T[N] Q:不合法
  • Q T*:指针类型,referenced type是Q T;T* Q:Q限定T*类型
限定类型形式 派生数组类型(N个元素) 派生指针类型 Q’ 限定修饰类型
QT QT[N] QT* QTQ’ / QQ’T / Q’QT
TQ TQ[N] TQ* TQQ’ / TQ’Q / Q’TQ
T*Q T*Q[N] TQ TQQ’ / TQ’Q

例:const int*(* const*)[4][5]?
例:const int* const?

typeof:

  • const typeof(int*[10]) <==> int* const[10]
  • const typeof(int*[5][10]) <==> int* const[5][10]

_Atomic(T) & _Atomic T:

  • _Atomic(T)是基于T派生的一个原子类型,T不能是数组类型,函数类型,限定类型和原子类型
  • _Atomic T是基于T的原子限定类型,T不能是数组类型,函数类型

Week 2

分配对象

1.对象标识符(Object Identifier)定义
2.String Literal(字符串字面量)
3.Compound Literal(复合字面量)
4.内存管理函数

对象标识符定义

一次定义多个对象标识符:T * Q O_1 Initializer, * Q O_2 Initializer,..., * O_n Initializer

例:int(*a)[10],(*b)[10]

Initialzier形式:除逗号表达式之外的任意表达式exp/花括号初始化器(Braced-Initializer)

  • 标量类型Initializer
    • {},空初始化列表->确省初始化
    • 除逗号表达式之外的任意表达式exp或{exp}
  • 数组类型Initializer
    • {},空初始化列表
    • {sub-initializer_1,sub-initializer_2,sub-initializer_n}
    • T[N]中N不存在,不能用{}初始化
    • 变长数组只能用{}初始化

例:
int a[2][3] = {{1,2},{3,4,5}} <> {{1,2,0},{3,4,5}}
int a[2][3] = {1,2,3,4} <
> {{1,2,3},{4,0,0}}
int a[10] = {[3] = 5}(Designated Initializer)

无Initializer时(如int a;),a被称为indeterminate representation,但实际上这个值是确定的,不确定只是从程序员视角而言

对象六元组模型

Object = {
Address,
Obj_Type,
Name,
Size,
Obj_value,
Alignment,
}

例:char b='a';``int* p;``int* p=NULL;``int c[2];``int c[2]={1,2}``const int e[2][3]的对象六元组?

例:定义一个对象int* f[2][3][4]={},对象f的Object_Type是什么?这个数组对象的元素对象类型是什么?元素对象对应的指针类型是什么?
int*[2][3][4]``int*[3][4]``int*(*)[3][4]

通过字符串字面量(String Literal)

encoding-prefix"s-char-sequence"

五种编码前缀:无编码、u8、u、U、L

编码前缀 元素字符对象类型 编码规则
u8 char8_t UTF-8
u char16_t UTF-16
U char32_t UTF-32
L wchar_t 实现定义

四种对象存储周期:static,automatic,allocated,thread

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(int argc, char* argv[]) {
"hello";
"hello";

return 0;
}

//第一个“hello”会分配一个字符数组对象,第二个“hello”不确定

int main(int argc, char* argv[]) {
"hello";
L"hello";

return 0;
}

//第一个“hello”对象类型是char[6],第二个“hello”对象类型是wchar_t[6]

通过复合字面量(Compound Literal)

(storage-class-specifiers type-name) Braced-Initializer

例:(int[]){1,2}

通过内存管理函数

内存管理函数:aligned_alloc,calloc,malloc,realloc

例:malloc(16)

定位对象

表达式,lvavlue,evaluate,rvalue

C语言中一共17种表达式,Evaluate优先级从上往下依次降低。
表达式需要根据语法的规定来进行Evaluate,包括:Value Computation, Initiation of Side Effect.
Value Computation得出表达式的rvalue,及其value of expression

对象定义T O = Initializer,其中的O就是对象标识符。表达式中的对象标识符都是合法的lvalue

  • lvalue表达式定位的对象类型
    • 数组对象类型
      • 普通数组对象类型
      • 变长数组对象类型
    • 非数组对象类型

lvalue表达式Evaluate规则

1.lvalue conversion:如果lvalue定位的对象是一个非数组类型对象,则rvalue就是该对象的对象值
2.Decay:如果lvalue定位的对象是一个数组类型对象,则rvalue就是该对象第一个元素的首地址,rvalue类型是元素对象类型对应的指针类型

例:int a={};,rvalue是0,rvalue type是int
const int a={},rvalue是0,rvalue type是int
int b[1]={},rvalue是Address,rvalue type是int*
const int b[1]={},rvalue是Address,rvalue type是const int*
int d[1][1],rvalue是Address,rvalue type是int()[1]
int n=1;int e[1][n]={},rvalue是Address,rvalue type是int(
)[n]

lvalue的对象值 & lvalue的右值

lvalue的对象值:lvalue定位对象的对象值
lvalue的右值:lvalue这个表达式如果被求值得到的右值

例:int a=0;int b[1]={1}
a的对象值是0,b的对象值是{1}
a的右值是0,b的右值是b第一个元素的地址