先看看strcpy函数是如何定义的吧:
这个函数采用了一个高效的写法来处理赋值问题,具体也就是(*strDest++ = *strSrc++) != '/0'这个表达式,但是这个表达式在高效的同时,也会给一些新手以理解上的障碍。我第一次阅读这个表达式时,开始也有些疑惑,疑惑之源就是经常让人疑惑的++操作符了。我先说说我当时的疑惑吧,不知道你是否有跟我一样的疑惑。我当时是这样思考的:
1.这个表达式的最终能结果是怎么样的。(这个简单,要求一个表达式的值就要找其核心运算符——通常是处于最外层的优先级最低的那个运算符,在这个表达式中虽然‘=’号优先级最低,但是它在有圆括号包裹的里层,所以本表达式的核心运算符就是'!=',因而本表达式最终结果为一个布尔值)
2.确定比较对象,很容易定位到,那就是*strDest++ = *strSrc++跟'/0'比较
3.求'!='号的左值。我的疑惑具体就在这一步。*strDest++ = *strSrc++也是一个表达式,这个表达式所求的结果就是'='的左值,那么这个左值到底是什么呢。照大多数书籍的介绍后置++就是使用值之后,使值加1,乍一听很明白其实很玄乎,因为我们经常这样按照这样的理解方式去使用它,后果却是经常出错。开始我也是以这种方式去理解*strDest++ = *strSrc++的——*strSrc先将值赋给*strDest,让后strSrc和strDest都加1。到这里似乎没有问题。但是整个表达式的是什么,也就是要跟'/0'比较的值是什么,具体就是*strDest代表什么,是加之前的值,还是加之后的值,我犯晕了。[后面来解惑]
4.比较'!='的左值和右值,得出结果。
上面说到,我的疑惑主要在第三步,下面我来说下我是如何解决我的疑惑的。 其实产生疑惑的根源,还是我以前说的对++的概念理解不清,没有理解后置++(包括后置--)的本质。后置++、--其实就是分别执行了前置++、--使值加1、减1的操作之后再返回先前的值,而前置++、--是返回加1、减1之后的值。因而后置++、--在执行过程中还要多定义一个用于储存先前值的变量用于稍后返回。这也是为什们编程规范提议,能用前置++、--,就不要用后置,除非你想得到的是先前的值(如同本例这样)。[具体参见《c++编程规范101条规则、准则、最佳实践》第28条]
理解了后置++的本质以后,上面的疑惑就迎刃而解了。对于*strDest++ = *strSrc++这个表达式,我们应该这样来理解:
由于‘=’的执行顺序是从右至左,所以我们应该先考虑右边,对于 *strSrc++,因为++的优先级高于*号,所以先执行++,又由于是后置的,所以执行结果是是使strSrc指向后一个位置,返回的是加之前的位置,因为*strSrc得到的strSrc是加之前所指向位置的的值;对于左边同理得到*strDest是strDest加之前所指向的位置的值。然后将*strSrc赋给*strDest。最后表达式得到的是*strDest即strDest加之前的位置的值。
最后还要说一下,为什么strcpy返回的是char *,而不是空。这是为了更灵活的运用strcpy函数,我么拷贝的目的是什么,还不是想使用char *strDest的值,那么我们为何不返回它呢。++,--只能用于变量[用于自定义类型变量时要重载],而不能用于常量和表达式这也是我们一个经常出错的地方。