c/c++整理--const和static关键字

一、改错——const的使用

  const使用时的注意点

#include <stdio.h>

int main()
{
	const int x = 1;
	int b = 10;
	int c = 20;
	
	const int* m = &b;
	int* const n = &b;
	const int* const s = &b;
	
	x = 2;
	
	m = &c;
	*m = 1;
	
	n = &c;
	*n = 1;
	
	s = &c;
	*s = 1;
	
	return 0;
}

  对于C语言中的const有一句秘诀记住它的特性:进水楼台先得月。意为最靠近const的变量的值是不能变的,一旦发生改变就会出现错误。

错误:

  第13行中,x的值不能发生改变,出错。

  第15行的做法是可以的,没有错误,但是16行中取它的值来改变就是错的,即m是可变的*m不可变。

  第19行的做法可以,没错,但是18行的做法就是错的,即n是不可变的,但是*n可变。

  第21和22行都是错的,*s和s都是不可变的。


二、说明const与#define的特点及区别

解析:

  #define只是用来做文本替换的。例如:

#define PI     3.1415926
当程序进行编译的时候,编译器会首先将这句话之后的所有代码中的“PI”替换为“3.1415926”,然后进行编译。 #define的生命周期仅在编译时期,它存在于程序的代码段,在实际程序中它只是一个常数、一个命令中的参数,并不实际存在。

  const常量存在于程序的数据段,并在堆栈分配了空间。const在程序中确确实实存在着,并可以被调用、传递。const常量有数据类型,而宏常量没有数据类型。编译器可以对const常量进行类型安全检查。


三、c++中const有什么作用?

解析:

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

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

void fun(A a);
void fun(A const &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有什么作用

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

(1)在函数体,一个被声明为静态的变量在这一函数结束的时候,其值会保留原值而不会被销毁,一直存在。

(2)工程内的一个文件内被声明为静态的变量可以被本文件内所有函数访问,不能被同一工程内的其他文件函数访问。是一个本地的全局变量。

(3)工程内的一个文件内被声明为静态的函数只可以被本文件的其他函数调用,但是不能被同一工程内的其他文件访问,这个函数被限制在声明它的文件内使用。


五、static全局变量与普通的全局变量有什么区别

解析:

  全局变量的说明加上static构成了静态全局变量。全局变量和static全局变量都是静态存储方式,两者区别在于,非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源程序都是有效的,而静态全局变量限制了作用域,只在定义该变量的源文件内有效,同一源程序的其他文件无法访问。

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

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

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


六、c++类的静态成员

看代码写输出:

#include <iostream>

using namespace std;

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;
	count<<"The Num. is"<<widget::num()<<endl;
	if(widget::num()>1)
	{
		widget x, y, z;
		cout<<"The Num. is"<<widget::num()<<endl;
	}
	widget z;
	cout<<"The Num. is"<<widget::num()<<endl;
	
	return 0;
}

代码中,构造函数中count自加,析构函数自减,28行构造两个count = 2,32行在if语句中构造3个局部对象,33行输出count = 5,36行的时候,局部对象已析构,输出count = 3

答案:

The Num. is2
The Num. is5
The Num. is3




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值