这也叫绝招?

今日CSDN的“精华”头条:C语言高效编程的四大绝招,看到第一个绝招就开始佩服CSDN的编辑们了。

绝招一:

方法A:通常的办法

#define LEN 32
char string1 [LEN];
memset (string1,0,LEN);
strcpy (string1,"This is a example!!");

方法B:

const char string2[LEN] ="This is a example!";
char * cp;
cp = string2;

说实话,第一,我没有看懂这两段代码是干什么用的(准确点说,我没有看出这两段代码是做同一件事情的,或者准备在以后做同一件事情),第二,一个const char[]的地址如何能够传递给一个非const的char指针?而该绝招的说明里,摆明是还要对这个指针指向的内容做一些手脚,那么const是如何得到保证的?如果编译器把const数据放置在一块只读内存里,那么运行时刻很可以及是一个“非法操作”……

绝招二,数学方法解决问题

立论不错,明确点说“算法决定效率”就更贴切一点,可惜举的例子不够生动,似乎就来自于少年高斯的那个传说。如果能象《编程珠玑》开篇讲的那个故事,那就跃然生辉了。

绝招三,用移位代替除法

方法G

int I,J;
I = 257 /8;
J = 456 % 32;

方法H

int I,J;
I = 257 >>3;
J = 456 - (456 >> 4 << 4);

绝招三至少有三个错误的地方,第一个想必是笔误,把一个数右移四位再左称四位,然后原值去减它,其实是模拟了对16取模,而不是32。第二个是没有考虑到负数,对一个正数,把它右称四位再左称四位再用原值去减它,的确与模16结果一致,但对一个负数就不一样了,因为C里面的移位操作是带符号的,设n=-15,n % 16应该等于-15,但把-15右移4位会得到-1,再左移4位会得到-16,用-15减去16会得到1。第三个错误也许不是错误,也许只是为了说明问题,却忘了上面的运算都是针对常量的,而对于常量的运算,编译器会自己先把它算出来……所以上述两段代码编译出来的结果会完全一样(除了%32应该是%16)。

由于移位和减法并不能替代取模,所以讨论二者的速度也没有必要的,只是顺便提一下,对一个常量取模,编译器产生的代码很精巧,如果取模的是两个变量,%也并不是个函数,它其实是CPU本身的硬件指令(idiv),手边恰好没有CPU指令周期表,但从感觉上也觉得一条idiv指令,不会比两个移位和一个减法指令慢多少吧?

绝招四,汇编嵌入。
char string1[1024], string2[1024];
int I;
for (I =0 ;I<1024;I++)
*(string2 + I) = *(string1 + I);

我不否认仔细编排过的汇编,在速度上也许要超过C编译器的优化,但作者所举的例子,以及说明实在是……

先说说C的例子,因为“在源数据里可能含有数据为0的字节,这样的话,标准库函数会提前结束而不会完成我们要求的操作”,所以用了一个1024次的循环来拷贝数据,难道标准库函数里没有memcpy()吗?再说说汇编,啊,我没有发言权,我不了解ARM平台,我只知道8086汇编,那里面有movsb,高效一点,因为知道1024是32的幂,在32位平台上还可以用movsd……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值