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


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


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

你可能感兴趣的:(c,function,File,语言)