C语言的许多特性是为了方便编译器设计者而建立的,因为开始几年C语言的主要客户就是那些编译器设计者。根据编译器设计者思路形成的特性有: 数组下标从0开始而不是从1开始。C语言的基本数据类型直接与底层硬件相对应。auto关键字。(这个关键字只对创建符号表入口的编译器设计者有意义)。register关键字。(这个关键字能给编译器设计者提供线索,即哪些变量属于常用,则可以把它们存放到寄存器中)。表达式中的数组名可以看作是指针。(数组和指针并不是在任何情况都是等效的)。不允许嵌套函数。(这简化了编译器,并稍微提高了C程序的运行时组织结构)。第一次C编译器出现时间大约是年,由于UNIX系统广泛应用使得C语言为人熟知。由于C语言直接能对硬件底层操作,带来了极高的效率和移植性,使得C语言帮助UNIX系统获得巨大成功。 1、#define与typedef1-1、#define宏最好只用于命名常量。宏名应该大写。比如,if(!strcmp(s,"volatile")){}这种表达式很抽象,我们可以通过#define换成一种直观的表达,如代码1-1 #include"stdio.h"#defineSTRCMP(a,R,b)(strcmp(a,b)R0)s="volatile";intmain(void){if(STRCMP(s,==,"volatile")){printf("s==volatile\r\n");system("pause");return0;}printf("%s\r\n",s);system("pause");return0;} 代码1-1 1-2、typedeftypedef它为一种类型引入新的名字,而不是创建新的变量。一般情况下,typedef用于简洁地表示指向其他东西的指针,如代码1-2 /*一个复杂的函数*/void(*signal(intsig,void(*func)(int)))(int);/*ptr_to_func是一个指针,它指向一个参数为int型的函数,该函数返回值为void型*/typedefvoid(*ptr_to_func)(int);/*signal是一个函数,它接收两个参数,其中一个是int型,另一个是ptr_to_func型,函数返回值是ptr_to_func型*/ptr_to_funcsignal(int,ptr_to_func); 代码1-2 typedef不应该用在什么地方和应该用在什么地方呢? typedef不应该用在的地方 不要为了方便而对结构体使用typedef。这样做的唯一好处是不必书写“sturct”关键字,但这个关键字可以向你提示一个信息,你不应该把他省掉。typedef应该用在的地方 数组、结构、指针以及函数的组合类型可移植类型,如typedefunsignedcharuint_8;为强制类型转换提供一个简单的名字1-3、typedef与#define区别typedef与#define区别在于typedef是一种彻底的“封装”类型。具体体现在两个方面 #define定义的类型名可以进行扩展,而typedef定义的类型名不允许这样做,如代码1-3在连续几个变量声明中,typedef定义的类型能够保证声明的所有变量为同一类型,而#define定义的类型无法保证相同,如代码1-4#definepeachintunsignedpeachi;/*没问题*/typedefintpeach;unsignedpeachi;/*错误*/ 代码1-3 #defineint_ptrint*int_ptri,j;/*经宏扩展,i,j为不同类型。int*i;intj;*/typedefint*int_ptr;int_ptri,j;/*i,j为相同类型。int*i;int*j;*/ 代码1-4 2、强制类型转换强制类型转换有两方面的作用:1、消除歧义;2、类型转换。 复杂强制类型转换可按以下3步进行编写 一个对象的声明,它的类型就是想要转换的结果类型。删除标识符以及任何如extern之类的储存限定符,并把剩余的内容放在一对括号里。把第2步产生的内容放在需要进行类型转换的对象的左边。具体的代码分析,如伪代码2-1和伪代码2-2。 voidqsort(voidbase,size_tnel,size_twidth,int(*
|