1.const声明的变量为常量变量,意为readonly 告诉编译器此变量不可修改,若修改则导致编译失败
2.函数声明又叫函数原型 例如 int function(); 只声明,不实现
3.include、define为预处理指令,gcc -E 可以只进行预编译,可以看到define为文本替换
4.数组名传递、指针传递可以达到引用传递的结果,但是事实上c语言的函数参数所有都为传值。
5.字符串以/0|null为结尾,因此“hello”长度为6
6.&&条件检查,以先左后右的方式进行
7. gcc是包含了预编译、编译器、汇编器、连接器的工具集,hello.c的文件编译为可执行文件需要先经过gcc -E 进行预编译,然后通过cc工具进行编译成目标文件,通过汇编器as编译成二进制文件,再通过ld工具将各个目标文件链接起来对全局变量、函数等进行地址重定向,决定最终的地址后生成可执行文件
8. c语言只有四种数据类型,整型、浮点型、指针、聚合类型(数组、结构体),其中枚举也属于整型,
9. c语言作用域分为文件作用域、代码块作用域、原型作用域(函数声明)、函数作用域。
10.链接属性为三种:none(没有链接属性的标识符被当做不同的个体)、external(跨文件的相同标识符被认为是同一个实体)、internal(单个文件内部的同一名称变量指向同一个实体)
可以通过static来改变标识符的链接属性,比如声明的全局变量 可以通过static变为internal的链接属性
11.存储类型有普通内存、运行时堆栈、硬件寄存器
凡是在任何代码块之外声明的变量总是存储在静态内存中,或代码块内部加上static后也会存储在静态存储区,这些变量被称为静态变量,是在进程初始化(可执行文件加载到内存中去的时候)
代码块内部的普通变量、动态申请的空间会放到运行时堆栈中,自动变量总是动态生成的
register声明的变量 编译器会推荐放入硬件寄存器中
12.static这个关键字比较迷惑 如果是作用在函数、全局变量 是修改其链接作用域,即只能本文件访问
如果作用在代码块内的变量上,则是修改其存储类型为静态存储
13.可以通过do{if xxx{break;}}while(0),来实现break掉已有流程
14.赋值过程为自右向左 a = b = c + 2
15.要区分左值和右值,左值才可以被赋值 左值是一个可以被标记的位置
16.移位有逻辑移位、算数移位,其中算数移位可能存在有符号数移位问题
左移其实都是逻辑左移,符号位不变,高位移出后面补0
逻辑右移不保存符号,低位移出,高位补0;算术右移若符号位为1则左边补1,否则补0
a = a >> 10 这样才能得到移位后的值
17.指针是一个变量,必须要初始化,否则就是个野指针,对野指针指向地址赋值是未定义的
18.++p先加++p后访问p,p++先访p问后p++
19.int *p = &a[0] || int *p = a 其中a为int类型数组 注意不是int *p = a[0] a[0]是个整数类型,类型不符合
20.c语言支持可变参数 int function(int n_values, …) 通过va_arg、va_list、va_start来获取变量
21.数组名为指针常量 这也解释了c语言中只有值传递
22.多维数组可以第一维自动推断 int matrix[][5] = {…}
23.指针比下标的效率高,但更容易出错 不要以可读性换性能
24.sizeof一个指针 是4/8个字节,取决于编译器和计算机 sizeof一个数组名 就是数组类型 * 长度
25.复制字符串 必须要考虑目的地址和原地址是否有重叠的可能
26.struct {int x; int y} abc; 声明了一个结构体变量abc,abc有两个int类型变量
27.结构体中内存布局一般要保证字节对齐,这是因为cpu一次读取一个cache line,跨cache line存储导致多次读存储cache、甚至读内存导致性能下降,是典型的以空间换时间的做法,也可以强制不进行内存对齐 使用#program pack(xxx)。内存对齐的规则是 A.变量的存储起始地址是变量字节数的整数倍,例如char类型 起始地址是1的倍数,short是2的倍数才行 int是4的倍数 B.总体大小要能被最长类型变量整除 C.如果结构体中有嵌套其他结构体 嵌套的结构体的起始地址需要是其最长长度的变量地址的整数倍 因此struct {char a; short b; int c; char d;} 这个结构体占用 1x1111111xxx 其中x为填充
28.union结构存储长度为最长成员
29.malloc申请的是一段连续的虚拟地址空间,是申请了字节数的空间,若失败则返回NULL
calloc是申请若干元素、元素指定大小的地址空间,会将空间清零,失败返回NULL
realloc根据原始地址指向内存大小和new_size判断,若new_size小则对原空间进行收缩,若new_size大则看原空间是否有连续空闲地址有则向后继续申请,无则换一个能装下的地址,返回新空间的地址,失败则返回NULL
30.define与undef对应,是宏的定义;在编译的预处理阶段进行处理,不做类型分析仅仅是字符替换,因此比函数效率高、快;使用宏定义注意多加括号保证展开后是正确的
31.include指令 后面如果是""文件 则先查找本地文件,再查找库文件 若是<>则仅查找库文件
32.信号又叫软中断信号,是软件层次上对中断机制的模拟,是进程间通信的唯一的异步通信机制
32.signal提供注册特定信号的回调函数,可捕捉信号有SIGINT、SIGQUIT(kill -3)、SITTSTP、SIGUSR、SIGCHLD等
不可忽略的信号为SIGSTOP、SIGKILL,同时这两个信号不可捕获