Skip to content

C语言重点总结

指针

就 c 语言的数组与函数, 我有一定理解, 总结如下 a[i]==i[a]==*(a+i) ()为根据地址执行指令

type&action object function array
值/name 函数地址 首元素地址
& 变量地址 函数地址 数组地址
* 值所代表的地址上的值 函数地址 首元素
sizeof type'size no (sizeof type)*length

c 与 c++

  • C++认为 int fun()==int fun(void), C 认为只是省略了
  • C 的 char 常量'a'是 int 类型, 因此'ABCD'不会报错
  • C++的 const 变量默认是内部链接, 可以用 extern 改为外部链接
  • C++const 变量可以初始化 const, C 不行
  • C++严格使用枚举, C 将之认定为整型
  • C++原生宽字符, C 原生复数
  • C++11 没有初始化器, restric, VLA, 伸缩型数组成员, 可变数量参数的宏
  • c 标记名与变量名可以重复, c++不行
  • molloc 在 C++中必须强制类型转换
  • C 警告将 const 指针赋给普通指针, C++error
  • C++可以用 const 整型声明数组大小
  • C++可以 type(name)强制类型转换
  • C++不可调用 main()现在 C 也不行了
  • C 可以 char[3]="asd"

以上受时间影响, 仅供参考

声明

构成:type name+修饰符 不讨论 const extern 等

修饰符有三种:

  • 后置有[]与(), 优先级相同, 自左向右结合 当然, 这是对规律的总结, 实际上它们不是运算符, 没有优先级与结合律
  • 前置* 优先级小于后置, 因此我们声明数组与函数的指针必须使用()

将修饰符与 name 结合, 理解它的类型 最后你会发现, 如果你将以上三种符号认为是运算符形式, 那么你得到的是一个表达式, 而前面的 type 就是表达式值的类型

链接数组

这是一个值得被单独拿出来说的事情 在链接阶段跨文件使用一个全局数组的时候 不能 extern 一个指针 (反之函数形参可以) 因为链接变量是指出 a 的地址 (由另一个文件定义), 当你把一个数组声明为对应元素的指针, 会认为数组地址存储的那个值是指针的值, 本质原因是数组的值虽然是首元素的指针, 但没有使用额外的空间存储, 程序会访问未知的内存

增补

sizeof(void)=1 (gcc)
sizeof("hello")=6
sizeof('a')=sizeof(int)

C 标准中的概念

  • 1byte >= 8bit
  • 函数最少支持 31 个参数
  • 一条代码行里至少可以有 509 个字符
  • 表达式中, 至少支持 32 层嵌套()
  • 至少 257 个 case
  • 对象指一个或多个字节, 这些字节的二进制值为对象表示, 对象表示中可能含有填充

对象类型

  • 大小与对齐要求
  • 算术类型, 标准有符号整数类型大概率没有填充
  • _BitInt(n) 类似 n 位有符号整数类型, 但可能有填充
  • 无符号去掉符号位
  • 派生类型:数组/函数(不是对象类型)/指针/结构/联合/原子
  • 数组类型, T[n], 要求 T 是完全对象类型, T[]为不完全对象类型, 若 N 为整数常量/整数常量表达式, 则 T[n]为普通数组类型, 否则为变长度数组类型
  • 指针类型
  • 限定类型, const/volatile/restrict(只能修饰指针/指针多维数组, 含义仅我所有)/_Atomic
  • 算术类型与指针类型(包括 nullptr_t)及其限定类型为标量类型
  • 初始化: name={};name=值;name=除,表达式外的任何 16 种表达式
  • 具名对象与匿名对象
  • 对象属性:地址/类型/对齐要求/大小/表示值/表示类型/对象名称
  • 分配对象的方式:声明/字符串/内存管理/复合字面量