C++复习之路:1.Static、const相关:作用,使用场景,struct和class

作用:

  1. Static用于定义静态变量,包括全局和局部的静态变量,两者的共同点:

  • 都存储在内存中的静态存储区;
  • 都是整个程序结束后才会被释放,否则一直存在,尤其是多次调用时,新一次的调用的初始值为上一次调用后的结果;

不同点:

  • 全局静态变量作用域为从定义之处到文件结尾,而局部静态变量作用域为定义之处开始到函数结束,但是函数结束后该局部变量在内存中并不会被销毁,等再次调用该函数时可以继续访问。

2.Static用于定义静态函数;

  • 作用于整个.cpp文件中,一般定义于cpp头部;
  • 好处:不同cpp文件中用static修饰的同名函数互相不会干扰。(作用域局限于所处文件)
  • 静态函数、静态变量不在头文件中定义是因为多个cpp使用该静态函数或者变量,看起来用的是文件全局的变量、或函数,但实际上对于每个cpp来说,输出该变量、函数的地址并不相同,相当于头文件被多少个cpp调用,头文件中的静态变量或函数就被定义了多少次。正确的头文件中的全局变量的定义应该是用extern修饰,例如: extern int a;(此时不能初始化其值)然后在别的cpp中定义一次(例如:int a=1;)即可全局使用

3.Static用于定义类中的静态成员变量、函数

  • 静态成员变量相当于被该类的对象共有,同时不会破坏隐藏数据的规则(即会受到public等的限制),

类中定义,类外初始化使用的时候只需要   类名::变量  或  类对象名. 变量   即可

  • 静态成员函数也是被该类的对象共有,使用的时候只需要   类名::函数(参数)  或  类对象名. 函数(参数)   即可;但是需要注意的是一般静态函数中无法调用非静态成员,除非把非静态对象作为参数传入静态函数,如:

不能直接调用的原因是非静态成员只有初始化之后才能调用,如果在类中静态函数里直接 调用时非静态成员尚未初始化,导致报错。将其作为参数传入函数,才能使用。

4.Const的用法

例如:const char * arr = "123";

//字符串123保存在常量区,const本来是修饰arr指向的值不能通过arr去修改,但是字符串“123”在常量区,本来就不能改变,所以加不加const效果都一样

char * brr = "123";

//字符串123保存在常量区,这个brr指针指向的是同一个位置,同样不能通过brr去修改"123"的值

const char crr[] = "123";

//这里123本来是在栈上的,但是编译器可能会做某些优化,将其放到常量区

char drr[] = "123";

//字符串123保存在栈区,可以通过drr去修改

Const:1)修饰常量

   const可以修饰常量,使该常量的值不能改变,局部变量与全局变量都一样,定义时就要赋值。

2)修饰指针:指针不能改变

3)修饰函数

3.1)const修饰函数的参数● 防止修改指针指向的内容或指针本身;

3.2)const修饰函数的返回值,那么函数返回值(指针)的内容就不能被修改,该返回值只能被附加给加const修饰的同类型返回值(指针)。

4)const修饰成员变量:const修饰类的成员函数,表示成员常量,不能被修改,同时它只能在初始化列表中或初始化时赋值。如: const int nValue=10;         //成员常量不能被修改

        A(int x): nValue(x) { } ; //只能在初始化列表中赋值

5)const修饰成员函数:则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰。如: void function()const; //常成员函数, 它不改变对象的成员变量.   

a. const成员函数不被允许修改它所在对象的任何一个数据成员。

b. const成员函数能够访问对象的const成员,而其他成员函数不可以。

 

 

 5.define 、enum和const的区别(编译阶段、安全性、内存占用等)

1.define可以用来定义常量字符、数字和表达式(如:#define a 15+5)

但是需要注意的是这里的定义是替换,如:a*a会被替换成15+5*15+5;(这可能造成计算结果的差异)

Define还可以用来定义简单的函数,如:#define M(y)(y*y)

最后还能用来防止重复定义,如#ifndef __headerfileXXX__

  #define __headerfileXXX__

 

Const用来修饰常类型的对象,修饰部分(先看左侧最近部分,没有再看右侧

const int* p1 = &Year;

int const *p2 = &Year; //p1和p2是同种类型的,指向内容不能变

int* const p3 = &Year; //p3指针所指向的地址不能变

const int* const p4 = &Year; //p4指针所指向的地址和指向内容都不能变

程序编译的四个阶段:预处理—->编译—->汇编—->链接,最后开始运行。 

 

枚举enum只能以标识符形式表示,不能为数字或字符常量,

enum week {Sun, Mon, Tue, Wed, Thu, Fri, Sat}; // 定义枚举类型week,默认从0开始依次加1

 

Enum相当于一系列的define操作

在没有显示说明的情况下,枚举常量(也就是花括号中的常量名)默认第一个枚举常量的值为0,往后每个枚举常量依次递增1。或者其中某个赋值之后,后续默认+1 。需要注意的是不能同名

变量是全局变量的情况下, 枚举值的缺省值是0,不是枚举的第一个值。局部变量时候默认值为1。 其他情况,其值是随机的,而且不限定于所列出的枚举值

=0

X1=0,x2=1,x3=10,x4=11,x5=12

总结:#define注重预处理的替换,const倾向于常类型的变量或对象,enum更偏向于一种自定义的数据类型,建议多使用const作为常量表达方式,原因是适用范围广且容易排查错误。

一:区别


(1)就起作用的阶段而言: #define是在编译的预处理阶段起作用,而const是在 编译、运行的时候起作用。
(2)就起作用的方式而言: #define只是简单的字符串替换,没有类型检查。而const有对应的数据类型,是要进行判断的,可以避免一些低级的错误。 
(3)就存储方式而言:#define只是进行展开,有多少地方使用,就替换多少次,它定义的宏常量在内存中有若干个备份;const定义的只读变量在程序运行过程中只有一份备份。
(4)从代码调试的方便程度而言: const常量可以进行调试的,define是不能进行调试的,因为在预编译阶段就已经替换掉了。

二:const优点


(1)安全性方面:const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
(2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。
(3)const可节省空间,避免不必要的内存分配,提高效率

 

 

Struct和class的区别

1内部成员变量及成员函数的默认防控属性
struct默认防控属性是public的,而class默认的防控属性是private的;并且在继承的时候也是struct默认public继承,class默认private继承;

class这个关键字还可用于定义模板参数,就像typename。但是strcut不用定义模板参数

赋值时class无法用{}赋值,但是struct在内部没有构造函数或虚函数的时候可以。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溯夜流云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值