声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

12
返回列表 发新帖
楼主: Rainyboy

[C/C++] 放松一下,来个编程挑战(不限于C/C++,而且答对有奖励)

[复制链接]
 楼主| 发表于 2010-10-20 10:48 | 显示全部楼层

另外,这行代码:
  1. printf("%d\n", N - (N - *funcp) * (2*(*funcp < N) - 1));//执行打印
复制代码
写得也很是精妙,深得C语言的精髓啊。
回复 支持 反对
分享到:

使用道具 举报

发表于 2010-10-20 12:17 | 显示全部楼层
回复 Rainyboy 的帖子

嗯嗯。。。对。。。
当时写的时候是想控制i的输出,i<N时候输出i,i>N时候输出2N-i。
a-b=i
a+b=2N-i
正负号好控制,对比i和N正好控制。然后用i<2N控制范围,后来发现控制范围还是大,,就改用i<2N-i_控制了,i_表示i的初始值,没删除i<2N。:@P
再写一下适用范围:
1、i的范围是MIN_SHORTD到MAX_SHORT,因为i被拆成高二字节和低二字节,同理N也被i限制,尽管N的高位并没有用到。
2、调用约定是_cdecl,相似调用约定也可以,原理见10楼。
3、32位机器。
4、call指令占5个Bytes。(不熟悉AT&T汇编,也不知道AT&T的call占几个Bytes,Masm一般都占5个Bytes或者6个Bytes)

缺陷:如有这样的调用p(-7, -3);还是有问题,考虑再改进一下。
最后感谢版主修正,嘿嘿,没事常交流。。。:@)
 楼主| 发表于 2010-10-20 12:44 | 显示全部楼层
回复 wqsong 的帖子

总的来说这是一种很C语言的方法,实实在在地满足了所有条件,让人无话可说,受益匪浅。
多年前我曾经有一个用内联汇编的尝试,现在看来,不值一提,不过还是贴上来吧。
  1. int p(int i,int N)
  2. {
  3. _asm{
  4.         mov ebx,dword ptr [i]

  5.       dec i
  6. stt:      mov     eax,dword ptr [i]
  7.          push    eax  
  8.      push    offset szFormat
  9.       call    printf
  10.       add     esp,8
  11.      inc  i
  12.      mov eax ,dword ptr[N]
  13.       cmp eax ,i
  14.      jnz stt

  15. ste:    dec i
  16.       mov eax,dword ptr [i]
  17.       push    eax  
  18.      push    offset szFormat
  19.      call    printf
  20.       add     esp,8
  21.       cmp ebx,i
  22.      jnz ste
  23. }
  24. }
复制代码
发表于 2010-10-20 13:16 | 显示全部楼层
回复 Rainyboy 的帖子
  1. int p(int i,int N)
  2. {
  3. _asm{
  4.         mov ebx,dword ptr [i]
  5.         mov ecx ,dword ptr[N]

  6.       dec i
  7. stt:      mov     eax,dword ptr [i]
  8.        ; inc  i是否应该在这里呢?
  9.          push    eax  
  10.      push    offset szFormat
  11.       call    printf
  12.       add     esp,8
  13.      inc  i
  14.       cmp ecx ,i
  15.      jnz stt

  16. ste:    dec i
  17.       mov eax,dword ptr [i]
  18.       push    eax  
  19.      push    offset szFormat
  20.      call    printf
  21.       add     esp,8
  22.       cmp ebx,i
  23.      jnz ste
  24. }
  25. }
复制代码
嗯嗯,符合规范的。汇编都快忘没了,学习了,嘿嘿。
记得看《C专家编程》里面,一个卡耐基梅隆大学的一个编程竞赛,各种各样的想法,直接修改进程控制块改变运行时间,:lol。。。

有个地方没看明白,第6行,第一个dec i,为了控制输出N一次,但stt循环的inc i又在printf后面,是否应该把inc i提前到push eax前面呢?
 楼主| 发表于 2010-10-20 13:23 | 显示全部楼层
本帖最后由 Rainyboy 于 2010-10-20 13:24 编辑

回复 wqsong 的帖子

提到前面和后面没有区别吧,因为压栈的是eax啊。

《C专家编程》是本好书,你说的那个桥段我也很喜欢,呵呵,还有什么混乱码大赛……
发表于 2010-10-20 13:32 | 显示全部楼层
本帖最后由 wqsong 于 2010-10-20 13:33 编辑

回复 Rainyboy 的帖子

噢,是提到mov  eax, dword ptr 前面。
sst循环前执行了dec i,进入循环后先打印后自加的话,那么如果有这样的调用
p(2, 3)是否就是打印出
1
2
3
2
呢?
 楼主| 发表于 2010-10-20 13:44 | 显示全部楼层
回复 wqsong 的帖子

确实哈……这个代码年代有些久远了,而且我现在用VS2010跑它居然报了一堆错……也罢。。。
发表于 2010-10-20 13:48 | 显示全部楼层
回复 Rainyboy 的帖子

嗯,重意不重形,学习了:@)。
版主工作了还是在读呢?
 楼主| 发表于 2010-10-20 13:55 | 显示全部楼层
回复 wqsong 的帖子

在读呢,要不哪来时间挂着啊,呵呵
发表于 2010-10-20 14:01 | 显示全部楼层
回复 Rainyboy 的帖子

噢,嘿嘿,我也是。。。
马上毕业了,正找工作呢。学热能与动力工程,招聘那些人都不需要写程序的,眼看单位过了一个又一个,都不知道该去哪儿了,哈哈。。。唉:dizzy:
 楼主| 发表于 2010-11-19 09:03 | 显示全部楼层
回复 25 # wqsong 的帖子

这两天又找工作去了……都没见你来?
发表于 2010-11-23 23:26 | 显示全部楼层
回复 26 # Rainyboy 的帖子

刚回来。。。忙了半个多月,给你招呼里细说啦。。。呵呵
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-12-23 19:05 , Processed in 0.107145 second(s), 15 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表