• OI程序常见的设计陷阱


    宏定义的问题

    有时候为了方便,我会大量使用宏定义。但是最近我发现下面这两个宏定义老是出问题:

    1 #define SET(x,a) memset(x,a,sizeof(x))
    2 inline void work(){
    3     SET(head,0),SET(vis,0),SET(dis,0x3f);
    4     //do something
    5 }

    这个宏定义似乎在初始化的时候会莫名奇妙地出现一些问题。

    另外,还有这个:

    1 #define RP(i,a,b) for(register int i=a; i<=b; i++)
    2 inline void work(){
    3     vector<int> ver;
    4     //do something
    5     RP(i,0,ver.size()-1){
    6         //do something
    7     }
    8 }

    当你定义了一个 RP 的循环宏时,它的判断会出一些问题。比如说在上面这个例子,如果ver.size()==0,那么正常的for就不会进入这个循环。但是宏定义之后它的判断顺序似乎发生了改变。

    很奇怪吧?因此,有些宏还是不要乱用。

    另外,宏和函数不同。它相当于是让编译器对源码进行自动替换,而宏的语法如果不加注意,则会出错。举个例子,如果你想把二维坐标映射到一个整数,用宏ID(a,b) = a * M + b 来实现,那么这个语法肯定有问题。假设坐标从0开始,你想得到右下角ID(M - 1, M - 1),那这个宏会把它变成M - 1 * M - M - 1 = -M - 1。正确的语法应该为ID(a,b) = (a) * M + (b)。

    不要乱卡常

    网上有一些奇奇怪怪的卡常方式,比如说把i++写成i=-~i,或者用大量的逗号链接若干个语句。对于前者,这个二进制优化其实并不如想象中的那么出色,对速度的提升不明显。(虽然我本人也喜欢把i++写成++i以提高速度)对于后者,虽然逗号运算符在一定程度上可以提高效率,但有些时候会出现一些奇怪的问题。我记得很久以前,我喜欢把很多语句用若干个逗号连成一条;但是有时候,程序可能只会其中的部分几条,剩下的会被忽略!我不知道是否真的有这个问题,但是我的建议还是不要乱用逗号。

    注意空间复杂度

    在学习任何一个算法或数据结构时,一定要翔实记录它的空间复杂度。比如说,trie树的空间复杂度是多少?一般要开多大?用链式前向星存无向图,是否把边数组开成题给的两倍?这些问题不注意,你也许可以通过样例,但最后可能一分都拿不到。如果你是在网上评测,有时候评测机并不会反馈RE的信息,而是WA。如果不加注意,你会因为这个问题而调试很久。

    另外,足够大的空间也可以从一定程度上提高程序的运行速度。这应该和“空间大易于伸展手脚”是一个道理。

    注意类型转换

    始终注意类型转换。有时候即便你把所有的数值变量开成long long类型,你可能会在赋值的时候忘记把一个int类型的表达式进行转换。这样,表达式在被赋值前就会发生溢出。任何时候要牢记各种变量的类型,并时不时转换一下。

    另外,强制转换的速度会相当慢。如果你想转换成long long类型,直接在变量前乘上1ll;对于普通double类型,可以直接乘上1.0;对于更特殊的long double或是__int128类型,你就只能强制转换了。

    慎用STL

    STL会节省很多时间,而且大部分时候它们除了常数大以外,由于封装了很多函数,使得它们操作起来非常方便。但是有些时候,用STL很有可能会RE。当然,这是否需要“释放内存”,或者一些更高级的处理方法,这我不得而知。

    学会设计参数

    不久前在写矩阵快速幂的时候,发现“引用形参”比不引用形参要快得多。因此,当函数的参数是一个比较大的数据结构时,采用引用的写法会加速很多。

  • 相关阅读:
    解决SharePoint 文档库itemadded eventhandler导致的上传完成后,编辑页面保持报错的问题,错误信息为“该文档已经被编辑过 the file has been modified by...”
    解决SharePoint 2013 designer workflow 在发布的报错“负载平衡没有设置”The workflow files were saved but cannot be run.
    随机实例,随机值
    Spring4笔记
    struts2笔记(3)
    struts2笔记(2)
    获取文本的编码类型(from logparse)
    FileUtil(from logparser)
    DateUtil(SimpleDateFormat)
    struts2笔记
  • 原文地址:https://www.cnblogs.com/LinearODE/p/11614318.html
Copyright © 2020-2023  润新知