程序的翻译环境和执行环境
在ANSN C(
ANSI C是由美国国家标准协会(ANSI)及国际标准化组织(ISO)推出的关于C语言的标准。ANSI C 主要标准化了现存的实践, 同时增加了一些来自 C++ 的内容 (主要是函数原型) 并支持多国字符集 (包括备受争议的三字符序列)。 ANSI C 标准同时规定了 C 运行期库例程的标准
)的任何一种实现中,存在俩种不同的环境
1.翻译环境:源代码被转换成可执行的机器指令
2.执行环境:用于实际执行的代码:
翻译环境:

1.组成程序的每个源文件通过编译器分别转换成目标代码(odject code)
2.每个目标文件由链接器捆绑在一起,形成一个单一而完整的可执行程序。
3.链接器同时也会引入C函数标准库中被改程序用到的函数,并且可以搜索到程序员个人的程序库,将需要的函数链接到程序中。
编译本身过程:
首先假如有一个test.c文件,那他是如何执行编译过程的?

1.预处理(gcc -E test.c -o test.i),将文件保存在test.i文件中。
2.编译(gcc -S test.c),将编译完成的文件保存在test.s中。
3.汇编(gcc -C test.c),经汇编文成的文件保存在test.o中。
程序执行过程:
1.程序必须载入内存,在有操作系统的环境中:一般这个由操作系统来完成。在独立的环境中,需要手工安排,也可通过可执行代码置入只读内存来完成。
2.程序执行开始,便调用mian函数
3.使用一个运行时的堆栈,存储函数的局部变量和返回地址。也可以使用静态内存,存储静态内存中变量在整个执行过程中一直保理他们的值。
4.终止程序,正常终止main函数,也有可能意外终止。
*静态内存:静态内存使用的是栈空间内存,不需要程序员自己分配,因为静态变量占用的空间对于编译器是可预计的,静态内存只需要编程的时候直接声明就可以使用了。
宏替换:不能出现递归。
用宏来实现简单的函数运算的优点:
1.宏比函数在程序的规模和速度方面上更胜一筹。
2.函数的参数需要制定类型,宏是类型无关的。
缺点:
1.每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。
2.宏是没法调试的。
3.由于与类型无关,所以不够严谨。
4.很可能带来运算符优先级问题,很容易出错。
下面是宏和函数的对比:

移除一个宏定义:
#undef name 如果要将现存的一个名字重新定义,那么他的旧名字首先要被移除。
防止头文件的重复引用
#ifndef __TEST_H__
#define __TEST_H__
//头文件内容
#endif
*如何理解头文件被重复引用,比如在a.h文件中引用了c.h文件,d.
c文件中引用了a.h文件又引用了c.h文件,这样就造成c.h的重复引用,重复引用不会造成太大的问题,仅仅使编译效率低一些,但是对于大工程来说编译效率低将是很头疼的事。
#error编译器停止工作显示错误信息。
#pragma 设定编译器的状态或者指示编译器完成一些特定的动作。
例如:#pragma once保证头文件只被编译一次。
#pragma pack(n)设定变量以n字节的对齐方式,n字节的对齐方式就是说存放的起始地址的偏移量的俩种情况:1.如果n大于该变量的所占的字节数,那么偏移量,必须满足默认的对齐方式。如果n小于该变量的所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。
结构的总大小也有俩种情况,1.如果n大于所有成员变量类型所占用的字节数,那么结构的总大小,必须为占用空间最大的变量占用空间的倍数,负责,负责为n的倍数。