C语言系统级编程
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 T或T 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 | int main(int argc, char* argv[]) { |
通过复合字面量(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第一个元素的地址
