由變量值交換編程題想到的(C++與Java機制的不一樣)

今天網上看到一個老套的編程題,就是「不用第三個變量進行兩個變量的值交換」。是一個同窗把java寫的答案放在網上求別人解析一下。平時由於作題用的都是C++,因此好奇瞄了一眼,卻發現實現方法與C++大相徑庭,而且,Java和C++算數表達式解析的機制也存在很大不一樣。好吧,咱們先來看看這個例子吧。
java

Java實現:(本文出自:http://my.oschina.net/happyBKs/blog/416632)ios

public static void main(String[] args) {
		// TODO Auto-generated method stub
		int x=4;
		int y=5;
		
		x=y+(y=x)*0;		
		System.out.println("x="+x+", y="+y);
	}

結果是:編程

x=5, y=4app

這裏我若是將表達式改成x=(y=x)*0+y; 函數

那麼結果就是 x=4, y=4oop

這個例子,我相信你們能猜出其中的緣由:Java在解析表達式時是從左向右執行的。測試

詳細地說,在這個賦值語句中,先執行右邊的算數表達式。執行以前x=4, y=5this

算術表達式又按照從左到右的順序執行,最左邊y+先執行。這時候 x=4, y=5.沒有任何變化spa

右邊是(y=x)*0再從左向右看,首先是(y=x),執行以後,x=4, y=4. y變了!.net

(y=x)*0顯然是0。

(y=x)*0+y則是0+y=0+4=4,賦給了賦值表達式左邊的x。這時候,x=5, y=4


那麼,若是在C++中的話,會怎麼樣呢?

代碼和結果是這樣的:

#include <iostream>
#include <stdlib.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {
	int x=4;
	int y=5;
	//x=(y=x)*0+y;
	x=y+(y=x)*0;
	printf("x=%d, y=%d",x,y);
	system("pause");
	return 0;
}

我將x=(y=x)*0+y;和x=y+(y=x)*0;兩個表達式都實驗了一下。結果答案都是:

x=4,y=4

這彷佛說明了,在解析算數表達式時,執行不存在像Java那樣的從左到右的順序。同時,也不是從右向左的。

C++中的執行更像是這樣一種狀況執行了這樣一個內聯函數。(我推測的)

x=4,y=5

inline void fn(int x1, int y1)

{

x1=x;

y1=y;

y=x1;

x=y1+y1*0;

}


這彷佛有點仍是使人難以信服。那麼咱們就完全跑個題吧,來看兩個同樣的代碼例子,可是分別放到了Java和C++編譯和運行環境中。

在java中的一個例子:

public static void main(String[] args) {
		int a=1;
		int b,c,d;
		d=(b=a++)+(c=a++)+(a++);
		System.out.println("a="+a+", b="+b+", c="+c+", d="+d);
	}

運行結果:

a=4, b=1, c=2, d=6

在C++中:

#include "stdafx.h"
#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[])
{
int a=1;
int b,c,d;
d=(b=a++)+(c=a++)+(a++);
printf("a=%d, b=%d, c=%d, d=%d",a,b,c,d);

	system("pause");
	return 0;
}

運行結果:

上面的C++代碼在gcc和VC下都進行了測試。


若是我把上面的例子再改一下。改成:

java:

public class TestMain {

	public static void main(String[] args) {
		int a=1;
		int b,c,d;
		d=(b=++a)+(c=++a)+(++a);
		System.out.println("a="+a+", b="+b+", c="+c+", d="+d);
		
		
	}

運行結果:

a=4, b=2, c=3, d=9


C++:

#include "stdafx.h"
#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[])
{
        int a=1;
        int b,c,d;

        d=(b=++a)+(c=++a)+(++a);
        printf("a=%d, b=%d, c=%d, d=%d",a,b,c,d);

	system("pause");
	return 0;
}

運行結果:

看到了吧。彷佛這時候,C++表達式也存在了從左到右的特性。Java任然亙古不變。


是否是有點暈了,C++到底怎麼了?

那麼咱們單獨再爲C++設置一個例子:此次我們裏面都是賦值。

int a=1, b=10, c=100, d=1000;
	d=(b=a)+(c=b)+a;
printf("a=%d, b=%d, c=%d, d=%d",a,b,c,d);
	system("pause");
	return 0;
}

結果是:

在修改個例子:若是d=(b=a)+(c=b)+++a;

運行結果是:

從上面的例子中已經能夠看出咱們以前下的結論了:Java在解析算數表達式時是從左向右執行的。C++解析算數表達式時, ++在前的因式須要在計算時就結算,而且從左向右執行。而=賦值則更像是在調用一個封裝了算術表達式和賦值功能的內聯函數。++在後的變量的累加操做在整個大表達式計算完成獲得值以後結算。(仍是整個表達式賦值以後結算?實際上是等價的)


若是有哪位朋友有更專業的解釋,請留言!謝謝!

相關文章
相關標籤/搜索