宏定义的问题

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

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

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

另外,还有这个:

 #define RP(i,a,b) for(register int i=a; i<=b; i++)
inline void work(){
vector<int> ver;
//do something
RP(i,,ver.size()-){
//do something
}
}

当你定义了一个 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。当然,这是否需要“释放内存”,或者一些更高级的处理方法,这我不得而知。

学会设计参数

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

OI程序常见的设计陷阱的更多相关文章

  1. 小程序-文章:微信小程序常见的UI框架/组件库总结

    ylbtech-小程序-文章:微信小程序常见的UI框架/组件库总结 1.返回顶部 1. 想要开发出一套高质量的小程序,运用框架,组件库是省时省力省心必不可少一部分,随着小程序日渐火爆,各种不同类型的小 ...

  2. Swing程序最佳架构设计—以业务对象为中心的MVC模式(转)

    前言: 我打算写一系列关于Swing程序开发的文章.这是由于最近我在做一个Swing产品的开发.长期做JavaEE程序,让我有些麻木了.Swing是设计模式的典范,是一件优雅的艺术品,是一件超越时代的 ...

  3. 官方问答--微信小程序常见FAQ (17.8.21-17.8.27)

    给提问的开发者的建议:提问之前先查询 文档.通过社区右上角搜索搜索已经存在的问题. 写一个简明扼要的标题,并且正文描述清楚你的问题. 提交 BUG:需要带上基础库版本号,设备信息(iOS, Andro ...

  4. C#WinForm窗体内Panel容器中嵌入子窗体、程序主窗体设计例子

    C#WinForm父级窗体内Panel容器中嵌入子窗体.程序主窗体设计例子 在项目开发中经常遇到父级窗体嵌入子窗体所以写了一个例子程序,顺便大概划分了下界面模块和配色,不足之处还望指点 主窗体窗体采用 ...

  5. java.awt包提供了基本的java程序的GUI设计工具

    java.awt包提供了基本的java程序的GUI设计工具.主要包括下述三个概念: 组件--Component 容器--Container 布局管理器--LayoutManager package T ...

  6. 微信小程序开发系列二:微信小程序的视图设计

    大家如果跟着我第一篇文章 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 一起动手,那么微信小程序的开发环境一定搭好了.效果就是能把该小程序的体验版以二维码的方式发送给其他朋友使用. 这个系列 ...

  7. python学习笔记(2)——练习小程序之 " input " 隐藏陷阱

    练习小程序之 ----------" input " 隐藏陷阱 age=input('please enter your age:') if age>=18: print(' ...

  8. 微信小程序常见的UI框架/组件库总结

    想要开发出一套高质量的小程序,运用框架,组件库是省时省力省心必不可少一部分,随着小程序日渐火爆,各种不同类型的小程序也渐渐更新,其中不乏一些优秀好用的框架/组件库. 1:WeUI 小程序–使用教程 h ...

  9. 深入浅出 Java Concurrency (39): 并发总结 part 3 常见的并发陷阱

    常见的并发陷阱 volatile volatile只能强调数据的可见性,并不能保证原子操作和线程安全,因此volatile不是万能的.参考指令重排序 volatile最常见于下面两种场景. a. 循环 ...

随机推荐

  1. MySql字段类型及字节

    字段类型:TINYINT-----------------一个很小的整数.有符号的范围是-128到127,无符号的范围是0到255. SMALLINT--------------一个小整数.有符号的范 ...

  2. 【小知识点】input输入框在安卓以及IOS手机中光标及字体不居中解决方法

    问题根本:不要使用line-height垂直居中. 解决方法:可直接定义height,然后高度由上下padding值撑开. input { height: 1rem; padding: 1rem 0; ...

  3. Spring注解实践

    原文:http://blog.csdn.net/xyh820/article/details/7303330 概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获 ...

  4. Jerry和您聊聊Chrome开发者工具

    Chrome开发者工具是Jerry日常工作使用的三大调试器之一.虽然工具名称前面带了个"开发者", 但是它对非开发人员仍然有用.不信? 用Chrome打开我们常用的网站,按F12, ...

  5. 根据CPU核心数确定线程池并发线程数(转)

    一.抛出问题 关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下: 第一派:<Java Concurrency in Practice>即&l ...

  6. Spring Cloud(四)服务提供者 Eureka + 服务消费者 Feign

    上一篇文章,讲述了如何通过RestTemplate + Ribbon去消费服务,这篇文章主要讲述如何通过Feign去消费服务. Feign简介 Feign是一个声明式的伪Http客户端,它使得写Htt ...

  7. Linux下创建NFS来实现共享文件

    简介说明: 在项目生产环境我们经常需要实现文件共享,传统的常见方案是通过NFS,实现服务器之间共享某一块磁盘,通过网络传输将分散的文件集中存储在一块指定的共享磁盘,实现基本的文件共享.实现这种方案,分 ...

  8. C# PDF 填值 填充数据

    看效果图   /// <summary> /// 赛事结果PDF /// </summary> /// <param name="model"> ...

  9. opencv3.0中contrib模块的添加+实现SIFT/SURF算法

    平台:win10 x64 +VS 2015专业版 +opencv-3.x.+CMake+Anaconda3(python3.7.0) Issue说明:Opencv3.0版本已经发布了有一段时间,在这段 ...

  10. Centos7虚拟机根分区扩展

    线上的kvm虚拟机,原来只规划了8G,后来发现硬盘动不动就被日志塞满了,需要进行扩容. 扩容步骤如下: 1.先把kvm虚拟机关机 2.在宿主机上进行kvm虚拟机的磁盘扩容 qemu-img resiz ...