实在是记不住啊,还是记下来,都是从网上抄的。虽然都是抄的,但也是综合抄的,哈哈
1. 可变长宏参数写法
C语言中,可变参数宏的写法有如下几种形式:
#define myprint_1(fmt, ...) printf(fmt, __VA_ARGS__) #define myprint_2(fmt, ...) printf(fmt, ##__VA_ARGS__) #define myprint_3(fmt, arg...) printf(fmt, ##arg) int main(void) { myprint_1("%s, %s, %d\r\n", __FILE__, __FUNCTION__, __LINE__); myprint_2("%s, %s, %d\r\n", __FILE__, __FUNCTION__, __LINE__); myprint_3("%s, %s, %d\r\n", __FILE__, __FUNCTION__, __LINE__); return 0; }
2. 宏## 扩展
有这样的需求,需要为5个变量同时进行赋不同的值,而且这5个变量名极其类似,以0,1,2,3,4结尾,代码片断如下:
#define MACRO_EXP(j, val) start ##j=val static int start0 = 0; static int start1 = 0; static int start2 = 0; static int start3 = 0; static int start4 = 0; int main() { int i = 0; int a[] = {2, 3, 4, 5, 7}; for (i = 0;i < 5;i++) MACRO_EXP(i, a[i]); return 0; }
编译后发现报错,使用gcc -E 发现预处理后的代码片断如下:
static int start0 = 0; static int start1 = 0; static int start2 = 0; static int start3 = 0; static int start4 = 0; int main() { int i = 0; int a[] = {2, 3, 4, 5, 7}; for (i = 0;i < 5;i++) starti=a[i]; return 0; }
结论:宏只是简单的在预处理阶段展开代码,如果需要同时处理多个变量,就必须写多个处理宏,不能在循环在处理多个变量。
3. 结构对齐方式
结构体的对齐方式,是按照其元素的最大对齐单位进行的,即如果某成员对齐单位为4,则整个结构体的对齐单位为4,其中如果某成员为数组,则参照单个元素,举例如下:
struct { char a; }struct_test_t1; struct { short i; char a; }struct_test_t2; struct { int i; char a; }struct_test_t3;
struct_test_t1 的大小为1字节;
struct_test_t2 的大小为4字节;
struct_test_t3 的大小为8字节;
4. 结构位域对齐方式
其实和普通的结构对齐相同,按照位域中最长的类型进行对齐,注意如果位域的类型为int,则按照32位(4字节)进行对齐,如果位域类型中全是char,则按照8位(1字节)进行对齐,例子如下:
struct key_conf { char b:2; char c:8; char a:6; };上例中结构体大小为3个字节
struct key_conf { char c:8; char a:6; char b:2; };上例中结构体大小为2个字节
struct key_conf { char c:7; char a:7; char b:2; };上例中结构体大小为3个字节
struct key_conf { int a:16; int b:32; int c:16; };上例中结构体大小为12个字节
struct key_conf { int b:32; int a:16; int c:16; };上例中结构体大小为8个字节
5. 左移、右移
在i386 架构上左移32位时,编译器居然智能的进行了循环左移,即没有任何移动。
但是在PPC架构上左移32位时,全移没了,变成了0,看来这个特性是编译器控制的啊。
6. 大小端宏BYTE_ORDER
这个宏是gcc 特有的,定义在<sys/types.h>,如果不包含这个头文件,这个宏将没有定义,千万注意!
7. 数组初始化
全局数组(静态非静态相同),如果不初始化,则会被编译器置为0;如果初始化,则未初始化的部分会被置为0。
静态局部数组,与全局数组完全相同
局部数组,目前在gcc 编译器上也会如此初始化,不知道其他编译器如何动作。