注册 登录
查看: 2074|回复: 106

【每日一思】比较代码特点

  [复制链接]
发表于 2013-12-12 15:13:49 | 显示全部楼层 |阅读模式
本帖最后由 山外メ雲ジ 于 2013-12-12 15:15 编辑

作为一个软件攻城师,优化代码的能力是必须要有的

有以下两段功能一样的代码,大家比较两者之前有什么区别?

第一段代码 是 昨天每日一思的题目,不过没一个人能完整回答到问题。
  1. char *func(char *dest, const char *src, int count)   
  2. {   
  3.     char *tmp = dest;   

  4.     while (count) {   
  5.         if ((*tmp = *src) != 0)   
  6.             src++;   
  7.         tmp++;   
  8.         count--;   
  9.     }   

  10.     return dest;   
  11. }   
第二段代码,也是实现上面的功能

  1. char *strncpy(char *dest, const char *src, int n)
  2. {
  3.     char c;
  4.     char *s = dest;
  5.     if (n >= 4)
  6.     {
  7.         size_t n4 = n >> 2;
  8.         for (;;)
  9.         {
  10.             c = *src++;
  11.             *dest++ = c;
  12.             if (c == '\0')
  13.                 break;
  14.             c = *src++;
  15.             *dest++ = c;
  16.             if (c == '\0')
  17.                 break;
  18.             c = *src++;
  19.             *dest++ = c;
  20.             if (c == '\0')
  21.                 break;
  22.             c = *src++;
  23.             *dest++ = c;
  24.             if (c == '\0')
  25.                 break;
  26.             if (--n4 == 0)
  27.                 goto last_chars;
  28.         }
  29.         n -= dest - s;
  30.         goto zero_fill;
  31.     }
  32. last_chars:
  33.     n &= 3;
  34.     if (n == 0)
  35.         return s;
  36.     for (;;)
  37.     {
  38.         c = *src++;
  39.         --n;
  40.         *dest++ = c;
  41.         if (c == '\0')
  42.             break;
  43.         if (n == 0)
  44.             return s;
  45.     }
  46. zero_fill:
  47.     while (n-- > 0)
  48.         dest[n] = '\0';
  49.     return s;
  50. }

大家认真去思考,直接看答案是 学不到东西的,认真回答一下问题 这些题目都是 找工作时面试笔试常考的问题,当然,往往是叫你自己写出源代码。

答案依旧回复可见。


游客,如果您要查看本帖隐藏内容请回复

本帖被以下淘专辑推荐:

回复

使用道具 举报

发表于 2013-12-12 16:44:21 | 显示全部楼层
路过,来看看的………
回复 支持 反对

使用道具 举报

发表于 2013-12-12 21:42:12 | 显示全部楼层
真棒!!非常感谢
回复 支持 反对

使用道具 举报

发表于 2013-12-13 03:58:29 | 显示全部楼层
我抢、我抢、我抢沙发~
回复 支持 反对

使用道具 举报

发表于 2013-12-13 09:06:38 | 显示全部楼层
真棒!!非常感谢
回复 支持 反对

使用道具 举报

发表于 2013-12-13 09:07:06 | 显示全部楼层
真棒!!非常感谢
回复 支持 反对

使用道具 举报

发表于 2013-12-13 11:27:19 | 显示全部楼层
走过路过,不能错过
回复 支持 反对

使用道具 举报

发表于 2013-12-13 14:03:16 | 显示全部楼层
晕啊..看到我..不是说不要用goto吗,代码可读性太差了.
回复 支持 反对

使用道具 举报

发表于 2013-12-15 10:43:53 | 显示全部楼层
真棒!!非常感谢
回复 支持 反对

使用道具 举报

发表于 2013-12-16 10:00:14 | 显示全部楼层
走过路过,不能错过
回复 支持 反对

使用道具 举报

发表于 2013-12-16 12:22:51 | 显示全部楼层
sarjet 发表于 2013-12-13 14:03
晕啊..看到我..不是说不要用goto吗,代码可读性太差了.

goto ,用得 比较灵活,缺点就是 可阅读性 差。

此题是给大家了解 空间换时间 的 函数。不过 题目太长,很多人都有阅读障碍
回复 支持 反对

使用道具 举报

发表于 2013-12-18 17:05:21 | 显示全部楼层
感觉第二段代码完全是用人工去代替了计算机的工作,人工把计算机的演算步骤全部算完了。代码很好理解,但是读起来很麻烦。想想刚开始接触编程的时候,也是这样,完全为了实现功能去写代码,很难回头维护。
回复 支持 反对

使用道具 举报

