1、Unix的哲学
简单性:Keep It Small and Simple。越大、越复杂的系统注定包含越大、越复杂的错误,而调试是所有人的苦差事。
集中性:不要把所有乱七八糟的功能堆在一起,功能臃肿的程序很那维护和使用。当用户出现新的需求的时候,我们通常是把小工具组合起来已完成更复杂的任务。
可重用组件:将应用程序的核心封装成库,便于调用。
过滤器:Unix提供了一些机制,让我们可以把一些Unix程序通过一种新颖的方式组合起来,以开发出相当复杂的程序。
开放的文件格式:比较成功并流行的Unix程序都是用纯ASCII码的文本文档或者XML文件作为配置文件和数据文件。
灵活性:你不能期待用户都能非常正确地使用你的程序。永远不要认为你知道用户想做的一切事。
2、Linux程序设计
Linux的应用程序有两种类型:可执行文件和脚本文件。可执行文件是计算机可以直接运行的文件,就像Windows下面的.exe文件一下;脚本文件通常是一组指令的集合,这些指令有解释器执行,按照脚本的顺序指令执行,比如shell文件。
Linux并不要求这两种类型的文件有特殊的文件名或者后缀名,但最好加上来区别,像shell文件的后缀为.sh、Python的后缀为.py等等。
3、Linux下与程序设计有关的目录
/bin:二进制文件目录,存放启动系统时用到的程序。
/usr/bin:用户二进制文件目录,用于存放用户使用的标准程序。
/usr/local/bin:本地二进制文件目录,用于存放软件安装的程序。
4、文本编辑器
书中推荐使用的编辑器是Emacs,而我本人使用的是vim,不做任何说话,避免开战。
编译器使用的gcc。
5、第一个Linux C语言程序
#include
#include
int main()
{
printf("hello world\n");
exit(0);
}
编译、链接和运行程序
$ gcc -o hello hello.c //-o name 告诉编译器可执行文件的名称,不加默认生成a.out(assembler output)
$ ./hello
hello world
6、开发系统引导
对C语言来说,头文件几乎总是位于/usr/include目录及其子目录中。那些依赖于特定Linux版本的头文件通常可以在目录/usr/include/sys和/usr/include/linux中找到。
在调试c语言的时候,可以使用-I(大写)标志来包含保存在子目录或非标准位置中的头文件。例如:
$ gcc -I /usr/openwin/include fred.c
编译器会在此目录下查找源文件中包含的头文件。
7、库文件
库是一组预先编译好的函数的集合,这些函数都是按照可重用的原则编写的。
库文件的类型:
.a代表的静态函数库
.so代表的是共享函数库
8、静态库和共享库
静态库:静态库,也叫做归档文件(archive),以.a结尾,前缀为lib,后面为静态库的名字。
实验:
//先创建一个源文件,命名为fred.c
#include
void fred(int arg)
{
printf("fred: we passed %d\n", arg);
}
//创建第二个源文件,命名为bill.c
#include
void bill(char *arg)
{
printf("bill: we passed %s\n", arg);
}
分别编译函数,产生目标文件,使用gcc编译器的-c选项,-c可以阻止产生完整的程序,以上还没有main函数,使用-o会报错。
$ gcc -c bill.c fred.c $ ls *.o
bill.o fred.o
现在编写一个头文件包含bill函数和fred函数。
$ vim lib.h void fred(int arg); void bill(char *arg);
编写程序调用bill函数
#include
#include "lib.h"
int main()
{
bill("hello world");
exit(0);
}
编译并测试这个程序
$ gcc - c program.c $ gcc -o program program.o bill.o $ ./program
bill: we passed hello world
现在,开始创建一个静态库(使用ar命令打包,ar程序可以创建任何类型文件的归档文件,是一个通用工具)。
$ ar crv libfoo.a bill.o fred.o
创建完毕,可以在编译器使用的文件列表中添加该库文件来创建程序。
$ gcc -o program program.o libfoo.a $ ./program
bill: we passed hello world
也可以使用-l选项来访问函数库,这样如果一个目录下有静态库和共享库两种类型,会优先使用共享库。例如:
$ gcc -o program program.o -i foo -L .
-L后面是要寻找的路径,-i后面加库的名字。
9、共享库的创建
共享库可以在多个程序中共用一段函数,程序本身不会包含这段函数代码,只有运行到调用这段函数的时候,才回去把编译好的程序代码装载到内存中执行。静态库会把函数放到程序内部中,这样就会消耗大量的内存和磁盘空间。
实验:
$ gcc -c -fpic bill.c fred.c $ gcc -shared -o libfoo.so bill.o fred.o
创建完毕,使用共享库的时候需要配置一下共享库的路径问题,要不然会显示:cannot open shared object file: No such file or directory。
方法1:打开/etc/ld.so.conf文件,在里面追加libfoo.so的路径,使用ldconfig命令更新一下即可。
方法2:配环境变量LD_LIBRARY_PATH。把当前目录(也就是.)加入到前述的环境变量里面,不过这种方法是临时的。