CMU C++ Tips 笔记

本文整理了CMU wiki中C/C++编写的小技巧和提醒。涵盖预处理器相关内容,如通用字符名、#include_next指令等;还介绍了memset使用、指针判断、结构体字节对齐等实用技巧;最后提及C++ 11及之后的单例模式和多值返回获取。

偶然发现 CMU 的 wiki,里面有 C/C++ 的编写小技巧和提醒,特意挑了些自以为的重点做了笔记,其中可能还混杂了我在其他地方看到的内容,详细内容 wiki 可以看文末链接。

1、preprocessor

1.1、universal character names

The universal character name \Unnnnnnnn designates the character whose 8-digit short identifier (as specified by ISO/IEC 10646) is nnnnnnnn.

Similarly, the universal character name \unnnn designates the character whose 4-digit short identifier is nnnn (and whose 8-digit short identifier is 0000nnnn).

1.2、#include_next

例如有个搜索路径链,在#include中,它们的搜索顺序依次是A,B,C,D和E。在B目录中有个头文件叫a.h,在D目录中也有个头文件叫a.h,如果在我们的源代码中这样写#include <a.h>,那么我们就会包含的是B目录中的a.h头文件,如果我们这样写#include_next <a.h>那么我们就会包含的是D目录中的a.h头文件。#include_next <a.h>的意思按我们上面的引号包含中的解释来说就是“在B目录中的a.h头文件后面的目录路径(即C,D和E)中搜索a.h头文件并包含进来)。#include_next <a.h>的操作会是这样的,它将在A,B,C,D和E目录中依次搜索a.h头文件,那么首先它会在B目录中搜索到a.h头文件,那它就会以B目录作为分割点,搜索B目录后面的目录(C,D和E),然后在这后面的目录中搜索a.h头文件,并把在这之后搜索到的a.h头文件包含进来。这样说的话大家应该清楚了吧。

还有一点是#include_next是不区分<>和""的包含形式的。

现在来说说为什么要引人这条指令!

假如,你要创建一个新的头文件,而这个新的头文件和现在已有的头文件有相同的名字,而且你想用你的这个新的头文件,那么你要做的就是把这个新的头文件放在#include指令的搜索路径的前面,即是在旧的头文件的前面新的头文件首先被搜索到,这样你就可以使用你这个新的头文件。但是你在另一个源代码文件中想使用旧的头文件了,那怎么办!有个办法就是使用绝对路径来搜索,那么就不存在这样的问题了。问题出在,如果我们把头文件的位置移动了,移到了其它的目录里了,那我们就得在相应的源码文件中修改这个包含的绝对路径,如果一个源码文件还好,但如果是大型工程的话,修改的地方多了就容易出问题。

1.3、macro side effects

#define ABS(x) (((x) < 0) ? -(x) : (x))
int m = ABS(++n);
// equal to below
m = (((++n) < 0) ? -(++n) : (++n));

// how to avoid
++n;
int m = ABS(n);

// or prefer inline or static functions to function-like macros
// Inline substitution is not textual substitution, nor does it create a new function.
static inline int iabs(int x) {
   
   
  return (((x) < 0) ? -(x) : (x));
}

// GCC's __typeof extension makes it possible to 
// declare and assign the value of the macro operand to a temporary of the same type 
// and perform the computation on the temporary, 
// consequently guaranteeing that the operand will be evaluated exactly once. 
#define ABS(x) __extension__ ({ __typeof (x) tmp = x; \
                    tmp < 0 ? -tmp : tmp; })

Expressions used as arguments to the standard assert() macro should not have side effects.

1.4、STDC_VERSION

Checks __STDC_VERSION__ to ensure that a pre-C11 compiler will fail to compile the code, rather than invoking undefined behavior.

#if __STDC_VERSION__ < 201112L
#error This code requires a compiler supporting the C11 standard or newer
#endif

2、tips

2.1、memset

int buff_2[10];
memset(buff_2,1,sizeof(buff_2));  
for(int i = 0;i<10;i++)
{
   
   
    printf("%d ",buff_2[i]);
}

是的,变量的类型变了,打印的结果是:

16843009
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值