发表于 2013-12-18 19:36:40 | 显示全部楼层
南宫先生 发表于 2013-12-18 17:05
感觉第二段代码完全是用人工去代替了计算机的工作,人工把计算机的演算步骤全部算完了。代码很好理解,但是 ...

第二段代码 不是简单的理解为 人工替换计算机 工作,他的目的 是 空间换时间

例如 memcpy 函数,你可以看出这函数 跟 库提供的函数的区别吗?
  1. void memcpy( uint8 *dst, uint8 *src, uint32 count)
  2. {
  3.     uint32 n;
  4.     if(count != 0)
  5.     {
  6.         n = (count + 7 ) / 8 ;
  7.         switch (count % 8 )
  8.         {
  9.             do
  10.             {
  11.             case 0 :
  12.                 * dst ++ = * src ++ ;
  13.             case 7 :
  14.                 * dst ++ = * src ++ ;
  15.             case 6 :
  16.                 * dst ++ = * src ++ ;
  17.             case 5 :
  18.                 * dst ++ = * src ++ ;
  19.             case 4 :
  20.                 * dst ++ = * src ++ ;
  21.             case 3 :
  22.                 * dst ++ = * src ++ ;
  23.             case 2 :
  24.                 * dst ++ = * src ++ ;
  25.             case 1 :
  26.                 * dst ++ = * src ++ ;
  27.             }
  28.             while ( -- n >    0 );
  29.         }
  30.     }
  31. }
原先 每 执行 一次都 进行 一次判断,现在 改成 执行 8次 进行 一次判断,效率就高了 ……
回复 支持 反对

使用道具 举报

发表于 2013-12-18 19:42:24 | 显示全部楼层
南宫先生 发表于 2013-12-18 17:05
感觉第二段代码完全是用人工去代替了计算机的工作,人工把计算机的演算步骤全部算完了。代码很好理解,但是 ...

估计 switch 里面 加  个 do while 的 用法 很少见吧?
  1. switch()
  2. {
  3.     do{
  4.     case :
  5.     case:
  6.     }while();
  7. }
在一些关键的代码里,宁可花长一些的代码,也要争取时间。例如上面提供的代码,就是 用在 我们 K60 的 无线收发 代码里,需要 中断里 复制比较大的数据,因此速度很重要。
回复 支持 反对

使用道具 举报

发表于 2013-12-18 23:32:58 | 显示全部楼层
复制n个字节 - - 以4个字节为单位复制。。看看答案。、
回复 支持 反对

使用道具 举报

发表于 2013-12-19 11:07:05 | 显示全部楼层
Admin 发表于 2013-12-18 19:36
第二段代码 不是简单的理解为 人工替换计算机 工作,他的目的 是 空间换时间

例如 memcpy 函数,你可以 ...

经过山外哥提醒,豁然开朗啊,哈哈。不知道编译后对于下位机而言,哪个执行文件比较大,毕竟下位机,既要考虑运行的速度也要考虑存储空间呀。不过这个思路真的很好,受益了
回复 支持 反对

使用道具 举报

发表于 2013-12-20 19:53:50 | 显示全部楼层
抢沙发~给哥们顶一个强烈支持,非常感谢哥们
回复 支持 反对

使用道具 举报

发表于 2013-12-20 22:52:36 | 显示全部楼层
第一段代码很简洁,第二段就有点看不明白了!
回复 支持 反对

使用道具 举报

发表于 2013-12-21 08:49:02 | 显示全部楼层
走过路过,不能错过
回复 支持 反对

使用道具 举报

发表于 2013-12-21 14:30:11 | 显示全部楼层
为了看答案 灌水
回复 支持 反对

使用道具 举报

发表于 2013-12-21 15:02:19 | 显示全部楼层
走过路过,不能错过
回复 支持 反对

使用道具 举报

发表于 2013-12-21 23:59:50 | 显示全部楼层
南宫先生 发表于 2013-12-19 11:07
经过山外哥提醒,豁然开朗啊,哈哈。不知道编译后对于下位机而言,哪个执行文件比较大,毕竟下位机,既要考 ...

下位机 虽然 也 需要考虑 空间 ,但 很多情况下 空间还是 有余,尤其现在 的 单片机 flash 容量越来越多 ……
需要分情况 考虑 是 空间换时间,还是 时间换空间 ……
回复 支持 反对

使用道具 举报

发表于 2013-12-24 15:45:08 | 显示全部楼层
这用法第一次见!
回复 支持 反对

使用道具 举报

发表于 2013-12-24 16:02:49 | 显示全部楼层
Admin 发表于 2013-12-18 19:36
第二段代码 不是简单的理解为 人工替换计算机 工作,他的目的 是 空间换时间

