最近在回顾基本的编程知识,现将部分整理如下:
static
C语言中 static用法
局部变量差异:
static 局部变量 和 局部变量
区别在于 static 局部变量只初始化一次,下一次运算依赖于上一次运算结果
static 全局变量 和 全局变量的区别
static 全局变量 只初始化一次,防止被其他文件引用
static 函数:
static 函数只在一个源文件中有效,不能被其他源文件函数调用。
详细分析描述:
变量的生存周期:
函数体内,static 变量表示静态局部变量,在函数调用过程中维持其值不变。
维持其值不变可以理解为:
一般的局部变量在函数调用后,即被销毁,下次调用重新申请内存。
静态局部变量存放在静态区,在函数调用后被初始化,一直保存在内存中没有被销毁,生命周期比较长,
一般与整个源程序同存亡,所以,只需要初始化一次。
变量作用域:
模块内,函数体外声明的静态全局变量,只能被本模块函数访问。
static 函数只能被本模块内函数访问,不能被其他模块的函数调用。
内部函数应当在当前源文件中声明和定义,可以被其他文件调用的函数,集中声明在头文件中,
其他函数调用时包含头文件。
C++ static用法
C++成员变量
c++在类成员中添加 static,该数据成员就是类内的静态数据成员。
静态数据成员的特性:
静态数据成员存储在全局数据区域。定义时需要分配空间,不能在类声明中定义。
静态成员被当作类成员,所以引申出以下几个特性:
非静态成员,每个对象都有复制品,静态成员被当做类成员,无论有几个对象,都只有一份复制品。
静态成员属于本类所有对象共享的成员,不属于特定的对象,在没有对象实列时也可以访问。
静态数据成员也遵从 public,protected, private 访问规则。
静态数据成员是在类内定义,类外进行初始化的。类的静态成员必须初始化。参照下面示例:
class A
{
private:
static int count ; // 类内声明
};
// 类外定义并初始化,不必再加static关键字
int A::count = 0 ;
C++成员函数
静态成员是一个函数
当类的成员函数添加 static 关键字,就变成了静态成员函数
静态成员函数为类的全部服务而不是为某一个类的具体对象服务。
静态成员函数是类的内部实现,属于类定义的一部分。
当然类的static函数在类内声明、类外定义时,类内要写明static 类外则不能加static关键字,否则也会出现编译错误,代码如下:
class box{
public:
static int f();
};
/*错误的写法
static int box::f(){
return 0;
}
*/
//正确的定义
int box::f(){
return 0;
}
int main(){
return 0;
}
普通成员函数隐藏有this指针,this指针指向类的对象本身,普通成员函数总是属于某个类的具体对象。
静态成员函数由于没有和任何对象关联,所以,它没有this指针。
从这个角度,它无法访问属于类对象的非静态数据成员 和 非静态的成员函数
另外,对于非静态成员变量,需要用到类的对象来进行调用,这里就涉及到this指针的概念:
静态成员函数由于没有传递this 指针,所以静态成员函数只能访问static 成员,而不能访问非static 成员。this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。换句话说,你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。在成员函数的内部,我们可以直接使用调用该函数的对象的成员,而无需通过成员访问运算符来做到这一点,因为this所指的正是这个对象。任何对类成员的直接访问都被看成this的隐式使用。this的目的总是指向这个对象,所以this是一个常量指针,C++中不允许改变this中保存的地址
class box{
private:
int _non_static;
static int _static;
public:
int a(){
return _non_static;
}
static int b(){
//_non_static=0; 错误
//静态成员函数不能访问非静态成员变量
return _static;
}
static int f(){
//a(); (不对,静态成员函数不能访问非静态成员函数)
return b();
}
};
int box::_static= 0;//static 静态成员变量可以在类的外部修改
int main(){
box box1;
box* pointer=&box1;
box1.a();
pointer->a();
box::b();//类名::静态成员函数名
return 0;
}
static静态变量与全局变量的对比
静态数据没有进入全局名字空间,不存在与全局名字冲突。
可以实现信息隐藏,如静态局部变量为 private
volatile类型
volatile是一个类型修饰符,用来修饰被不同线程访问和修改的变量。volatile 变量,系统每一次使用时直接对应的内存中提取,而不是从cache中提取。定义为volatile变量是指这个变量可能会被意想不到的改变,编译器不会假设这个变量的值,即优化器在用到这个变量时必须每次都小心的重新读取这个变量的值(from Memory),而不是使用保存在寄存器里面的备份。
const 变量
c语言中 const,主要用于 定义变量为常类型 以及 修饰函数参数与返回值。C++中,还可以修饰函数定义,定义类的成员函数。常类型的变量或这个对象是不能更新的。
由于const 常量不能改变,所以,定义const 常量要初始化。
const的作用
const常量,具有不可变性。
进行类型检查,使编译器对处理类容有更多的了解,消除了一些隐患。
避免意义模糊的数字出现,可以很方便的进行参数调整和修改,类似于宏定义。
const int MAX = 100;
int array[MAX];
保护被修饰的类容,防止被意外修改,增强程序健壮性。
void f(const int i) {
i = 10; // 编译器会报错
}
为函数重载提供参考
非const对象调用的是没有const修饰的函数,而const对象调用的是用const修饰的函数。
因为类的成员函数的参数中,其实还有一个隐式的this指针,它会在在调用的时候传入。
在非const修饰的函数中,this指针也是非const的。在const修饰的函数中,this指针是const修饰的。
函数重载提供参考 部分参考链接:C++类中const修饰的函数与重载_函数返回值带const是不是重载_物随心转的博客-CSDN博客
节省空间,避免必要的内存分配
const常量从汇编角度,只给出了对应的内存地址,不像#define 给出的是立即数。所以,const常量只有一份复制品,#defone有很多复制品。
提高程序效率
编译器不为普通const常量分配存储空间,将他们保存在符号表中,没有了存储和读内存的操作。