C/C++常量与变量的使用

C/C++常量与变量的使用

常量:

定义时设置初值,编译器将其放置一个只读的内存区域。

用处:

  • 程序多出使用一个常数值时,可以用常量代替。C采用define来进行定义,eg:#define PI 3.1415;而C++采用const来定义,eg:const float PI = 3.14159;
  • 在函数体中,不需要修改的参数定义常量。

变量:

分配内存,一般需要进行初始化,变量定义分为如下两步:

  • 变量声明:告知编译器变量的名称和数据类型
  • 变量定义:为变量分配存储区域

C++中的左值和右值

  • 左值:C语言中用出现在等号左边的为左值,C++中广泛认为:可以取地址的,有名字的就是左值
  • 右值:C语言中用出现在等号右边的为右值,C++中广泛认为:可以不能取地址的,有没有名字的就是右值。右值由两个概念组成:将亡值和纯右值。纯右值:临时变量(eg:非引用函数的return语句、一些运算表达式)、不跟对象关联的字面量值(eg:2,’a’,true)将忙值:将要被移动对象(移动为他用)

左值引用和右值引用

无论声明左值引用还是右值引用,都为引用类型,故必须立即初始化。
- 左值引用:C具有名字的变量名、能去地址的操作变量的别名
- 右值引用:C匿名(没有名字)的变量的别名 T&& a=ReturnRvalue();有一个临时变量来存放ReturnRvalue()返回的值,T a=ReturnRvalue()此形式赋值一结束,则临时变量的生存期也结束。而T&& a=ReturnRvalue()延长了临时变量的生存期,(优点:减少了a对象的构造以及临时对象的析构)
注意:右值的引用是不能绑定左值的,以及左值的引用是不能绑定右值的。
int c;
int && d=c;

常量左值引用是一个万能的引用,它能够接受非常量左值、常量左值、右值来对其初始化。
const T& f=ReturnRvalue()

变量存储四种类型

  • extern:声明而不定义变量,用于不同文件之间的通信(与全局变量之间通信)全局变量:函数体之外的变量,有着全局作用域。
  • static: 静态变量,全局生存期(即从文件执行开始到文件执行结束),局部变量:函数体之内的变量,有着局部作用域。
  • register: 变量放置在CPU中的寄存器中,只能作用于局部变量。常用于频繁访问的局部变量。
  • auto:动态变量,即根据表达式的结果类型来确定变量的类型,此变量的内存为动态分配(即随着程序运行而分配内存)

代码存储方式

  • 代码区:存放类成员函数、其它函数代码等。
  • 全局数据区:存放全局变量、静态变量、常量等。
  • 栈区:(随时更新数据),存放局部变量、函数参数、返回数据等。
  • 堆区:自由存储区

数据存储方式

  • 栈存储:存储空间小,生命周期短的数据,eg:局部变量、函数参数等。
  • 堆存储:存储占用空间大,生命周期长的数据,eg:静态变量,全局变量等。
  • new操作:在堆中开辟一个空间,使变量存储在堆中。故手动分配内存需要手动释放内存,否则造成内存泄漏。释放对象:delete p;释放对象数组:delete[] p。小窍门:释放内存时,把该指针设为nullptr,可以避免访问删除的指针错误。针对经常忘记释放内存,引入了智能指针:unique_ptr、shared_ptr以及weak_ptr。

常见错误

  • 函数返回值为地址或引用时:不要将局部自动变量返回过来,由于生存期引起的一系列问题
  • 实数之间的比较是否相等:不要用:==/!=。由于计算机中的实数(除开整数)都是按浮点数形式存储的,一般比较相等,定义一个精度,两者之差的绝对值小于此精度,则表示相等。
  • 实数之间相加:float、double存储实数都是有有效数字的限制的。一般float有效数字为6~7位,eg:float f=86041238.78,则此变量在计算机存储之后显示结果为:86041240.00。从而不要用一个较大的数加上一个非常小的数,会造成结果不变。

深入const常量

常量的值可以通过指针来修改,但输出值时const在C和C++中是有区别的(内存中的值实质修改了)。

  • C语言中,const修饰的变量为只读变量(会分配存储空间),访问时,会去它的地址读取内容。
  • C++语言中,const修饰的变量表示常量,而这种修饰也分内置类型和非内置类型。内置类型:const做的是一个替换工作(不会分配存储空间,只是把他们保存在符号表中,使得它们成为编译期间的常量,没有存储和读内存的操作,使得它的效率非常高);非内置类型:会去它的地址读取内容
    const int i=10;
    int *p=(int *)(&i);
    *p=20;
    printf("i=%d *p=%d \n",i,*p);

    C++中输出结果为10,20,i为10的原因:并没有去读内存中的内容;而C中输出结果为20,20。

volatile修饰的变量

volatile提醒编译器它后面所定义的变量随时都有可能改变。如果没有volatile关键字,则编译器可能优化读取和存储。

  • 告诉编译器不能做任何优化
  • 用volatile 定义的变量会在程序外被改变,每次都必须从内存中读取,而不能重复使用放在cache或寄存器中的备份。
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值