1.c标准的指导思想
指导思想:相信程序员。让我想到,C语言提供的指针以及对内存的操作。提供了便利的同时也提供了安全隐患。
2.链接器和编译器
链接器的作用:将系统的标准启动文件、目标代码和库代码 结合在一起,存放在单个文件,即可执行文件中。
程序源码从高级语言到机器语言的过程中离不开编译器。多个.o文件链接成一个可执行文件的过程中,也离不开链接器。现代的IDE一般都集成了编译器和链接器。点击“编译”按钮,进行编译,点击“构建”按钮就进行链接。
编译器:
为什么需要编译器,可以参考笔者 这篇博文:深入理解计算机系统,源码到可执行文件翻译过程:预处理、编译,汇编和链接
3.函数声明、定义、调用
函数声明,定义,调用:
思考下,为什么要有函数?函数的声明有什么作用?
函数声明和定义:
在一个大型项目中,源文件的编译是有顺序的。当在编译一个文件时,遇到函数fun1调用fun2。此时编译器如何对调用fun2做检查呢?比如检查参数个数和类型是否正确。但是当此时编译器可能还未遇到fun2的定义,因此不知道如何检查fun2函数调用的是否正确。此时,就需要提前告诉编译器该函数的原型。这就是声明的作用。
函数调用:
函数调用过程,需要开辟栈帧空间,把参数和返回地址进行压栈。调用结束后,再返回调用处。如需要进一步了解,可以参考笔者的这篇博客:深入理解计算机系统:缓冲区溢出、内存越界访问和栈破坏检测
函数声明:
函数的形参和实参:
需要了解c语言中函数传参的三种形式:值传递,指针传递,引用传递
函数参数:
函数返回值:
4.头文件的作用
头文件的使用:
5.行缓冲、全缓冲、无缓冲以及用户缓冲区、内核缓冲区介绍
6.编程技术相关
6.1 数据类型的作用
当一个数值存储到计算机中,就是0101的二进制。而这些二进制如何有含义,就涉及到数据类型。
比如,
6.2 常量
使用#define预处理命令:
使用const关键字修饰
另外一种更灵活的常量设置方法:
把一个常量定义成变量,也行。但为什么定义成常量呢?为了为了避免这个常量的值被意外更改。定义成常量就放在了内存的仅可读的区域,而定义成变量,在程序运行过程中,有可能被主动或被动意外更改(程序中主动改,或者踩内存意外更改了这个常量的值)
6.3 typedef关键字
c语言的typedef是为已有的类型创建一个别名。
在项目中,经常会使用typedef.
比如
typedef unsingned int uint;
6.4 运算符
sizeof和+,-,*,等都属于运算符。sizeof的结果是在编译时就已经确定,而不是在运行时。
6.5 i++和++i的区别
i++和++i的区别:
一个是先赋值,后自增。另一个是先自增,后赋值。
6.6 循环
6.7 转换说明
printf中转换说明的意义:把存储在计算机中的二进制格式的数值准换成一系列字符,以便于显示。
6.8 文件结尾EOF
6.9 数组
关于内存访问越界,可以参考笔者的这篇博客:深入理解计算机系统:缓冲区溢出、内存越界访问和栈破坏检测
二维数组: