C 语言相关(宏扩展、字节对齐)

来源:互联网 发布:主对角占优矩阵 编辑:程序博客网 时间:2024/06/05 18:07


实在是记不住啊,还是记下来,都是从网上抄的。虽然都是抄的,但也是综合抄的,哈哈


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=valstatic 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 编译器上也会如此初始化,不知道其他编译器如何动作。

原创粉丝点击