您的位置:首页 > 编程语言 > C语言/C++

c++之左值

2016-05-06 01:01 561 查看
左值是c++中的一个基本概念,凡是可以出现在赋值运算左边的表达式都是左值。右值跟左值相对,凡是可以出现在赋值运算右边的表达式都是右值。

左值一定可以作为右值,而反过来不一定成立。

左值概念有:

(1)必须可寻址

(2)非只读单元

(3)不能是临时无名对象 如: i+1 =5 不行

(4)如果表达式运算结果是一个引用,可以作为左值。 如:int &fun() 函数可以,(i+=1)=5 可以,i+=运算结果是对i的引用

由此可知:

(1)并不是只有单个变量才能作为左值

(2)也不能仅由表达式的外在形式判断是否为左值。要根据一个表达式的运算结果的性质判断。

结合引用的性质可知:

(1)能建立普通引用的表达式一定是左值;

(2)不能作为左值的表达式只能建立常引用,而不能建立普通引用。

函数的参数声明为引用,这样在发生函数调用时可以减少运行时开销。将函数的参数声明为一般的引用还是声明为常引用很有讲究。

int Max(int &a,int &b) {
return (a>b)?a:b;
}

int main()
{
//freopen("input.txt","r",stdin);

int i=2;
cout<<Max(i,5)<<endl;

return 0;
}


以上代码编译不通过,显示“非常引用的初始值必须为左值”,由于5不是左值,不能为它建立普通引用,所以编译错误。于是在此时修改函数定义

int Max(int &a,const int &b);


可见:

将函数的参数声明为常引用,不完全是因为参数的值在函数体内不能修改,还可能是接受非左值作为函数参数的情况。

常引用类型转换

对某个变量(或表达式)建立常引用,允许发生类型转换,而一般的引用不允许

int Max(const int &a,const int &b) {
return (a>b)?a:b;
}

int main()
{
//freopen("input.txt","r",stdin);

char c='a';
const int &rc = c;
PRINT((void*)&c);
PRINT((void*)&rc);

int i=7;
const int &ri = i;
PRINT((void*)&i);
PRINT((void*)&ri);
cout<<Max(rc,5.5)<<endl;

return 0;
}


输出:



如果将下句的const去掉则会报错。原因是普通引用只能建立在相同的数据类型变量上。同样,能允许 Max(rc,5.5) 这样的函数调用也是因为函数 Max() 的第二个参数是常引用,因此将实参 5.5 先转换为 int 型无名变量,然后再建立对该无名变量的常引用。

const int &rc = c;


对表达式建立常引用:

(1)首先要考虑该表达式结果是否能寻址

(2)其次还要考虑表达式结果的数据类型与引用数据类型是否一致

否则只能另外建立一个无名变量,该变量中存放非左值表达式的运算结果,然后再建立对该无名变量的常引用。

不过既然这里建立的是一个临时的无名变量,但这个变量同时也占用栈空间,那就可以相办法改变,而且改变这个值不会改变原有的变量:

int main()
{
//freopen("input.txt","r",stdin);

char c='a';
const int &rc = c;
PRINT(c);
PRINT(rc);
PRINT((void*)&c);
PRINT((void*)&rc);

int dis = (int)&rc-(int)&c;
PRINT(dis);
int* addr = (int*)((int)&c+dis); //精确计算rc指向的无名变量的地址

*addr = 666;
PRINT(c);
PRINT(rc);

return 0;
}


输出:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: