对”const“和”static“的深度理解—预处理、const、static与sizeof(二)
目录
static所修饰的全局/局部变量/函数和普通的全局/局部变量/函数的区别
const的使用
const修饰整型常量的类型
#include <stdio.h>
int main()
{
const int x = 1;//将x定义为整型常量,设置为不可更改的属性。
x = 2; //会报错,因为x不可被更改
system("pause");
return 0;
}
const修饰指针类型变量的情况
#include <stdio.h>
int main()
{
int b = 10;
int c = 20;
const int* a1 = &b; //将变量的类型设为固定值
int* const a2 = &b; //将变量本身设为固定值
const int* const a3 = &b;//将变量的类型及本身都设定为固定值
a1 = &c; //正常运行
//*a1 = 1;//报错
//a2 = &c;
*a2 = 1;
//a3 = &c;
//*a3 = 1;
system("pause");
return 0;
}
以"a1 = &c;"为例,因为a1的类型不可修改,但a1本身所存的值可以修改,故,将a1这个变量本身所存的值,换成c的地址,是可以成功的。
以"//*a1 = 1;"同理,a1的类型不可修改,去将*a1=1,意味着将a1变量所存的地址指向的变量的内容修改为1,那为什么修改了指针所指向的内容,会影响到指针类型呢?这是因为,指针类型要和其所指向的内存空间存放的内容保持一致,对指针类型加上const,在这里有双重含义:不止是要保证所指向的内容的数据类型不可更改,更是保证所指向的内容本身也不可被修改。
一语概括,当const用来修饰int*的时候,const在int*的左边,那int*所创造的指针所指向的内存空间所存放的内容,不可被修改;const在int*的右边,那int*所创造的指针变量不可被修改。
const具体的应用场景
- const用于定义常量,编译器会对其进行数据类型静态类型检查。
- const修饰函数形式参数(形参),保证输入的这个参数,不会在函数中被修改。
- const修饰函数的返回值,如果返回值用const修饰,那么返回值不能直接被修改,同时,也应该一个用const定义的一个常量去接这个返回值才行。
- const修饰类的成员函数(函数定义体),任何一个不会修改函数成员的函数,都应该用const来修饰。
static的理解
static的使用范围
- 在函数体内,一个被声明为静态的变量在函数体内维持其值的不变。
- 在作用域内(模块内),但在函数体外,维持这个被声明为静态的变量可以被作用域内的所有函数访问,但不能被作用域之外的函数所访问。相当于在作用域内的全局变量的存在。
- 同理,用静态定义的函数,也是只可在当前的作用域内(模块内)使用,可以被其他函数所调用。
static所修饰的全局/局部变量/函数和普通的全局/局部变量/函数的区别
static所修饰的全局变量和普通全局变量的区别
在大型的项目中,相关的cpp文件可能有许多个,如果在其中定义的一个全局变量,那么其作用域是源程序,而大型的项目的源程序可能是由好多个源程序组成的,这就造成的了,非静态全局变量即普通变量在每个源程序中都是有效的;而被static修饰的全局变量,只在当下的定义该变量的作用域内有效,只能被该作用域下的函数所使用,不能被该作用域之外的程序所调用,这样就可以避免在其他源文件中被引用从而引起错误的风险。
static变量自始至终只初始化一次。
static所修饰的局部变量和普通局部变量的区别
如果一个局部变量没有被static所修饰,那其生命周期,就只在其所在的函数中了,而被static修饰以后,其生命周期,就扩大到了当前的作用域下,即直到作用域中的所有程序都运行完毕了,它才会被析构掉。即,static可以改变了局部变量的生命周期。
static变量自始至终只初始化一次。
static所修饰的函数和普通函数的区别
被static修饰的函数只能在所创建它的这个作用域下进行使用,如果非想在作用域外对它进行调用,必须在头文件中将其声明出来,让想调用这个函数的函数使用的时候,把这个头文件给包含进去。、
而且,static函数在内存中独有一份,而普通函数在每次被调用的时候中都会创建一份复制出来。
static对象在类中创建的情况
静态变量如果是创建在一个类中的,那么这个对象是在作用域中第一次被调用时被创建出来的,且自始至终只创建一次且不可修改,在main函数运行退出后进行销毁;静态变量是属于整个类的而不属于类所创建的任何对象,静态对象变量只存储一份,想调用它的函数都公用这一份数据。
小case
#include <stdio.h>
#include <iostream>
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;
printf("创建对象的个数:%d\n", widget::num());
system("pause");
return 0;
}
利用static这个特性,就可以完成一些非常有趣的事情,如上代码,就可以利用static定义的变量,不会受所创建的对象的影响,可以完成对类所创建的对象的计数。运行结果:
上一篇: 原生js实现Ajax的原理