一:宏定义
1、不带参数的宏定义:
#define 标识符 字符串 例如:#define PI 3.1415926 说明:(1)宏名一般习惯用大写字母表示,但并非规定,也可以用小写
(2)使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量
(3)宏定义是用宏名代替一个字符串,也就是做简单的置换,并不做正确性检查。 比如如果写成 :
#define PI 3.l4l5926(把1错写成了l),在预编译时并不会做任何语法检查,只有在编译已经把宏展开后的源程序时才会发现语法错误并报告
(4)宏定义不是C语句,不必在行末加分号,如果加了分号将会连同分号一起进行置换。 比如如果写成:
#define PI 3.1415926; area=PI*r*r;则宏展开后该语句为:area=3.1415926;*r*r
(5)#define命令出息在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束,通常宏定义写在文件开头,在此文件范围内有效
(6)可以用#undef命令来终止宏定义的作用域,这样可以灵活控制宏定义的作用范围
(7)在进行宏定义时,可以应用已经定义的宏名,可以层层置换
(8)对程序中用引号括起来的字符串内的字符,即使与宏名相同,也不进行置换(9)宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,只做支付替换,不分配内存空间
2、带参数的宏定义:
#define 宏名(参数表) 字符串 例如:#define S(a,b) a*b · · ·
area=S(3,2); 说明:
(1)对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符串代替#define命令行中的形参
(2)在宏定义时,在宏名与带参数的括号之间不应加空格,否则将空格以后的字符都作为代替字符串的一部分。例如如果有:
#define S (r) PI*r*r(在S与(之间有空格)
被认为S是符号常量(不带参数的宏名),它代表字符串“(r) PI*r*r”,如果在程序中有语句: area=S(a); 则被展开为:
area=(r)PI*r*r(a); 显然不对
3、对于带参数的宏定义与函数的区别,主要有:
(1)函数调用时,先求出实参表达式的值,然后代入形参,而使用带参数的宏只是进行简单的字符替换
(2)函数调用是在程序运行时处理的,为形参分配临时的内存空间,儿宏展开是在编译前进行的,在展开时并不分配内存单元,不进行值的传递,也没有“返回值”的概念
(3)对函数中的市场和形参都要定义类型,二者的类型要求一致,如不一致则要进行类型转换,而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符合代替,展开时代入指定的字符串即可,宏定义时,字符串可以是任何类型的数据
(4)调用函数只可得到一个返回值,而用宏可以设法得到几个结果
(5)宏使用次数多是,宏展开后源程序变长,因为每次展开都使程序增长,而函数调用不会
(6)宏替换不占用运行时间,只占编译时间,而函数调用则占用运行时间用于分配单元、保存现场、值传递、返回等
二:结构体
格式:struct 结构体标识名
{类型名1 结构成员表1;
类型名2 结构成员表2;
„„类型名n 结构成员表n; };
注意:struct是关键字,是结构体类型的标志。“结构体标识名”和“结构体成员名”都是用户定义的标识符,“结构体标识名”是可选项,在说明中可以不出现。每个“结构成员表”中都可以含有多个同类型的成员名,它们之间用逗号隔开。结构体中的成员名可以和程序中的其他变量名相同,不同结构体中的成员也可以同名。要记住:结构体说明要以分号结尾。
定义结构体类型的变量、数组、和指针变量可用4中方式:a:紧跟在结构体类型说明之后进行定义;b:在说明一个无名结构体类型的同时直接进行定义;c:先说明结构体类型,再单独进行变量定义;d:使用typedef说明一个结构体类型名,再用新类型名来定义变量。
如果已经定义了一个结构体变量和基类型为同一结构体类型的指针变量,并使该指针指向同类型的变量,则引用结构体变量中的成员可以用以下三种形式:
形式1:结构体变量名.成员名 形式2:指针变量名->成员名 形式3:(*指针变量名).成员名
注意:结构体变量名也可以是已经定义的结构体数组中的数组元素。
说明:点号(.)称为成员运算符;箭头(->)称为结构指向运算符,它由减号和大于号两部分组成,它们之间不能有空格;在形式三中,一对圆括号不可少。这两个运算符与圆括号、下标运算符的优先级相同,在c语言的运算符中优先级最高。