i=i++計算過程還不會?C/C++的輸出語句與Java有何不同?-創(chuàng)新互聯(lián)

??作者主頁:微涼秋意
?作者簡介:后端領域優(yōu)質創(chuàng)作者🏆,內容合伙人🏆,阿里云專家博主🏆
?精品專欄:C++面向對象

成都創(chuàng)新互聯(lián)作為成都網(wǎng)站建設公司,專注網(wǎng)站建設、網(wǎng)站設計,有關企業(yè)網(wǎng)站制作方案、改版、費用等問題,行業(yè)涉及活動板房等多個領域,已為上千家企業(yè)服務,得到了客戶的尊重與認可。

文章目錄
  • 🔥前言
  • 1、第一題揭秘
    • 1.1、認為是100 的原因
    • 1.2、0 的正確打開方式
  • 2、第二題揭秘
    • 2.1、Java 中的printf 是格式化輸出
    • 2.2、C/C++ 打印時按照從右向左順序入棧
  • 3、 留一道課后作業(yè)


🔥前言

最近身邊的朋友分享了一些有趣的算法題給我,我看到題后直接不假思索的說出了我的答案,然而沒有一道說對的,頓時我的脾氣就上來了,通過查閱資料并與同學討論,最終從語言特點以及匯編層面解決了問題。接下來我把三道題目放出來,大家盡情作答,看看你是否能成功入坑。

第一題:你覺得i的結果為多少?A. 99 B. 100 C. 0

第一題

第二題:C/C++以及Java 輸出的結果會不會相同呢?A. 相同 B. 不相同

第二題在這里插入圖片描述

1、第一題揭秘

正確答案應該是 0:

在這里插入圖片描述

1.1、認為是100 的原因
i = 0;
i = i++;

如上,i++0++,把結果0賦給i,然后再進行加1操作,for循環(huán)了100次,那么最終i也遞增了100次,答案為什么不是100??

實際上,i確實遞增了,但是屬于 “無效遞增”。

1.2、0 的正確打開方式

不妨從JVM內存模型上分析,賦值運算符兩邊會分別進入內存中的兩個部分,前者是局部變量表,后者是操作數(shù)棧,對于i = 0來說,0會先進入操作數(shù)棧,i 進入局部變量表中,操作數(shù)棧彈出棧頂元素賦值給局部變量,也就是把 0 賦值給了 i;那么對于i = i++,i++ 首先入操作數(shù)棧,也就是操作數(shù)棧的棧頂是0++ ,局部變量表中的 i 會進行自增變?yōu)?1,最終操作數(shù)棧彈出棧頂,將 0 賦值給局部變量表中的 i。這樣無論進行多少次賦值操作,最終 i 的結果只能是 0。

而對于 i = ++i,操作數(shù)棧中進入的是 ++i,也就是操作數(shù)棧的棧頂元素等于1,局部變量表中的 i 自增后結果也是1,最后彈出棧賦值結果也會是1,因此對于 ++i 操作直接按照字面意思理解即可。

2、第二題揭秘

先來看一下打印結果吧:

Java 運行結果:
在這里插入圖片描述C/C++ 運行結果:
在這里插入圖片描述

可以清晰地看到 Java 的打印結果與 C/C++ 不同,在下面將做出我的解釋。

2.1、Java 中的printf 是格式化輸出

諸如%d、%f%s分別代表著整型、浮點型、字符串類型的占位符,在進行打印的時候會被后續(xù)的變量替代。在a為 2 時,a++的結果為 2 ,自增后 a 變?yōu)?3,然后進行++a,結果為 4,而 Java 的打印結果也確實如此。

按照同樣的理解,為什么 C/C++ 中的結果是 3 4 呢?這就涉及到了 函數(shù)調用約定 問題,printfcout參數(shù)是右向左進行入棧操作的。那到底這個入棧操作是怎么進行的呢,那就往下看看匯編的指令吧!

2.2、C/C++ 打印時按照從右向左順序入棧

匯編層面解析printf函數(shù)執(zhí)行順序:

匯編

由上面匯編指令得知執(zhí)行流程為:

  1. 先處理最后一個參數(shù)++a
    • 通過 mov 傳送指令將 內存中a對應的值傳送到累加器 eax 中
    • 累加器進行加 1 操作后將此值再次送回內存
  2. 然后處理參數(shù)a++
    • 先將此時 a對應的值傳送到寄存器 ecx 中,然后存儲到另一個內存單元中,為了方便描述,將該內存單元稱為temp
      • mov 指令不允許兩邊的操作數(shù)同時為內存,因此使用 ecx 作為媒介
    • 隨后將 a 對應的值送到寄存器 edx 中并進行加 1 操作并重新送入原內存中
  3. 運算完后,將 a 對應的值傳送到 eax 中通過 push 指令入棧,將 temp 內存對應的值送到 ecx 中也通過 push 入棧,最后將剩余字符串入棧,調用函數(shù),完成打印。

結果分析:

a++的結果就是臨時存儲單元temp對應的結果,而此結果正是 3,++a的結果就是累加器 eax 存儲的值,該值經(jīng)過兩次 add 1 操作,從 2 變?yōu)榱?4,最終結果也就是 4。這也正是C 語言printf輸出的結果。

3、 留一道課后作業(yè)

對于C++中的cout執(zhí)行流程我便不做解釋,過程與printf一致,都是右向左先進行入棧操作,看了這么多,來一個練習題吧:

在這里插入圖片描述


最終打印結果為?我做個投票吧,一天后我在評論區(qū)公布答案,大家快來檢驗一波學習成果!

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

新聞名稱:i=i++計算過程還不會?C/C++的輸出語句與Java有何不同?-創(chuàng)新互聯(lián)
本文鏈接:http://muchs.cn/article26/egijg.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計、定制網(wǎng)站、商城網(wǎng)站App設計、網(wǎng)頁設計公司、網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設