技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 编程语言 --> C语言函数实现的另类方法

C语言函数实现的另类方法

浏览:2908次  出处信息

在前面看过那个BT的Javascript程序后,我们来看一个C语言的,相信大家还记得输出从1到1000的数最后的那个示例,本站还有很多这样的示例,如:变态的hello word如何教新手编程还有恐怖的C++,在下面这个示例面前,神马都是浮云。

下面这个示例向你展示了如何写一个swap()函数(把两个值交换),这段代码在我的Linux下的 gcc v4.1.1下可以正确编译通过,连一个Warning都没有,而且可以正确工作。我能说什么?!C语言并不疯狂,疯狂的是程序员。

#include
void(*swap)() = (void(*)()) \"\\x8b\\x44\\x24\\x04\\x8b\\x5c\\x24\\x08\\x8b\\x00\\x8b\\x1b\\x31\\xc3\\x31\\xd8\\x31\\xc3\\x8b\\x4c\\x24\\x04\\x89\\x01\\x8b\\x4c\\x24\\x08\\x89\\x19\\xc3\";
  
int main(){ // works on GCC 3+4
        int a = 37, b = 13;
        swap(&a, &b);
  
        printf(\"%d %d\\n\",a,b);
}
 
其实,这种用字符串来实现函数的方法,在原理上是很好理解的。

字符串就是一段内存空间,把一个字符串指针强转成函数指针,那么这个指针所指向的内容就是各种指令,因此,那堆乱七八糟的东西说白了就是汇编。8086的汇编。你可以使用ndisasm来看看。

# ruby -e \"print \\\"\\x8b\\x44\\x24\\x04\\x8b\\x5c\\x24\\x08\\x8b\\x00\\x8b\\x1b\\x31\\xc3\\x31\\xd8\\x31\\xc3\\x8b\\x4c\\x24\\x04\\x89\\x01\\x8b\\x4c\\x24\\x08\\x89\\x19\\xc3\\\"\" | ndisasm -u -
  
00000000  8B442404          mov eax,[esp+0x4]       ; load pointers to two parameters into eax, ebx
00000004  8B5C2408          mov ebx,[esp+0x8]
  
00000008  8B00              mov eax,[eax]           ; load values of two parameters from pointers (*eax, *ebx) into eax, ebx
0000000A  8B1B              mov ebx,[ebx]
  
0000000C  31C3              xor ebx,eax             ; swap two values (eax, ebx) using xor trick
0000000E  31D8              xor eax,ebx
00000010  31C3              xor ebx,eax
  
00000012  8B4C2404          mov ecx,[esp+0x4]       ; load pointer to param 1 into ecx
00000016  8901              mov [ecx],eax           ; store swapped value 1 (eax) into param 1 (*ecx)
  
00000018  8B4C2408          mov ecx,[esp+0x8]       ; load pointer to param 2 into ecx
0000001C  8919              mov [ecx],ebx           ; store swapped value 2 (ebx) into param 2 (*ecx)
  
0000001E  C3                ret

注意:这段汇编中使用了XOR而不是引入第三个变量来完成了变量值的交换。

关于XOR的方式,参看下面的示例:

a = a^b;
b=a^b;
a=b^a;

或者更为简单的:

a^=b^=a^=b;

(全文完)

建议继续学习:

  1. 不定参数的应用 function(fmt, …)    (阅读:3995)
  2. 函数式编程    (阅读:3677)
  3. JavaScript的5种调用函数的方法    (阅读:3599)
  4. C 语言中统一的函数指针    (阅读:3032)
  5. 关于在函数调用时传递string引用的必要性    (阅读:2841)
  6. 深入理解PHP之匿名函数    (阅读:2591)
  7. MySQL 内部函数简介    (阅读:2443)
  8. PHP中htmlentities()和htmlspecialchars()这两个函数的区别    (阅读:2442)
  9. 情人节特献:有心之函数必然就有分手函数    (阅读:2420)
  10. 一个想当然造成的错误(函数引用参数的一个问题)    (阅读:2395)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1