欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c/c++易错知识点整理2(预处理,const,static,sizeof)(上)

程序员文章站 2024-01-30 10:55:58
...
预处理、const、static与sizeof


1.在#define宏中需要把参数小心地用括号括起来。因为宏只是简单的文本替换,如果不注意,很容易引起歧义。
  
#define SQR(x) (x*x)

int a,b=3;
a=SQR(b+2);  //a=b+2*b+2
输出a=11。


2.宏参数
#define STR(s)  #s
#define CONS(a,b) (int)(a##e##b)

#把宏参数变为一个字符串,用##把两个宏参数贴在一起。



3.用宏定义得到一个字的高位和低位字节
#define  WORD_LO(xxx) ((byte) ((word)(xxx)&255))
#define  WORD_HI(xxx) ((byte) ((word)(xxx)>>8))

4.宏定义得到一个数组所含的元素个数
#define ARR_SIZE(a) (sizeof((a))/sizeof((a[0]))

5.const
靠近const的变量的值是不能改变的,一旦改变就会出现错误。
int b=10;
const int*a1=&b;
a1=&c;
*a1=1;
此处把a1指向变量c是允许的,因为这修改的是指针本身;

但改变a1指向的内容是不允许的。

int* const a2=&b;
a2=&c;
*a2=1;
a2定义为int* const类型,注意这里的const在int*的右侧,它是用来修饰指针本身,即指针本身为常量。

因此,第二行a2=&c是不允许的,而第三行修改a2指向的内容是允许的。

const int* const a3=&b;
.
a3=&c;
*a3=1;
a3定义为const int* const类型,这里有两个const,分别在int*的左右两侧,因此它不仅表示指针本身不能修改,并且其指向的内容也不能修改。

所以第二第三行都是错的。


6.const与#define的特点及区别

#define只是用来做文本替换的,它存在于程序的代码段,在实际程序中它只是一个常数、一个命令中的参数,并没有实际的存在。

const常量存在于程序的数据段,并且在堆栈分配了空间,它在程序中确确实实地存在着并且可以被调用、传递。const常量有数据类型,而宏常量没有数据类型。

编译器可以对const常量进行类型安全检查。


7. c++中const有什么作用

(1)、const用于定义常量:const定义的常量编辑器可以对其进行数据静态类型安全检查。

(2)、const修饰函数形式参数:当输入参数为用户自定义类型和抽象数据类型时,应该将“值传递”改为“const&传递”,可以提高效率。

void fun(A a);
void fun(A const &a);

第一个函数效率低。函数体内产生A类型的临时对象用于复制参数a,临时对象的构造、复制、析构过程都将消耗时间。而第二个函数提高了效率。用“引用传递”不需要产生临时对象,节省了临时对象的构造、复制、析构过程消耗的时间。但光用引用有可能改变a,所以加const。

(3)、const修饰函数的返回值:如给“指针传递”的函数返回值加const,则返回值不能被直接修改,且该返回值只能被赋值给加const修饰的同类指针。例:

const char *GetChar(void){}
char *ch=GetChar();           //error
const char *chGetChar();    //correct


(4)、const修饰类的成员函数(函数定义体):任何不会修改数据成员的函数都应用const修饰,这样,当不小心修改了数据成员或调用了非const成员函数时,编译器会报错,const修饰类的成员函数形式为:

int GetCount(void) const;


8.static有什么作用

在c语言中,关键字static有3个明显的作用:

(1)在函数体,一个被声明为静态的变量在这一函数被调用的过程中维持其值不变。

(2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所有函数访问,但不能被模块外其他函数访问。它是一个本地的全局变量。

(3)在模块内,一个被声明为静态的函数只可被这一模块的其他函数调用。那就是这个函数被限制在声明它的模块的本地范围内使用。


9.static全局变量与普通的全局变量有什么区别

全局变量的说明之前再加上static就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是.静态存储方式。这两者在存储方式上并无不同。这两者的区别在于,非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态全局变量在各个源文件中都是有效地的;而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件的函数公用,因此可以避免在其他源文件中引起错误。

从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式,即改变了它的生存期;把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。

static函数与普通函数的作用域不同。static函数的作用域仅在本文件,只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。

总结:

static全局变量与普通全局变量的区别是,static全局变量只初始化一次,防止在其他文件单元中被引用。

static局部变量和普通局部变量的区别是,static局部变量只被初始化一次,下一次依据上一次结果值。

static函数与普通函数的区别是,static函数在内存中只有一份,普通函数在每个被调用中为维持一份复制品。