现在的位置: 首页 > 综合 > 正文

c语言——重提++运算

2013年09月14日 ⁄ 综合 ⁄ 共 1466字 ⁄ 字号 评论关闭

昨天晚上看了几个小时的《C Traps and pitfalls》感觉这里面讲的东西都是比较边缘的东西,自己水平还是有限,有点看不懂,不过对于其中的一个题目倒是发生了很大的兴趣:

练习 1-4. a+++++b的含义是什么?

事实上答案是很简单的,((a++)++)+b, 后来在参看答案的时候发现了这样一句话:这个式子从语法上面来说是不正确的,a++的结果不能作为左值。

对于++运算,前缀,后缀和别人谈得也是很多的,不过对于左值却谈得很少,因此决定对这个问题作一下了解。

首先我们来看看什么是左值。

左值 (lvalue):左值表达式是对一个变量存储的引用,变量存储表达式称为左值表达式,我们可以简单的理解为可以被赋值的表达式。

我们先来看看这个程序:

#include <stdio.h>
#include <stdlib.h>

int main(  )
{
    int a = 1  ;
 (a++)++ ;
 ++(++a) ;
 (++a)++ ;
 ++(a++) ;
    return 0 ;
}

编译的时候是不能通过的:error C2105: '++' needs l-value, 也就是说++运算符缺需要一个值参与++运算,我们知道++运算符是单目运算符,它缺少了一个值参与这个运算,当然就是不能编译通过的了。通过编译我们还可以知道问题出在

 (a++)++ ; 和++(a++) ; 这两个表达式上面。而这个原因是因为++a返回的值是左值,而a++返回的值不是左值。而导致这个原因的罪魁祸首在于c/c++对于递增运算的定义:

返回引用:

type& type::operator++( )
{
this.value += 1;
return *this;
}

返回值:

type& type::operator++( )
{
 type co(this);  this.value += 1;
return co;
}

在运算过程中,先将对象修改然后返回对象的运算称为前增量运算符,在运算符重载中采取返回对象引用的方式,否则称为后增量运算符,在运算符重载中采取返回对象值的方式。返回引用的函数是可以当左值的。

我们现在来做一个测试:定义一个函数max( int x , int y ) ; 看看在返回值的时候和返回引用的时候会有什么区别:

#include <iostream>
using namespace std ;

int& max( int x , int y ) ;

void main()
{
 int temp = 0 ;
 temp = max(2,3) = 4 ;
 cout << temp << endl ;
}

int& max( int x , int y )
{
 return x>y?x:y ;
}

这个程序中我们定义了一个max函数,返回两个整型数中比较大的一个,但是这里有一个比较难以理解的句子: temp = max(2,3) = 4 ; 实际上,这就使因为max()返回的是一个引用,可以被赋值的原因,我们现在把这个函数改成返回值的:

#include <iostream>
using namespace std ;

int max( int x , int y ) ;

void main()
{
 int temp = 0 ;
 temp = max(2,3) = 4 ;
 cout << temp << endl ;
}

int max( int x , int y )
{
 return x>y?x:y ;
}

现在就不能编译通过了:error C2106: '=' : left operand must be l-value

参考资料:

Andrew Koening . C Traps and pitfalls. 人民邮电出版社. 2002.13,129

Scott Meyers . Effctive c++ .  华中科技大学出版社. 2003. 64-68

抱歉!评论已关闭.