1.#ifdef、#else、#endif、#ifndef 指示符
#include<stdio.h>
#define DEBUG
//定义DEBUG预处理常量
int main()
{
#ifdef DEBUG
//判断预处理常量是否被定义
printf("定义了名为DEBUG的预处理常量");
#else
printf("没有定义名为DEBUG的预处理常量");
#endif
return 0;
}
#ifndef与#ifdef作用相同,即判断预处理常量是否没被定义
2.宏定义,良好的宏定义能提高代码的可移植性和可读性。在宏中需要把参数小心的用括号括起来,因为宏是简
单的文本替换,如果不注意容易引起歧义。如下:
#define SQR(x) (x*x)
int main()
{
int a,b = 3;
a = SQR(b 2);
printf("a = %d\n",a); //输出为:11
return 0;
}
本例中原本想求5即(b 2)的平方,由于宏定义展开是在预处理时期就是编译之前。此时b并没有被赋值,b只是一个符号,因此展开为:a = (b 2*b 2),于是输出为11。为了达到本意需要将SQR(x)定义如下:
#define SQR(x) ((x)*(x))
3.用#define实现求最大最小值(注意:参数都用括号括起来)
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIX(x,y) ((x)<(y)?(x):(y))
4.用#define得到一个字的高位和低位字节
#define WORD_LO(xxx) ((byte)((word)(xxx)&0xff))
#define WORD_HI(xxx) ((byte)((word)(xxx)>>8))
5.用#define得到数组元素个数
#define ARR_SIZE(a) (sizeof((a))/sizeof((a[0])))
总结以上2、3为宏定义如何使用及注意事项,4描述了宏定义与位运算的使用,5描述了宏定义与sizeof的使用。
6.const是C的一个关键字,限定变量不允许被改变,增强程序的健壮型。
const关键字在指针声明时的作用,const位于*的左侧,是修饰指针所指向的变量,即为指针常量;const位
于*号的右侧,是修饰指针本身,即为常量指针。如下:(法则:用const修饰的对象它是一个常量,*号右侧
修饰本身)
char* const p1; //*号右侧,const修饰p1即p1为常量,p1又是指针,所以p1为指针常量。假设p1指向的变
量为0x00005895,此值为一个地址值,p1永远指向0x00005895本身不能再修改,但是0x00005895地址中的
内容可以改变。
char const* p2; //*号左侧,const修饰p2指向的变量,假设p2指向的地址为0x00005800,那么const修饰
的为0x00005800地址中的内容,所以0x00005800中的内容不能再修改,但是p2可以再指向其他的地址如
0x00005700,这里p2就是一个常量指针,它指向的是一个常量。
const char* p3; //常量指针
const char* const p4; //p4是常量,它指向的内容也是常量。但p4依然为常量指针
********************************
#include<stdio.h>
int main()
{
const int x = 1; //定义常量x
int b = 10; int c = 20;
const int* a1 = &b; //定义a1为常量指针
int* const a2 = &b; //定义a2为指针常量
const int* const a3 = &b;
x = 2; //错误,x为整型常量,值不能改变
a1 = &c; //可以,*号左侧,修饰的为指针指向的变量,即变量为常量。而指针可以指向其他变量。
*a1 = 1; //错误,原因同上
a2 = &c; //错误,*号右侧,修饰的为指针,即指针为常量不能改变,它只能始终如一的指向b
*a2 = 1; //可以,*a2表示指针指向的内容
a3 = &c; //错误,const出现在*号左右两侧,表示指针不能改变其指向的内容也不能改变
*a3 = 1; //错误,同上
}
***************************************************
7.const与#define区别
(1)#define存在于程序的代码段,const常量存在于程序的数据段。
#define只用来做文本替换,在程序进行编译时,编译器先进行宏替换再进行编译,因此#define常量生命
周期至于编译期;const常量在堆栈中分配了空间,它在程序中确确实实地存在着并可以被调用、传递。
(2)#define宏常量没有数据类型,const常量有数据类型并能进行类型安全检查。
8.C 中const有什么作用?
(1)用于定义常量。如:const int x = 1;
(2)用于修饰函数参数,如:void fun(int const &n);
(3)用于修饰函数的返回值,如:const char *GetChar(void){};
(4)用于修饰类的成员函数,如:int GetCount(void) const;任何不需要修改数据成员的函数都应该用
const修饰。
9.static代表静态,它可以作用于变量和函数。
静态局部变量,即在局部变量前加上static关键字;
静态函数,即在函数返回类型前加上static关键字;
10.C 中static关键字3个明显的作用为:
(1)在函数体内声明静态局部变量;
(2)在模块内声明本地的全局变量;
(3)在模块内声明静态函数;
11.静态全局变量与普通全局变量区别,普通全局变量前面加上static关键字就构成了静态的全局变量。普通全
集变量作用域是整个源程序,而静态全局变量作用域是只在定义该变量的源文件内有效。静态全局变量只被初
始化一次,不能在其他文件中被引用。
12.静态局部变量与普通局部变量区别,生存期不同、作用域不同。静态局部变量只被初始化一次,下一次依据上
一次结果的值。
13.静态函数与普通函数区别,静态函数在内存中只有一份,普通函数在每个被调用中维持一份复制品。
class widget
{
public:
widget()
{
count ;
}
~widget()
{
count--;
}
//一个静态方法
static int num()
{
return count;
}
private:
//一个静态成员
static int count;
}
//静态成员、方法不属于类的实例,属于类本身并在所以类的实例间共享。
//调用方法为:类名加上操作符"::"来引用
int widget::count = 0;
int main()
{
widget x,y;
cout<<"The Num.is"<<widget::num()<<endl;
if(widget:num()>=1)
{
wodget x,y,z;
cout<<"The Num.is"<<widget::num()<<endl;
}
widget z;
cout<<"The Num.is"<<widget::num()<<endl;
return 0;
}