《C专家编程》学习总结2
《C专家编程》学习总结2
转自 : http://blog.chinaunix.net/u2/87570/showart_2120069.html
编译器做了些什么
图1:编译器通常分割成几个更小的程序
静态链接与动态链接
图2:静态链接与动态链接的区别
动态链接的优势:
1, 动态链接可执行文件比功能相同的静态链接的可执行文件的体积小。它能够节省磁盘空间和虚拟内存,因为函数库只有在需要时才被映射到进程中。以前,避免把函数库的拷贝绑定到每个可执行程序文件的惟一方法就是把服务器置于内核而不是函数库中,使得内核膨胀。
2, 所有动态链接到某个特定函数库的可执行文件在运行时共享该函数库的一个单独拷贝。操作系统内核保证映射到内存中的含数据库可以被使用它的其他进程共享,提供了更好的I/O和交换空间利用率,节省了物理内存,从而提高了系统的整体性能。如果可执行文件是静态链接的,每个文件都将拥有一份函数库的拷贝,显然极为浪费空间。
关于函数链接
1, 动态库文件的扩展名是.so,而静态库文件的扩展名是.a,并以libname的形式命名。
2, gcc通过-lthread选项,告诉编译器链接libthread.so。
3, 编译器期望在确定的目录寻找库。默认查找一些特定目录如/usr/lib, /lib,-Lpathname告诉编译器在其他位置查找库。
4, 通过观察头文件,确认使用的函数库。
如math.h-->/usr/lib/libm.so, thread.h—>/usr/lib/libthread.so
运行时数据结构
图3:源文件到可执行文件的映射
图4:可执行文件内核映像
图5:共享库的虚拟地址空间
图6: 过程活动记录
C语言自动提供的服务之一就是跟踪调用链,即哪些函数调用了哪些函数,当下一个return语句执行后,控制将返回何处等。C语言通过堆栈中的过程活动记录解决这一问题,当每个函数被调用时,都会产生一个过程活动记录(或类似的结构)。过程活动记录是一种数据结构,用于支持过程调用,并记录调用结束后返回调用点所需要的全部信息,如图6所示。活动记录内容的描述很具有说明性,结构的具体细节在不同的编译器中各不相同。过程活动记录并不一定在堆栈中,有时为了提高效率,将过程活动记录置于寄存器中。
从堆栈实现函数调用的方式可以解释为什么
相关文档:
access(判断是否具有存取文件的权限)
相关函数 stat,open,chmod,chown,setuid,setgid
表头文件 #include<unistd.h>
定义函数 int access(const char * pathname,int mode);
函数说明 access()会检查是否可以读/写某一已存在的文件。参数mode有几种情况组合,R_OK ......
http://uncrustify.sourceforge.net/
Ident code, aligning on parens, assignments, etc
Align on '=' and variable definitions
Align structure initializers
Align #define stuff
Align backslash-newline stuff
Reformat comments (a little bit)
Fix inter-character spacing
Add or remove parens on return ......
关于#和##在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。比如下面代码中的宏:
#define WARN_IF(EXP) \
do{ if (EXP) \
& ......
C/C++ Reference
http://www.cppreference.com/
C++ Library Reference
http://www.cplusplus.com/ref/
Standard C++ Library Class Reference at Rogue Wave
http://www.roguewave.com/support/docs/hppdocs/stdref/
Dink ......