实在是记不住啊,还是记下来,都是从网上抄的。虽然都是抄的,但也是综合抄的,哈哈
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 编译器上也会如此初始化,不知道其他编译器如何动作。