日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

面试常碰到++p/p--问题到底结果是什么?

發(fā)布時(shí)間:2023/11/28 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试常碰到++p/p--问题到底结果是什么? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

下面代碼輸出結(jié)果是什么?

int p = 5;
cout<<++p/p--<<endl;

是不是覺(jué)得面熟? 😄,看到這個(gè)題目的同學(xué),想必其中很多人在筆試面試過(guò)程中都碰到過(guò)這個(gè)問(wèn)題,但究竟結(jié)果是多少呢?
也許你心里面已經(jīng)有了答案!
1?++p 結(jié)果是6, 6/5 再?gòu)?qiáng)制轉(zhuǎn)成int, 那不就是1嘛!
結(jié)果真的是這樣嗎?下面是是實(shí)際運(yùn)行的結(jié)果。

root@LAPTOP-GV31B6PG:~/code/cpp/tmp$ cat main.cpp
#include <iostream>
using namespace std;int main()
{int p = 5;cout<<++p/p--<<endl;return 0;
}root@LAPTOP-GV31B6PG:~/code/cpp/tmp$ g++ -g main.cpp -o main
root@LAPTOP-GV31B6PG:~/code/cpp/tmp$ ./main
0

結(jié)果是0,是不是出乎意料,到底為什么呢?

下面帶大家分析一下這個(gè)問(wèn)題。自古:靠山,山會(huì)崩;靠地,地會(huì)陷;靠人,人會(huì)走。 人一輩子,靠天,靠地,不如靠自己;求天,求地,不如求自己。是的,必須要自己弄懂才行,要弄懂就得多動(dòng)手!
下面的分析會(huì)用到gdb,匯編的知識(shí),因此先給大家科普一下基礎(chǔ)知識(shí),如果對(duì)此熟悉的請(qǐng)略過(guò)這一段。

項(xiàng)目
AX――累加器(Accumulator),使用頻度最高
AX――累加器(Accumulator),使用頻度最高
BX――基址寄存器(Base Register),常存放存儲(chǔ)器地址
CX――計(jì)數(shù)器(Count Register),常作為計(jì)數(shù)器
DX――數(shù)據(jù)寄存器(Data Register),存放數(shù)據(jù)
SI――源變址寄存器(Source Index),常保存存儲(chǔ)單元地址
DI――目的變址寄存器(Destination Index),常保存存儲(chǔ)單元地址
BP――基址指針寄存器(Base Pointer),表示堆棧區(qū)域中的基地址
SP――堆棧指針寄存器(Stack Pointer),指示堆棧區(qū)域的棧頂?shù)刂?/td>
IP――指令指針寄存器(Instruction Pointer),指示要執(zhí)行指令所在存儲(chǔ)單元的地址。IP寄存器是一個(gè)專用寄存器。
(gdb) disassemble /rm
Dump of assembler code for function main():
5       {0x000000000800088a <+0>:     55      push   %rbp0x000000000800088b <+1>:     48 89 e5        mov    %rsp,%rbp0x000000000800088e <+4>:     48 83 ec 10     sub    $0x10,%rsp6               int p = 5;
=> 0x0000000008000892 <+8>:     c7 45 fc 05 00 00 00    movl   $0x5,-0x4(%rbp)7               cout<<++p/p--<<endl;0x0000000008000899 <+15>:    83 45 fc 01     addl   $0x1,-0x4(%rbp)0x000000000800089d <+19>:    8b 4d fc        mov    -0x4(%rbp),%ecx0x00000000080008a0 <+22>:    8d 41 ff        lea    -0x1(%rcx),%eax0x00000000080008a3 <+25>:    89 45 fc        mov    %eax,-0x4(%rbp)0x00000000080008a6 <+28>:    8b 45 fc        mov    -0x4(%rbp),%eax0x00000000080008a9 <+31>:    99      cltd0x00000000080008aa <+32>:    f7 f9   idiv   %ecx0x00000000080008ac <+34>:    89 c6   mov    %eax,%esi0x00000000080008ae <+36>:    48 8d 3d 6b 07 20 00    lea    0x20076b(%rip),%rdi        # 0x8201020 <_ZSt4cout@@GLIBCXX_3.4>0x00000000080008b5 <+43>:    e8 a6 fe ff ff  callq  0x8000760 <_ZNSolsEi@plt>0x00000000080008ba <+48>:    48 89 c2        mov    %rax,%rdx0x00000000080008bd <+51>:    48 8b 05 0c 07 20 00    mov    0x20070c(%rip),%rax        # 0x8200fd00x00000000080008c4 <+58>:    48 89 c6        mov    %rax,%rsi0x00000000080008c7 <+61>:    48 89 d7        mov    %rdx,%rdi0x00000000080008ca <+64>:    e8 71 fe ff ff  callq  0x8000740 <_ZNSolsEPFRSoS_E@plt>8               return 0;0x00000000080008cf <+69>:    b8 00 00 00 00  mov    $0x0,%eax
---Type <return> to continue, or q <return> to quit---9       }0x00000000080008d4 <+74>:    c9      leaveq0x00000000080008d5 <+75>:    c3      retqEnd of assembler dump.
(gdb)
  • 命令disassemble /rm 顯示反匯編, /r按照16進(jìn)制顯示數(shù)值,/m 顯示源代碼與匯編代碼對(duì)應(yīng)
  • 前三句初始配置函數(shù)棧幀
	0x000000000800088a <+0>:     55      push   %rbp  0x000000000800088b <+1>:     48 89 e5        mov    %rsp,%rbp0x000000000800088e <+4>:     48 83 ec 10     sub    $0x10,%rsp
  • 這段揭示了真實(shí)面目
7               cout<<++p/p--<<endl;0x0000000008000899 <+15>:    83 45 fc 01     addl   $0x1,-0x4(%rbp)0x000000000800089d <+19>:    8b 4d fc        mov    -0x4(%rbp),%ecx0x00000000080008a0 <+22>:    8d 41 ff        lea    -0x1(%rcx),%eax0x00000000080008a3 <+25>:    89 45 fc        mov    %eax,-0x4(%rbp)0x00000000080008a6 <+28>:    8b 45 fc        mov    -0x4(%rbp),%eax0x00000000080008a9 <+31>:    99      cltd0x00000000080008aa <+32>:    f7 f9   idiv   %ecx

mov -0x4(%rbp),%ecx 將上一句自增的值復(fù)制到寄存器%ecx, 注意到后面idiv除法運(yùn)算時(shí)候這是作為分母值,再看分子lea -0x1(%rcx),%eax%rcx值(也就是%ecx)6 - 0x1即5賦值給 %eax 分子的5。

這一步就是揭示了++p/p--的值也就是5/6取整后就是0,這下真相大白了。

總結(jié)

通過(guò)以上分析,使用gdb調(diào)試功能很大程度上幫助我們分析一些看似不好理解的表達(dá)式。例如++p/p--那樣,最終的計(jì)算實(shí)際是5/6的結(jié)果,取整輸出后就是0。

微信公眾號(hào)
第一時(shí)間獲取最新內(nèi)容,歡迎關(guān)注微信公眾號(hào):「程序員阿廣」。

總結(jié)

以上是生活随笔為你收集整理的面试常碰到++p/p--问题到底结果是什么?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。