1. 在c语言中,有一些特殊的预定义符号,这些预定义结合使用,会产生非常有趣的事情。下面,介绍一下这些特殊的预定义符号:
_ _FINE_ _
_ _LINE_ _
_ _ DATE_ _ //文件被编译的日期
_ _TIME_ _
如下面的程序代码语句:
printf("file:%s\nline:%d\ndate:%s\ntime:%s\n",__FILE__,__LINE__,__DATE__,__TIME__);
这样可以将当前被编译文件的路径、文件编译到哪一行、文件编译的日期以及文件编译的时间等信息清晰地显示出来。
除此之外,c语言中还有#和##这样的符号。
其中带#的指令是写给编译器看的,好让它更好地为c程序代码服务,比如#include 指令就是告诉编译器看到这句话就要把已写好的文件包含进来;
#define指令就是告诉编译器看到这个宏就用前面已经定义好的内容替换等等。
而##在c语言中具有连接字符串的作用,例如:执行完A ## B后变为AB(连接A和B并去掉空格)。
有下面这样一段程序代码:
<span style="color:#3333ff;"><pre name="code" class="plain">#include<stdio.h>
#include<windows.h>
#define POST(n) printf("take "#n"=%d",take##n)
int main()
{
int take9=10;
POST(9);
system("pause");
return 0;
}
上述程序运行结果为:<pre name="code" class="plain">take9=10</span>
2.关于宏和函数的区别
宏可以非常频繁地用于执行简单的程序,如比较两个数的大小问题:<span style="color:#3366ff;"><pre name="code" class="plain">#define MAX(a,b) ((a)>(b)?(a):(b))</span>
针对这一程序,采用宏比使用函数在程序的规模和运行速度方面更胜一筹,因为若采用函数方式,用于调用和从函数返回的码很可能比实际执行这个小型计算工作代价更大;
另一方面,采用宏是与类型无关的,即宏可以用于整形、长整形、单浮点型、双浮点型以及其他任何可以使用>操作符比较值大小的类型。
</pre><pre name="code" class="plain">使用宏也有不利之处,每次使用宏时,一份宏定义代码的拷贝将插入到程序中,除非宏非常短,否则使用宏可能会大幅度增加程序的长度,这时,使用函数是更好的方法。<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
3.一个c语言程序的编译链接过程
翻译过程:组成一个程序的每个源文件通过编译过程分别转换成目标代码-->每个目标文件由链接器捆绑在一起,形成一个单一而完整的可执行程序。
编译过程:
第一阶段:预处理器--预编译阶段(在这个阶段,预处理器在源代码上执行一些文本操作,比不可少的有:头文件展开、宏替换、去掉注释和条件编译等过程)。
第二阶段:源代码经过解析,判断它的语句的意思,这个阶段产生绝大多数的错误和警告。
第三阶段:产生目标代码。
执行过程:
第一过程:程序必须载入内存中,在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
第二过程:程序的执行便开始。接着便调用main函数。
第三过程:开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
第四过程:终止程序。正常终止main函数;也有可能是意外终止。
</pre><br /><br /><p></p><p><span ></span></p><pre name="code" class="plain">