c++ 输入输出流 的学习

前言

最近要准备面试,于是复习一下C++的语法。看起了C++ Primer这本书。

在看书上示例代码的时候,产生了一些疑惑。

话不多说,直接动手调试一遍吧。

示例代码

#include <iostream>

int main()
{
	// prompt user to enter two numbers
	std::cout << "Enter two numbers:"<< std::endl; 
	int v1 = 0, v2 = 0;
	std::cin >> v1 >> v2;   
	std::cout << "The sum of " << v1 << " and " << v2
	          << " is " << v1 + v2 << std::endl;
	return 0;
}

一个很简单的求两数之和的程序

调试

编译之后,使用disassemble main 指令看一下对应的汇编代码。

   0x0000555555555199 <+0>:	push   rbp
   0x000055555555519a <+1>:	mov    rbp,rsp
   0x000055555555519d <+4>:	sub    rsp,0x10
   0x00005555555551a1 <+8>:	mov    rax,QWORD PTR fs:0x28
   0x00005555555551aa <+17>:	mov    QWORD PTR [rbp-0x8],rax
   0x00005555555551ae <+21>:	xor    eax,eax
   0x00005555555551b0 <+23>:	lea    rsi,[rip+0xe4e]        # 0x555555556005
   0x00005555555551b7 <+30>:	lea    rdi,[rip+0x2ea2]        # 0x555555558060 <_ZSt4cout@@GLIBCXX_3.4>
   0x00005555555551be <+37>:	call   0x555555555050 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x00005555555551c3 <+42>:	mov    rdx,rax
   0x00005555555551c6 <+45>:	mov    rax,QWORD PTR [rip+0x2e03]        # 0x555555557fd0
   0x00005555555551cd <+52>:	mov    rsi,rax
   0x00005555555551d0 <+55>:	mov    rdi,rdx
   0x00005555555551d3 <+58>:	call   0x555555555060 <_ZNSolsEPFRSoS_E@plt>
   0x00005555555551d8 <+63>:	mov    DWORD PTR [rbp-0x10],0x0
   0x00005555555551df <+70>:	mov    DWORD PTR [rbp-0xc],0x0
   0x00005555555551e6 <+77>:	lea    rax,[rbp-0x10]
   0x00005555555551ea <+81>:	mov    rsi,rax
   0x00005555555551ed <+84>:	lea    rdi,[rip+0x2f8c]        # 0x555555558180 <_ZSt3cin@@GLIBCXX_3.4>
   0x00005555555551f4 <+91>:	call   0x555555555030 <_ZNSirsERi@plt>
   0x00005555555551f9 <+96>:	mov    rdx,rax
   0x00005555555551fc <+99>:	lea    rax,[rbp-0xc]
   0x0000555555555200 <+103>:	mov    rsi,rax
   0x0000555555555203 <+106>:	mov    rdi,rdx
   0x0000555555555206 <+109>:	call   0x555555555030 <_ZNSirsERi@plt>
   0x000055555555520b <+114>:	lea    rsi,[rip+0xe06]        # 0x555555556018
   0x0000555555555212 <+121>:	lea    rdi,[rip+0x2e47]        # 0x555555558060 <_ZSt4cout@@GLIBCXX_3.4>
   0x0000555555555219 <+128>:	call   0x555555555050 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x000055555555521e <+133>:	mov    rdx,rax
   0x0000555555555221 <+136>:	mov    eax,DWORD PTR [rbp-0x10]
   0x0000555555555224 <+139>:	mov    esi,eax
   0x0000555555555226 <+141>:	mov    rdi,rdx
   0x0000555555555229 <+144>:	call   0x555555555090 <_ZNSolsEi@plt>
   0x000055555555522e <+149>:	lea    rsi,[rip+0xdef]        # 0x555555556024
   0x0000555555555235 <+156>:	mov    rdi,rax
   0x0000555555555238 <+159>:	call   0x555555555050 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x000055555555523d <+164>:	mov    rdx,rax
   0x0000555555555240 <+167>:	mov    eax,DWORD PTR [rbp-0xc]
   0x0000555555555243 <+170>:	mov    esi,eax
   0x0000555555555245 <+172>:	mov    rdi,rdx
   0x0000555555555248 <+175>:	call   0x555555555090 <_ZNSolsEi@plt>
   0x000055555555524d <+180>:	lea    rsi,[rip+0xdd6]        # 0x55555555602a
   0x0000555555555254 <+187>:	mov    rdi,rax
   0x0000555555555257 <+190>:	call   0x555555555050 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x000055555555525c <+195>:	mov    rdx,rax
   0x000055555555525f <+198>:	mov    ecx,DWORD PTR [rbp-0x10]
   0x0000555555555262 <+201>:	mov    eax,DWORD PTR [rbp-0xc]
   0x0000555555555265 <+204>:	add    eax,ecx
   0x0000555555555267 <+206>:	mov    esi,eax
   0x0000555555555269 <+208>:	mov    rdi,rdx
   0x000055555555526c <+211>:	call   0x555555555090 <_ZNSolsEi@plt>
   0x0000555555555271 <+216>:	mov    rdx,rax
   0x0000555555555274 <+219>:	mov    rax,QWORD PTR [rip+0x2d55]        # 0x555555557fd0
   0x000055555555527b <+226>:	mov    rsi,rax
   0x000055555555527e <+229>:	mov    rdi,rdx
   0x0000555555555281 <+232>:	call   0x555555555060 <_ZNSolsEPFRSoS_E@plt>
   0x0000555555555286 <+237>:	mov    eax,0x0
   0x000055555555528b <+242>:	mov    rcx,QWORD PTR [rbp-0x8]
   0x000055555555528f <+246>:	xor    rcx,QWORD PTR fs:0x28
   0x0000555555555298 <+255>:	je     0x55555555529f <main()+262>
   0x000055555555529a <+257>:	call   0x555555555070 <__stack_chk_fail@plt>
   0x000055555555529f <+262>:	leave
   0x00005555555552a0 <+263>:	ret

整个程序就是输入两次分别存放到 rbp-0x10rbp-0xc 中 并求和输出。

可以看到每调用一次输入输出,就是调用一次函数。

虽然书上说,调用std::cout << << 这种写法等价于调用两次std::cout,但却是调用的不同的函数(因为地址根本不一样)。

string和传int值时,调用的函数也是不一样的。

大概看了一下std::endl的反汇编,调用流程如下 std::ctype -> std::cout -> std::ostream::flush

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值