例如 memcpy 函数,你可以 ...

可以讲一下,这段代码的执行顺序吗??
回复 支持 反对

使用道具 举报

发表于 2013-12-25 13:47:14 | 显示全部楼层
指针好复杂
回复 支持 反对

使用道具 举报

发表于 2013-12-25 13:47:47 | 显示全部楼层
指针好复杂
回复 支持 反对

使用道具 举报

发表于 2013-12-28 08:12:29 | 显示全部楼层
这个真不知道哦,需要学习下
回复 支持 反对

使用道具 举报

发表于 2013-12-28 08:17:30 | 显示全部楼层
这个真不知道哦,需要学习下
回复 支持 反对

使用道具 举报

发表于 2013-12-30 21:50:42 | 显示全部楼层
真的看不懂,所以只好看答案咯
回复 支持 反对

使用道具 举报

发表于 2014-1-4 21:48:38 | 显示全部楼层
学习学习、、、、、、、、、、、、、、
回复 支持 反对

使用道具 举报

发表于 2014-1-5 16:46:55 | 显示全部楼层
小白  看看答案再理解
回复 支持 反对

使用道具 举报

发表于 2014-1-7 10:08:18 | 显示全部楼层
我是来看答案的
回复 支持 反对

使用道具 举报

发表于 2014-1-8 23:28:34 | 显示全部楼层
比雷公还雷人哦~
回复 支持 反对

使用道具 举报

发表于 2014-1-13 08:44:29 | 显示全部楼层
有点晕,看看
回复 支持 反对

使用道具 举报

发表于 2014-1-13 08:50:07 | 显示全部楼层
顶起!!!
回复 支持 反对

使用道具 举报

发表于 2014-1-18 12:34:00 | 显示全部楼层
顶起!!!   
回复 支持 反对

使用道具 举报

发表于 2014-2-15 23:42:38 | 显示全部楼层
额,,不懂
回复 支持 反对

使用道具 举报

发表于 2014-2-16 13:09:00 | 显示全部楼层
强烈支持,非常感谢哥们强烈支持,非常感谢哥们强烈支持,非常感谢哥们
回复 支持 反对

使用道具 举报

发表于 2014-2-24 22:57:06 | 显示全部楼层
第一个程序好像还好理解,可是第二个是不是因为有点太长的原因没耐心看还是因为太绕了。指针真是深奥,在C语言世界里看来也只有指针能让人溺水了。第一个程序是执行N次在判断;第二个程序,好像是每执行一次就跳出一个判断情况,然后在判断在执行第二个判断,最后还是执行了N次,不知道对不对呀。还是看答案吧。
回复 支持 反对

使用道具 举报

发表于 2014-3-4 11:17:56 | 显示全部楼层
走过路过,不能错过
回复 支持 反对

使用道具 举报

发表于 2014-3-8 14:09:31 | 显示全部楼层
强烈支持,非常感谢哥们
回复 支持 反对

使用道具 举报

发表于 2014-3-10 11:50:00 | 显示全部楼层
笑坏我的肚子了
回复 支持 反对

使用道具 举报

发表于 2014-3-14 21:09:27 | 显示全部楼层
笑坏我的肚子了笑坏我的肚子了
回复 支持 反对

使用道具 举报

发表于 2014-3-25 21:15:59 | 显示全部楼层
向山外哥学习
回复 支持 反对

使用道具 举报

发表于 2014-3-27 11:57:25 | 显示全部楼层
走过路过,不能错过走过路过,不能错过
回复 支持 反对

使用道具 举报

发表于 2014-3-30 13:28:23 | 显示全部楼层
感觉这次好像看懂了,函数以4个字符为单位,一旦判断到到达空字符,直接用goto zero_fill;补'/0',避免了判断语句的使用,以空间换时间
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-3-30 13:48:06 | 显示全部楼层
詹伟彬 发表于 2014-3-30 13:28
感觉这次好像看懂了,函数以4个字符为单位,一旦判断到到达空字符,直接用goto zero_fill;补'/0',避免了判 ...

厉害,看懂了
回复 支持 反对

使用道具 举报

发表于 2014-4-7 16:52:30 | 显示全部楼层
第二种也太乱了吧,goto都来了
回复 支持 反对

使用道具 举报

发表于 2014-4-11 09:24:47 | 显示全部楼层
抢沙发~给哥们顶一个
回复 支持 反对

使用道具 举报

发表于 2014-4-12 19:29:44 | 显示全部楼层
区别:第一段使用的是指针
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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