? (((val) - 1) / ALIGN_SIZE + 1) : 0)
/*将HeaderStruct按照Align划分,找到最小的n,使得n*ALIGN_SIZE>=sizeof(HeaderStruct),在自然数集中*/
#define HEADER_ALIGN_SIZE (reva lue_up_align(sizeof(HeaderStruct)))
/*实现了memory.h接口中Header不完全类型,Align是对齐用的,内存结构的头结点.链表链接的主要结点*/
union Header_tag {
HeaderStruct s;
Align u[HEADER_ALIGN_SIZE];
};
主要看 union Headr_tag 中 Align结构. 保证不同机器上内存是对齐的. 比较古老了. 特别底层的库会见到.
7. 可变参数宏, 那些事
同样直接看下面工程中用的示例
//4.0 控制台打印错误信息, fmt必须是双引号括起来的宏
#ifndef CERR
#define CERR(fmt, ...) \
fprintf(stderr,"[%s:%s:%d][error %d:%s]" fmt "\r\n",\
__FILE__, __func__, __LINE__, errno, strerror(errno),##__VA_ARGS__)
#endif/* !CERR */
//4.1 控制台打印错误信息并退出, t同样fmt必须是 ""括起来的字符串常量
#ifndef CERR_EXIT
#define CERR_EXIT(fmt,...) \
CERR(fmt,##__VA_ARGS__),exit(EXIT_FAILURE)
#endif/* !ERR */
#ifndef IF_CERR
/*
*4.2 if 的 代码检测
*
* 举例:
* IF_CERR(fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP), "socket create error!");
* 遇到问题打印日志直接退出,可以认为是一种简单模板
* code : 要检测的代码
* fmt : 必须是""括起来的字符串宏
* ... : 后面的参数,参照printf
*/
#define IF_CERR(code, fmt, ...) \
if((code) < 0) \
CERR_EXIT(fmt, ##__VA_ARGS__)
#endif //!IF_CERR
#ifndef IF_CHECK
/*
* 是上面IF_CERR 的简化版很好用
*/
#define IF_CHECK(code) \
if((code) < 0) \
CERR_EXIT(#code)
#endif // !IF_CHECK
那 传说中的 3颗痣, 就是可变参数宏的一切o(∩_∩)o
8. 简单的谢幕. 还是宏
一个数如何和0比较,真的是 == 吗. 其实好的思路是定义阀值.
//3.0 浮点数据判断宏帮助, __开头表示不希望你使用的宏
#define __DIFF(x, y) ((x)-(y)) //两个表达式做差宏
#define __IF_X(x, z) ((x)<z&&(x)>-z) //判断宏,z必须是宏常量
#define EQ(x, y, c) EQ_ZERO(__DIFF(x,y), c) //判断x和y是否在误差范围内相等
//3.1 float判断定义的宏
#define _FLOAT_ZERO (0.000001f) //float 0的误差判断值
#define EQ_FLOAT_ZERO(x) __IF_X(x,_FLOAT_ZERO) //float 判断x是否为零是返回true
#define EQ_FLOAT(x, y) EQ(x, y, _FLOAT_ZERO) //判断表达式x与y是否相等
谢幕吧 : [
老师布置一个作业, 问学生, 看见那个晾衣杆吗. 谁能帮我测试出高度来.
一个同学自告奋勇的把晾衣杆放倒了. 测试出长度 为 1.5m.
老师把他骂了一顿, 我要的是高度, 不是长度.
]
//5.0 获取数组长度,只能是数组类型或""字符串常量,后者包含'\0'
#ifndef LEN
#define LEN(arr) \
(sizeof(arr)/sizeof(*(arr)))
#endif/* !ARRLEN */
后记 - 认真做容易的
错误是难免的, 欢迎吐槽交流. ... 还有下半辈子的苟且. 哈哈, 但是在变化, 那会变得有意思, O(∩_∩)O哈哈~