想请教各路大神这个V1,V2地址不同什么机制导致的

链接:https://www.nowcoder.com/questionTerminal/9fd169364f4a42599aa7ade7f1c9bbd9?toCommentId=1860979
来源:牛客网
函数func的定义如下:
1
2
3
4
5
voidfunc(constint& v1,constint& v2)
{
std::cout << v1 <<' ';
std::cout << v2 <<' ';
}
以下代码在vs中输出结果为____。
1
2
3
4
5
6
intmain (intargc,char* argv[])
{
int i=0;
func(++i,i++);
return0;
}

以上为题干

以下为测试demo
#include "stdafx.h"
#include <iostream>

using namespace std;

void func(const int& v1, const int & v2)
{
cout << "&v1 = "<< &v1 << endl;
cout << "&v2 = " << &v2 << endl;
std::cout <<"v1 =  "<< v1 << ' ';
std::cout <<"v2 = "<< v2 << ' ';
}

int _tmain(int argc, _TCHAR* argv[])
{

int i = 0;
cout <<"&i = "<< &i << endl;
func(++i, i++);
system("pause");
return 0;
}

以下为VS2013测试结果
&i = 004FFA04
&v1 = 004FFA04
&v2 = 004FF938
v1 =  2 v2 = 0 请按任意键继续. . .

全部评论
我个人的理解是,首先你要理解++i和i++的区别,++i的处理方式是先自增然后后返回i本身,而i++的处理方式是先用一个临时变量保存i,之后将i自增,最后返回临时变量,注意不是返回i本身,这就意味着++i是一个左值,而i++是一个右值!此外函数的形参编译是从右向左编译的。现在你可以理解为什么v2是0了,函数先编译v2,因为v2是i未自增前的一个副本,所以v2=0,v1是i本身经过两次自增变成2。如果函数传入顺序是fun(i++,++i)此时输出1,2,又如果是fun(i++,i++)此时输出变成1,0。
点赞 回复
分享
发布于 2018-09-16 08:37
i++ 的结果是右值
点赞 回复
分享
发布于 2018-09-15 23:38
小红书
校招火热招聘中
官网直投
void func( const int & v2) {     //cout << "&v1 = "<< &v1 << endl;     cout << "&v2 = " << &v2 << endl;     //std::cout <<"v1 =  "<< v1 << ' ';     std::cout <<"v2 = "<< v2 << ' '; } int _tmain(int argc, _TCHAR* argv[]) {         int i = 0;         cout <<"&i = "<< &i << endl;         func(i++);         system("pause");         return 0; } &i = 0115FB70 & v2 = 0115FAA4 v2 = 0 请按任意键继续. . . 可以看到在 经过推理,最终落脚在i++,个人认为,在执行i++的之后会由编译器先制作一个副本变量,存储++之前需要处理的值,作用域类被严格限制。 最后做了个demo验证 #include "stdafx.h" #include <iostream> using namespace std; void func(const int& v1,const int & v2) {     cout << "&v1 = "<< &v1 << endl;     cout << "&v2 = " << &v2 << endl;     std::cout <<"v1 =  "<< v1 << ' ';     std::cout <<"v2 = "<< v2 << ' '; } int _tmain(int argc, _TCHAR* argv[]) {     int i = 0;     int a = 0;     cout << "&a = " << &a << endl;     const int &b = a++;     cout << "&b = " << &b << endl;     cout << "&a = " << &a << endl;     cout <<"&i = "<< &i << endl;     func(++i, i++);     system("pause");     return 0; } 希望大神可以帮忙找到标准语意相关的标准答案。
点赞 回复
分享
发布于 2018-09-16 00:01
#include<stdio.h> #include<stdlib.h> #include<string.h> void _fastcall ***(const int &a, const int &b) {     printf("a: %d, address of a: %p\n", a, &a);     printf("b: %d, address of b: %p\n", b, &b); } int main() {     int i = 1;     printf("i: %d, address of i: %p\n", i, &i);     printf("=======================\n");     ***(++i, ++i);     printf("=======================\n");     ***(++i, i++);     printf("=======================\n");     ***(i++, ++i);     printf("=======================\n");     ***(i++, i++);     printf("=======================\n");     system("pause");     return 0; } 拉一下反汇编看看,一目了然。i++因为涉及到先传参数后修改,所以实际上会被单独开辟一块内存放未修改之前的值。而对于++i来说,因为修改可以安稳地写回内存,所以不需要另外放。 输出是这样: i: 1, address of i: 000000062556F7C4 ======================= a: 3, address of a: 000000062556F7C4 b: 3, address of b: 000000062556F7C4 ======================= a: 5, address of a: 000000062556F7C4 b: 3, address of b: 000000062556F8A4 ======================= a: 6, address of a: 000000062556F8C4 b: 7, address of b: 000000062556F7C4 ======================= a: 8, address of a: 000000062556F904 b: 7, address of b: 000000062556F8E4 ======================= 明显看到,i++的地址不同,++i的地址相同。 另外值得一提的是,两次++i并不会如想象的那般输出3和2,而是统一的3,即便形参是int a和int b也同样如此。
点赞 回复
分享
发布于 2018-09-16 02:00

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务