C中不使用临时变量交换两个变量的值
2005-12-29 21:14
447 查看
C中不使用临时变量交换两个变量的值
作者:yxin1322
blog:http://blog.csdn.net/yxin1322 转载请注明出处
前两天同学去面试,碰到一道C算法题,要求不使用额外的临时变量而交换两个变量的值,这个问题以前曾经在qq群里和人讨论过,所以有点印象,具体实现同样是三句赋值语句,只是巧妙的运用了和与差的运算来达到交换的目的。
ExchangeValue2是传统的交换方法,用到了一个临时变量。ExchangeValue1没有用到临时变量,只是通过两变量间的加减运算就完成了变量值的“交换”,这种方法看起来还是很新颖的,但它只适合于交换支持加减运算的值类型,如果是两个结构体变量或类对象就没办法了,只能乖乖地用临时变量来中转。那么哪种方式要高效一点呢?看以下反汇编代码:
15: //不使用临时变量
16: void ExchangeValue1(int * a, int * b)
17: {
004010AC push ebp
004010AD mov ebp,esp
18: *a=*a+*b;
004010AF mov eax,dword ptr [a]
004010B2 mov edx,dword ptr
004010B5 mov edx,dword ptr [edx]
004010B7 add edx,dword ptr [eax]
004010B9 mov eax,dword ptr [a]
004010BC mov dword ptr [eax],edx
[b]19: *b=*a-*b;
004010BE mov eax,dword ptr [a]
004010C1 mov edx,dword ptr
004010C4 mov edx,dword ptr [edx]
004010C6 neg edx
004010C8 add edx,dword ptr [eax]
004010CA mov eax,dword ptr [b]
004010CD mov dword ptr [eax],edx
[b]20: *a=*a-*b;
004010CF mov eax,dword ptr [a]
004010D2 mov edx,dword ptr
004010D5 mov edx,dword ptr [edx]
004010D7 neg edx
004010D9 add edx,dword ptr [eax]
004010DB mov eax,dword ptr [a]
004010DE mov dword ptr [eax],edx
[b]21: }
004010E0 leave
004010E1 ret
22:
23: //使用临时变量
24: void ExchangeValue2(int * a , int * b)
25: {
004010E2 push ebp
004010E3 mov ebp,esp
004010E5 push esi
004010E6 push eax
004010E7 push edi
004010E8 push ecx
004010E9 mov edi,ebp
004010EB sub edi,4
004010EE mov ecx,1
004010F3 mov eax,0CCCCCCCCh
004010F8 rep stos dword ptr [edi]
004010FA pop ecx
004010FB pop edi
004010FC pop eax
26: int c;
27: c=*a;
004010FD mov eax,dword ptr [a]
00401100 mov eax,dword ptr [eax]
00401102 mov dword ptr [c],eax
28: *a=*b;
00401105 mov eax,dword ptr
00401108 mov edx,dword ptr [a]
0040110B mov eax,dword ptr [eax]
0040110D mov dword ptr [edx],eax
[b]29: *b=c;
0040110F mov eax,dword ptr
00401112 mov edx,dword ptr [c]
00401115 mov dword ptr [eax],edx
[b]30: }
00401117 leave
00401118 ret
以上是VC的反汇编代码,可以看出来ExchangeValue1被译成了24条汇编代码,而ExchangeValue2被译成了26条汇编代码,从代码条数上来看两种方法差不多。不过这里的代码是VC在debug模式下生成的,没有经过优化,加上ExchangeValue1有多次ADD操作,而ExchangeValue2有多次push、pop和stos操作,各种指令的执行周期也不同,所以很难判断哪种方法更好,况且对于这么一个小问题来分析它的执行效率似乎有点小题大作,我就不往下分析了。有兴趣的朋友可以继续分析一下,只是别忘了把结果告诉我哦!
作者:yxin1322
blog:http://blog.csdn.net/yxin1322 转载请注明出处
前两天同学去面试,碰到一道C算法题,要求不使用额外的临时变量而交换两个变量的值,这个问题以前曾经在qq群里和人讨论过,所以有点印象,具体实现同样是三句赋值语句,只是巧妙的运用了和与差的运算来达到交换的目的。
1 #include <stdio.h> 2 3 void ExchangeValue1(int * a,int * b); 4 void ExchangeValue2(int * a,int * b); 5 6 main() 7 { 8 int a=1; 9 int b=2; 10 printf("a=%d,b=%d/n",a,b); 11 ExchangeValue1(&a,&b); 12 printf("a=%d,b=%d/n",a,b); 13 } 14 15 //不使用临时变量 16 void ExchangeValue1(int * a,int * b) 17 { 18 *a=*a+*b; 19 *b=*a-*b; 20 *a=*a-*b; 21 } 22 23 //使用临时变量 24 void ExchangeValue2(int * a , int * b) 25 { 26 int c; 27 c=*a; 28 *a=*b; 29 *b=c; 30 }
ExchangeValue2是传统的交换方法,用到了一个临时变量。ExchangeValue1没有用到临时变量,只是通过两变量间的加减运算就完成了变量值的“交换”,这种方法看起来还是很新颖的,但它只适合于交换支持加减运算的值类型,如果是两个结构体变量或类对象就没办法了,只能乖乖地用临时变量来中转。那么哪种方式要高效一点呢?看以下反汇编代码:
15: //不使用临时变量
16: void ExchangeValue1(int * a, int * b)
17: {
004010AC push ebp
004010AD mov ebp,esp
18: *a=*a+*b;
004010AF mov eax,dword ptr [a]
004010B2 mov edx,dword ptr
004010B5 mov edx,dword ptr [edx]
004010B7 add edx,dword ptr [eax]
004010B9 mov eax,dword ptr [a]
004010BC mov dword ptr [eax],edx
[b]19: *b=*a-*b;
004010BE mov eax,dword ptr [a]
004010C1 mov edx,dword ptr
004010C4 mov edx,dword ptr [edx]
004010C6 neg edx
004010C8 add edx,dword ptr [eax]
004010CA mov eax,dword ptr [b]
004010CD mov dword ptr [eax],edx
[b]20: *a=*a-*b;
004010CF mov eax,dword ptr [a]
004010D2 mov edx,dword ptr
004010D5 mov edx,dword ptr [edx]
004010D7 neg edx
004010D9 add edx,dword ptr [eax]
004010DB mov eax,dword ptr [a]
004010DE mov dword ptr [eax],edx
[b]21: }
004010E0 leave
004010E1 ret
22:
23: //使用临时变量
24: void ExchangeValue2(int * a , int * b)
25: {
004010E2 push ebp
004010E3 mov ebp,esp
004010E5 push esi
004010E6 push eax
004010E7 push edi
004010E8 push ecx
004010E9 mov edi,ebp
004010EB sub edi,4
004010EE mov ecx,1
004010F3 mov eax,0CCCCCCCCh
004010F8 rep stos dword ptr [edi]
004010FA pop ecx
004010FB pop edi
004010FC pop eax
26: int c;
27: c=*a;
004010FD mov eax,dword ptr [a]
00401100 mov eax,dword ptr [eax]
00401102 mov dword ptr [c],eax
28: *a=*b;
00401105 mov eax,dword ptr
00401108 mov edx,dword ptr [a]
0040110B mov eax,dword ptr [eax]
0040110D mov dword ptr [edx],eax
[b]29: *b=c;
0040110F mov eax,dword ptr
00401112 mov edx,dword ptr [c]
00401115 mov dword ptr [eax],edx
[b]30: }
00401117 leave
00401118 ret
以上是VC的反汇编代码,可以看出来ExchangeValue1被译成了24条汇编代码,而ExchangeValue2被译成了26条汇编代码,从代码条数上来看两种方法差不多。不过这里的代码是VC在debug模式下生成的,没有经过优化,加上ExchangeValue1有多次ADD操作,而ExchangeValue2有多次push、pop和stos操作,各种指令的执行周期也不同,所以很难判断哪种方法更好,况且对于这么一个小问题来分析它的执行效率似乎有点小题大作,我就不往下分析了。有兴趣的朋友可以继续分析一下,只是别忘了把结果告诉我哦!
相关文章推荐
- C中不使用临时变量交换两个变量的值(作者:yxin1322;blog:http://blog.csdn.net/yxin1322)
- 关于两个变量不使用临时变量进行值交换
- 两个数字交换(不使用临时变量)
- 不使用临时变量,实现两个变量值的交换
- 不使用临时变量 依次交换两个已知数组的值
- 不使用临时变量交换两个变量的值---这种算法有溢出的可能
- 不使用临时变量交换两个变量的值(异或,加减,乘除)
- 实现两个int变量的值的交换,要求不使用临时变量。
- 如何在不使用临时变量的情况下交换两个变量的值?
- C中不使用临时变量交换两个变量的值
- 两个数字交换(不使用临时变量)
- 不使用临时变量交换两个变量的值
- 不使用临时变量交换两个变量的值
- C语言实现两个整形变量的值的交换,不使用临时变量
- 算法研究之不使用临时变量实现两个值的交换
- 不使用临时变量,交换两个变量的值
- 不使用临时变量的情况下,两个变量之间交换值的问题
- 不使用临时变量交换两个整数
- 不使用 临时变量交换两个变量的值(SWAP)【原理分析】
- 不使用临时变量而交换两个整形数