在程序開發中,++i 與 i++的區別在哪裡?


i++ 與 ++i 的主要區別有兩個:

1、 i++ 返回原來的值,++i 返回加1後的值。

2、 i++ 不能作為左值,而++i 可以。

毫無疑問大家都知道第一點(不清楚的看下下面的實現代碼就瞭然了),我們重點說下第二點。

首先解釋下什麼是左值(以下兩段引用自中文維基百科『右值引用』詞條)。

左值是對應內存中有確定存儲地址的對象的表達式的值,而右值是所有不是左值的表達式的值。

一般來說,左值是可以放到賦值符號左邊的變數。但

能否被賦值不是區分左值與右值的依據。比如,C++的const左值是不可賦值的;而作為臨時對象的右值可能允許被賦值。左值與右值的根本區別在於是否允許取地址運算符獲得對應的內存地址。

比如,

int i = 0;
int *p1 = (++i); //正確
int *p2 = (i++); //錯誤

++i = 1; //正確
i++ = 5; //錯誤

那麼為什麼『i++ 不能作為左值,而++i 可以』?

看它們各自的實現就一目了然了:

以下代碼來自博客:為什麼(i++)不能做左值,而(++i)可以

// 前綴形式:
int int::operator++() //這裡返回的是一個引用形式,就是說函數返回值也可以作為一個左值使用
{//函數本身無參,意味著是在自身空間內增加1的
*this += 1; // 增加
return *this; // 取回值
}

//後綴形式:
const int int::operator++(int) //函數返回值是一個非左值型的,與前綴形式的差別所在。
{//函數帶參,說明有另外的空間開闢
int oldValue = *this; // 取回值
++(*this); // 增加
return oldValue; // 返回被取回的值
}

如上所示,i++ 最後返回的是一個臨時變數,而臨時變數是右值


根本區別是語義上的區別,這個書上有,一個返回+之後的值一個返回+之前的值。

如果沒有用到返回值的話,區別在於效率。

  • 若i是內置的數值類型,兩者完全一樣
  • 若i是一些自定義的類,如iterator,++i的效率 &> = i++的效率

對於後者推薦都用++i;對於前者,用哪個是程序風格問題,i++的好處是更符合人類思維習慣,++i的好處是每次都用這種形式就不用考慮i的類型。


答:

(1)如果只是看i++和++i,這兩個是等價的,都等同於i=i+1,都是變數自身加1。

(2)在一般情況下,它們都是跟賦值聯繫在一起。

比如:

int a;

a=i++;//將i的值賦值給a,即a=i;然後再執行i=i+1;

也就是【a=i++;】與【a=i; i=i+1;】等價。

a=++i;//將i+1的值賦給a,即a=i+1;然後再執行i=i+1;

也就是【a=++i;】與【a=i+1;i=i+1;】等價。

(3)【總結一下】

①前置++是將自身加1的值賦值給新變數,同時自身也加1;

②後置++是將自身的值賦給新變數,然後才自身加1.


C++中

i++是

self opreator++(int)

{

self tmp = *this;

++(*this);

return tmp;

}

++i是

self opreator++()

{

++current;

return(*this);

}

++i與+=操作符等價



++i是左值,直接原地操作,效率高點,但現在誰還在乎這一點效率呢


在工作中把i++和++i用出區別的,都該拉出去槍斃。


1、首先,單獨拿出來說++i和i++,意思都是一樣的,就是i=i+1。

2、如果當做運算符來說,就是a=i++或者a=++i這樣的形式。情況就不一樣了。

先說a=i++,這個運算的意思是先把i的值賦予a,然後在執行i=i+1;

而a=++i,這個的意思是先執行i=i+1,然後在把i的值賦予a;

舉個例子來說,如果一開始i=4。

那麼執行a=i++這條語句之後,a=4,i=5;

那麼執行a=++i這條語句之後,i=5,a=5;

同理,i--和--i的用法也是一樣的。


++i是先處理完加法,再做其它運算, i++是處理完相關運算(執行完一條語句後)後自加


i++ 與 ++i 的關係. 好比i是一個姑娘,運算結果就是懷孕,那麼i++就是未婚先孕,i在前,++就是結婚的這個運算;++i就是先有++結婚這個運算,後懷孕i,就是已婚受孕。。。。。不知道這個比喻對不對


i++和++i的區別樓上各位都說了,我補充一些就行了。(i++)+(i++)+(++i)這類式子是沒有任何意義的,不用浪費時間糾纏在這個問題上,你只要會知道i++,++i,i--,--i這4個的區別,會用就夠了。那種複雜的式子,用不同的編譯器會編譯出不同的結果,討論這個沒意義


哪個在前就先操作哪個 i在前先用i再+ i在後先+再用


就像為什麼叫C++而不是++C一樣,C++是一種新的語言,++C是C的一個新的版本。


比如這個,拷貝一個字元串.用前綴型++就顯得怪怪的,而且還要麻煩很多...(話說第一次在C與指針里看到這麼用++的時候感覺風騷的不得了..)( 感謝@劉海洋的提醒,是....我究竟幹了什麼.....)


如果只是獨立的++i; 和i++; 是基本一樣的,到彙編都是一句Add或Inc指令(根據不同的編譯器可能會有差異);

如果是在如下環境:

int i = 0;

int j = 0;

j = ++i;

j = i++;

語義上是有差別的:++i 表示在用該表達式的值之前先使 i 的值增 1 ,i++ 表示在用該表達式的值之後再使 i 的值增 1 ;

性能上應該是一樣的(不確定,跟編譯器的實現有關),在VS2013下是這樣的:

j = ++i;

002E17DE mov eax,dword ptr [i]

002E17E1 add eax,1

002E17E4 mov dword ptr [i],eax

002E17E7 mov ecx,dword ptr [i]

002E17EA mov dword ptr [j],ecx

j = i++;

002E17ED mov eax,dword ptr [i]

002E17F0 mov dword ptr [j],eax

002E17F3 mov ecx,dword ptr [i]

002E17F6 add ecx,1

002E17F9 mov dword ptr [i],ecx


&
window.onload=function(){
var i=0;
var a=++i;
alert(a);
}
&

區別是a的區別,不是i的區別,i的值最終都是要+1


補充一點:++i得到左值,i++得到右值。


關於++i和i++的不同前面好多人都解釋了,我就不重複了,如果你學的c++的話,那推薦你一本書,裡面關於這種類似++i, i++不同點就有講到,對改善編程和提高代碼質量有很大的幫助,書名是&<&&>, :)


1

對於基本數值類型,看心情了。

2

自定義結構體或類 的迭代器,看具體情況具體討論,實在看不出就在構造和析構里加一個列印語句。以免造成不必要的開銷。

~~~~~~~~~~~

我沒做過實時系統、單片機、鍋爐、飛機導彈。


以a=1

i=a++/++a為例

共同點是兩個都分為兩步執行:

1.為新變數i 賦值

2.a自身增加1

不同點是第一步:

a++後置自增是將a的值賦給變數i,即i=1,a=2

++a前置自增則是將a+1的值賦給變數i,即i=2,a=2

前置自增和後置自增的區別是新變數的賦值不同,而自身的值相同。


推薦閱讀:

為什麼 C 語言對字元串的設計是用零結尾,而不是像 Pascal 一樣在字元串首指明長度?
計算機專業的學編程是怎麼套路?
有沒有一本講解gpu和CUDA編程的經典入門書籍?
有哪些語言的編譯器是用C++寫的? 為何選用C++

TAG:軟體開發 | 編程語言 | 編程 | C |