https://blog.csdn.net/weixin_40627841/article/details/88134780
const、volatile、static、extern、assert()、struct、typedef struct

const

const 在C++中是用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数。

作用

  • 修饰变量,说明该变量不可以被改变;
  • 修饰指针,分为指向常量的指针和指针常量,还有指向常量的指针常量;
  • 常量引用,经常用于形参类型,即避免了拷贝,又避免了函数对传入值得修改(建议使用);
  • 修饰成员函数,说明该成员函数内不能修改成员变量。

    使用

    常对象成员,只能在初始化列表中赋值
    常成员函数,常量对象调用此函数,不得修改类中的任何数据成员的值
    常对象,只能调用常成员函数、更新常成员变量 ``` // An highlighted block var foo = ‘bar’; class A { private: const int a; // 常对象成员,只能在初始化列表中赋值 public: // 构造函数 A() : a(0) { }; // 默认构造函数 A(int x) : a(x) { }; // 初始化列表

    // const可用于对重载函数的区分 int getValue(); // 普通成员函数,普通对象调用此函数 int getValue() const;
    // 常成员函数,常量对象调用此函数,不得修改类中的任何数据成员的值(除开被mutable修饰的成员) // Effective C++中建议“运用const成员函数实现出其non-const孪生兄弟”,用到强制类型转换 };

void function() { // 对象 A b; // 普通对象,可以调用全部成员函数 const A a; // 常对象,只能调用常成员函数、更新常成员变量 const A *p = &a; // 常量的指针,即指向常量的指针变量 const A &q = a; // 常量的引用

  1. // 指针
  2. char greeting[] = "Hello";
  3. char* p1 = greeting; // 指针变量,指向字符数组变量
  4. const char* p2 = greeting; // 指针变量,指向字符数组常量
  5. char* const p3 = greeting; // 指针常量,指向字符数组变量
  6. const char* const p4 = greeting; // 指针常量,指向字符数组常量

}

// 函数 void function1(const int Var); // 传递过来的参数在函数内不可变,拷贝传递 void function2(const char Var); // 参数指针所指内容为常量 void function3(char const Var); // 参数指针为指针常量 void function4(const int& Var); // 引用参数在函数内为常量,不可修改

// 函数返回值 const int function5(); // 返回一个常数 const int function5_1(){return 0;} //此处加不加const都一样,返回值是内置类型 const int function6(); // 返回一个指向常量的指针变量,使用:const int p = function6(); int const function7(); // 返回一个指向变量的指针常量,使用:int const p = function7(); ———————————————— 版权声明:本文为CSDN博主「Joey_PRC」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_40627841/article/details/88134780

  1. [<br />](https://blog.csdn.net/weixin_40627841/article/details/88134780)
  2. <a name="ooBkj"></a>
  3. # volatile
  4. Volatile关键字跟**const对应相反,是易变的,容易改变**的意思。
  5. <a name="wwyrp"></a>
  6. #### 易变性:
  7. 所谓的易变性,在汇编层面反映出来,就是两条语句,下一条语句不会直接使用上一条语句对应的volatile变量的寄存器内容,而是**重新从内存中读取**。
  8. <a name="pi152"></a>
  9. #### 不可优化特性:
  10. volatile告诉编译器,不要对我这个变量进行各种激进的优化,甚至将变量直接消除,保证程序员写在代码中的指令,一定会被执行。
  11. <a name="Vux7G"></a>
  12. #### 顺序性:
  13. 能够保证volatile变量间的顺序性,编译器不会进行乱序优化。volatile变量与非volatile变量的顺序,编译器不保证顺序,可能会进行乱序优化。同时,C/C++ volatile关键词,并不能用于构建happens-before语义,因此在进行多线程程序设计时,要小心使用volatile,不要掉入volatile变量的使用陷阱之中。
  14. <a name="NjN39"></a>
  15. # static
  16. **作用:隐藏、持久、初始化、**
  17. - 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在**静态区**,在main函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统会用默认初始值初始化;(用**static**定义全局变量时,放在源文件而不是头文件,防止其他源文件引用时对此项又申请一个内存)
  18. - 修饰普通函数,表明函数的作用范围:**仅在定义该函数的文件内才能使用。**在多人开发的项目时,为了防止与他人定义函数重名,可将函数定位为**static**;
  19. - 修饰成员变量,修饰成员变量使**所有的对象只保存一个该变量**,而且**不需要生成对象就可以访问该成员**,静态数据成员是类的成员,而不是对象的成员;
  20. - 修饰成员函数,修饰成员函数使得**不需要生成对象就可以访问该函数**,类的静态成员函数是属于整个类而非类的对象,所以它没有**this**指针,这就导致 了它仅能访问类的静态数据和静态成员函数。
  21. <a name="S2Gdp"></a>
  22. ## 备注
  23. - 静态成员初始化与一般数据成员初始化不同:<数据类型><类名>::<静态数据成员名>=<值>;
  24. - 存储在静态存储区的2种变量:全局变量、static变量,相比于全局变量,static可以控制变量的可见范围:比如static定义在**某个文件内**,则作用域为**整个文件**。static局部变量在**函数内**定义,则作用域仅在该函数内,但由于存储在静态区,所以**生存期为整个源程序**。
  25. [<br />](https://blog.csdn.net/weixin_40627841/article/details/88134780)
  26. <a name="drBQm"></a>
  27. # extern
  28. <a name="DhWBR"></a>
  29. #### 用法:
  30. 1. 变量的声明和定义中,C++中某些变量的声明和定义不在一个文件内,被分离开;

extern int i; //声明i而非定义,不申请存储空间 int j; //声明并定义i,申请存储空间

extern int v = 2; int v = 2; //这两个语句效果完全一样,都是v的定义,都申请存储空间 ``` 2.extern函数声明
如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。
注意:若把全局变量的声明和定义放在一起,连接时会报错误

  1. 多个文件中共享const对象,又不希望编译器为每个文件单独生成一个变量
    方法:对于const变量不管是声明还是定义都添加extern关键字,这样只需要定义一次就可以了

    extern与static

    (1)extern 表明该变量在别的地方已经定义过了,在这里要使用那个变量;
    (2)static 表示静态的变量,分配内存的时候, 存储在静态区,不存储在栈上面;
    (3)static 作用范围是内部连接的关系, 和extern有点相反.它和对象本身是分开存储的,extern也是分开存储的,但是extern可以被其他的对象用extern 引用,而static 不可以,只允许对象本身用它. 具体差别首先,static与extern是一对“水火不容”的家伙,也就是说extern和static不能同时修饰一个变量;其次,static修饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义了;最后,static修饰全局变量的作用域只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,其他编译单元则看不到它;

    extern与const

    C++中const修饰的全局常量具有跟static相同的特性,即它们只能作用于本编译模块中,但是const可以与extern连用来声明该常量可以作用于其他编译模块中, 如

    assert()

    断言,是宏,而非函数。assert 宏的原型定义在 (C), (C++)中,其作用是如果它的条件返回错误,则终止程序执行。可以通过NDEBUG来关闭 assert,但是需要在源代码的开头,include 之前。assert() 多用于在函数开始处检验传入参数的合法性,且一个assert()只检验一个条件;

    sizeof()

  2. sizeof 对数组,得到整个数组所占空间大小;(所占内存字节数)

  3. sizeof 对指针,得到指针本身所占空间大小;(与所指对象没有任何关系)
  4. 当字符数组表示字符串时,其 sizeof 值将 ‘/0’ 计算进去;
  5. sizeof 也可对函数调用求值,返回的是函数返回值类型的大小,函数不会被调用;(函数得带实参,不能对void 函数求值…)

    struct和typedef struct

    C 中
    定义1个结构体类型要使用typedef struct…

c++中用struct