(一)用#define实现宏,并求最大值和最小值
#define MAX(x,y) (((x)>(y)) ? (x):(y))
#define MIN(x,y) (((x)
分析:这个操作符能产生比if-else更优化的代码,并且书写上更简洁明了。
而且有一点值得注意:在宏中需要把参数小心地用括号括起来,因为宏只是简单的文本替换,如果不注意很容易引起歧义。比如下面这个例子:
我们知道宏只是简单的文本替换,那么a = b+2*b+2 = 11,因此,最终输出为a=11;
如果程序的本意是想输出(b+2)平方,那么宏定义应该改为:#define SQR(x) ((x)*(x))
(二)宏参数的连接
分析:本程序中,使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起。
因此STR(s)定义的是一个参数s表示的字符串,STR(vck)实际表示的就是字符串"vck"
而CONS(a,b)定义的是一个将参数a与b按aeb连接起来的一个整型值,所以CONS(2,3)实际表示2e3,也就是2000
程序执行结果为:
(三)用宏定义得到一个字的高位和低位字节
#define WORD_LO(x) ( (byte)( (word)(x)&255 ) )
#define WORD_HI(x) ( (byte)( (word)(x)>>8 ) )
(四)用宏定义得到一个数组所含的元素个数
#define ARR_SIZE(a) ( sizeof((a))/sizeof((a[0])) )
(五)const和define的各自特点及区别
分析:#define只是用于做简单的文本替换,例如#define PI 3.1415926,当程序进行编译的时候,编译器会将#define PI 3.1415926之后的所有PI全部换成3.1415926,然后再进行编译。因此#define常量的生命周期止于编译期,它存在于程序的代码段,在实际程序中只是一个常数,一个命令中的参数,并没有实际的存在。
const常量存在于程序的数据段,并在堆栈中分配了空间。const常量是一个Run-Time的概念,它在程序中确确实实地存在着并可以被调用、传递。
const常量有数据类型,而宏常量没有数据类型。编译器可以对const常量进行类型安全检查。
(六)C++中const有什么作用
1、const用于定义常量:const定义的常量,编辑器可以对其进行数据静态类型安全检查。
2、const修饰函数的形参:当输入参数为用户自动以类型和抽象数据类型时,将“值传递”改为“const &传递”可以提高效率。例如,
void fun(A a);
void fun(A const &a);
第一个函数效率低,函数体内产生A类型的临时对象用于传递“值传递”参数,临时对象的构造、复制、析构过程都将消耗时间。而第二个函数提高了效率,用“引用传递”不需要产生临时对象,省了临时对象的构造、复制、析构过程,但只引用可能会改变a,所以加const。
3、const修饰函数的返回值:如果给“指针传递”的函数的返回值加上const,则返回值不能被直接修改,且该返回值只能被赋值给const修饰的同类型指针。
如,const char *GetChar(void) {};
char *ch = GetChar(); //error
const char *ch = GetChar(); //correct
4、const修饰类的成员函数:任何不需要修改数据成员的函数都应该用const修饰,这样即使不小心修改了数据成员或调用了非const成员函数,编译也会报错。如,int GetCount(void) const;
(七)static有什么作用?
1、在函数体,一个被声明为静态的变量,在函数被调用的过程中维持其值不变。
2、在模块内,一个被声明为静态的变量,可以被模块内所有函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3、在模块内,被声明为静态的函数,只能被这一模块内的其它函数调用,即函数被限制在声明它的模块范围内。
(八)#pragma pack的作用
分析:#pragma pack(1)的作用是将对齐设为1。由于结构体test中s1,s2,i的自身对齐分别为2、2、4,因此,sizeof(test)=1+2+2+4=9。如果将#pragma pack(1)注释掉,则编译器默认对齐为8,因此sizeof(test)=12。
(九)用sizeof计算联合体的大小
分析:联合体的大小取决于它所有的成员中占用空间最大的一个成员的大小,对齐方式为成员中最大的成员对齐方式。
对于联合体u,sizeof(u)=sizeof(double)=8
对于联合体u2,最大的空间是数组char a[13],但是由于int b的存在,u2的对齐方式变成了4,因此,sizeof(u2)=16
对于联合体u3,sizeof(u3)=13
但是,如果在上述代码中加入:#pragma pack(2)
那么,由于手动更改对齐方式为2,则sizeof(u2)=14
(十)使用strlen()函数代替sizeof计算字符串长度
分析:char型数组,strlen()函数返回数组内元素个数,不包括'\0',sizeof是运算符,计算数组长度,包括'\0'
strlen()函数的定义是:从内存的某个位置开始扫描,直到碰到第一个'\0'结束,返回计数器的数值,单位是字节。
sizeof运算符的定义是:返回一个对象或者类型所占的内存字节数。
因此,
第29行,strlen(str)=5;
第30行,sizeof(str)=6,sizeof(str[0])=1,故sizeof(str)/sizeof(str[0])=6
执行UpperCase()函数,函数目的是将小写字母改为大写字母
第7行,test=sizeof(str),由于此时str为指针,因此sizeof(str)=4
第8行,test2=sizeof(str[0])=1
第13行,str1是指针,指向字符串"abCDEFG",因此strlen(str1)=7,sizeof(str1)=4
第14行,str2是数组,因此srelen(str2)=7,sizeof(str2)=8
程序执行结果为: