请问 :程序开销有什么不同???

当我遇上-你 2009-04-27 09:23:17
下面的1和2有什么区别:
1:
void swap(int &a, int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
main()
{
int a=1,b=3;
swap(a,b);
return 0;
}
2:
void swap(int *p1, int *p2)
{
int *temp;
*temp=*p1;
*p1=*p2;
*p2=temp;
}
main()
{
int a=1,b=3;
swap(&a,&b);
return 0;
}
...全文
248 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
hjjdebug 2009-04-28
  • 打赏
  • 举报
回复
你这个例子太简单,不过就以这个简单例子说明问题吧。
1. 从函数实现上是完全等价的。 我们用汇编说话。(vc6.0 下)
希望你能看懂汇编。
: void swap(int &a, int &b)
5: {
......
6: int temp;
7: temp=a;
00401278 mov eax,dword ptr [ebp+8]
0040127B mov ecx,dword ptr [eax]
0040127D mov dword ptr [ebp-4],ecx
8: a=b;
00401280 mov edx,dword ptr [ebp+8]
00401283 mov eax,dword ptr [ebp+0Ch]
00401286 mov ecx,dword ptr [eax]
00401288 mov dword ptr [edx],ecx
9: b=temp;
0040128A mov edx,dword ptr [ebp+0Ch]
0040128D mov eax,dword ptr [ebp-4]
00401290 mov dword ptr [edx],eax
10: }

11: void swap(int *p1, int *p2)
12: {
......
13: int temp;
14: temp=*p1;
004012C8 mov eax,dword ptr [ebp+8]
004012CB mov ecx,dword ptr [eax]
004012CD mov dword ptr [ebp-4],ecx
15: *p1=*p2;
004012D0 mov edx,dword ptr [ebp+8]
004012D3 mov eax,dword ptr [ebp+0Ch]
004012D6 mov ecx,dword ptr [eax]
004012D8 mov dword ptr [edx],ecx
16: *p2=temp;
004012DA mov edx,dword ptr [ebp+0Ch]
004012DD mov eax,dword ptr [ebp-4]
004012E0 mov dword ptr [edx],eax
17: }

2. 从函数调用上也是完全等价的。
21: swap(&a,&b);
00401326 lea eax,[ebp-8]
00401329 push eax
0040132A lea ecx,[ebp-4]
0040132D push ecx
0040132E call @ILT+0(swap) (00401005)
00401333 add esp,8
22: swap(a,b);
00401336 lea edx,[ebp-8]
00401339 push edx
0040133A lea eax,[ebp-4]
0040133D push eax
0040133E call @ILT+15(swap) (00401014)
00401343 add esp,8

你是不是有点糊涂啊? 函数调用和函数实现都完全一样。 是,我也有点糊涂,不过想象一下是对的。
因为传引用也是传指针,所以无论是函数调用还是函数实现都完全一样。
那么引用和指针到底有什么差别呢?
引用是c++引入的概念,c中是没有引用的。
用过c的人都知道,80%以上的错误是指正引起的。指针太容易出错了。
c++引入了引用,叫变量的别名。这样我们不在用指针,而是直接用引用名称来表示变量。举例说
就是原来用*temp 表示变量, temp 表示指针,如果你一烦糊涂或疏忽大意,把*temp 写成temp, 就错了。而且很难查。

引用用temp来表示变量。 有时候(大部分),我们只关心变量,不关心变量存储的地址。
所以我们操作temp=a, b=temp, 它就不会引入错误,因为这些都只是数据的交换。

好,上面说清了对人的接口这个层次。下面再说实现上层次。
在实现上,编译器把引用当作指针处理,因为它要取到数据,必须要知道数据地址,这是跑不了的。

综上述,我们得出结论:
引用是方便我们操作数据的一种表现形式,其实质,就是说在实现上与指针是完全等价的
ljhiiiiiiii 2009-04-28
  • 打赏
  • 举报
回复
在C++中引用的实现是靠指针来实现的。所以本质上两者等价。
但对于别的语言C#、Java等语言来说引用的概念是不同的。
appleshao 2009-04-28
  • 打赏
  • 举报
回复
引用实际上就是指针,这个问题记得在某本黑客调试书里有看到过他的本质.
当我遇上-你 2009-04-28
  • 打赏
  • 举报
回复
谢谢
  • 打赏
  • 举报
回复
void swap(int *p1, int *p2)
{
int temp; // 这里有错,帮你改了
temp=*p1;
*p1=*p2;
*p2=temp;
}


然后就是,传指针开销大一点,因为多了个指针副本。但是其实号称引用也不传说中完全不开销,它也需要维护的。
firstdad 2009-04-27
  • 打赏
  • 举报
回复
个人觉得引用的效率比较高, 但结果是一样的。

传指针的话,指针也要赋值( 也就是相当于int赋值)
引用也是别名,也就免去了赋值。
jackyjkchen 2009-04-27
  • 打赏
  • 举报
回复
开销是差不多的,引用实际上就是取地址,&是取地址符,与解引用符*相对,也属于指针操作,但是比较安全,因为功能比较单一就是取个地址。

指针本身效率就属于C中最高的了吧,要知道指针哪怕是间接操作,但至少没有 复制内容 等耗时的工作,内存的读写速率通常在几G到几十G每秒,指针连这个时间都省了。

看看反汇编吧,也许有不同,大家推荐能用引用就别用指针不是为了效率,而是为了安全和程序可读性、可维护性,引用毕竟比较容易
yangch_nhcmo 2009-04-27
  • 打赏
  • 举报
回复
使用引用的效率比较高,
引用访问一个变量是直接访问,而指针是间接访问
lingyin55 2009-04-27
  • 打赏
  • 举报
回复

g++反编了下,引用和传指针都是一样的,在函数内得到就是地址.
//void swap(int &a,int &b)
//void swap(int *a,int *b)
//{
//a += 5;
//b += 6;
//}
movl 8(%ebp), %edx //把a的地址暂存起来
movl 8(%ebp), %eax //把a的地址放到eax寄存器中
movl (%eax), %eax //把a的值mov到eax中,以便进行操作
addl $5, %eax //加5
movl %eax, (%edx) //通过eax完成了对a的操作
lingyin55 2009-04-27
  • 打赏
  • 举报
回复
传指针:传“指针对象的值”,只需要对这个指针对象进行拷贝,而不必拷贝指针所指对象的值;
传引用:在语言层面上讲是传数据/对象本身,不会引起拷贝。从编译器实现的层面上讲,很可能就是通过“传指针”来实现的
zhangjundriver 2009-04-27
  • 打赏
  • 举报
回复
你第二个swap都是错误的,temp都是个野指针

如果效率上说,使用第一种明显要好很多的,
使用引用比使用指针要安全很多,不需要作额外的安全检查,第二中就需要做安全检查了。只不过你没有做而已,如果别人调用你的函数采用null来作为参数呢?程序崩溃就要了。
liliangbao 2009-04-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 goodname 的回复:]
2:
void swap(int *p1, int *p2)
{
int *temp; <----------------应该是int temp,写错了吧。
[/Quote]
具体的开销吗~
引用的内部实现听说也是使用指针,等高手了~
pengzhixi 2009-04-27
  • 打赏
  • 举报
回复
个人觉得void swap(int *p1, int *p2)开销大些吧
goodname 2009-04-27
  • 打赏
  • 举报
回复
2:
void swap(int *p1, int *p2)
{
int *temp;<----------------应该是int temp,写错了吧。

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