C语言宏定义的几种简单用法

本文最后更新于:4 年前

  • 1、计算数组的大小

    1
    #define countof(a) (sizeof(a)/sizeof(*(a)))
  • 2、转换大小写字母

    1
    2
    #define FS_TOUPPER(x) ((((x) >= 'a') && ((x) <= 'z')) ? (x) - 'a' + 'A' : (x))
    #define FS_TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? (x) - 'A' + 'a' : (x))
  • 3、大小端模式转换

    1
    2
    3
    #define SWAP16(x) (((x) << 8) & 0xff00) | (((x) >> 8) & 0xff)
    #define SWAP32(x) ((((uint32_t)(x) >> 24) & 0xff) | (((uint32_t)(x) >> 8) & 0xff00) | (((uint32_t)(x) << 8) & 0xff0000) | (((uint32_t)(x) << 24) & 0xff000000))

  • 4、生成字,双字

    1
    2
    3
    #define MAKE_DWORD(b3, b2, b1, b0) (((uint32_t)((uint8_t)(b3) << 24)) | ((uint8_t)(b2) << 16) | ((uint8_t)(b1) << 8) | ((uint8_t)(b0)))
    #define MAKE_WORD(h, l) (((uint32_t)(h) << 8) | ((l) & 0xffff))

  • 5、获取高,低字节

    1
    2
    3
    4
    5
    #define GET_WORD_HIGH(x) ((uint32_t)(x) >> 16)
    #define GET_WORD_LOW(x) ((uint32_t)(x) & 0xffff)
    #define GET_WORD_HIGHBYTE(x) ((uint32_t)(x) >> 24)
    #define GET_WORD_LOWBYTE(x) ((uint32_t)(x) & 0xff)

  • 6、计算结构体成员的偏移量

    1
    #define OFFSET(s,m)  (size_t)&(((s * )0)->m)  //计算分量 m 在结构体 s 中的偏移量,单位是字节

以上宏定义的示例程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdio.h>
#include <stdint.h>

#define countof(a) (sizeof(a)/sizeof(*(a)))

#define FS_TOUPPER(x) ((((x) >= 'a') && ((x) <= 'z')) ? (x) - 'a' + 'A' : (x))
#define FS_TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? (x) - 'A' + 'a' : (x))

#define SWAP16(x) (((x) << 8) & 0xff00) | (((x) >> 8) & 0xff)
#define SWAP32(x) ((((uint32_t)(x) >> 24) & 0xff) | (((uint32_t)(x) >> 8) & 0xff00) | (((uint32_t)(x) << 8) & 0xff0000) | (((uint32_t)(x) << 24) & 0xff000000))

#define MAKE_DWORD(b3, b2, b1, b0) (((uint32_t)((uint8_t)(b3) << 24)) | ((uint8_t)(b2) << 16) | ((uint8_t)(b1) << 8) | ((uint8_t)(b0)))
#define MAKE_WORD(h, l) (((uint32_t)(h) << 8) | ((l) & 0xffff))

#define GET_WORD_HIGH(x) ((uint32_t)(x) >> 16)
#define GET_WORD_LOW(x) ((uint32_t)(x) & 0xffff)
#define GET_WORD_HIGHBYTE(x) ((uint32_t)(x) >> 24)
#define GET_WORD_LOWBYTE(x) ((uint32_t)(x) & 0xff)

#define OFFSET(s,m) (size_t)&(((s * )0)->m)

void test_countof(){

int a[10] = {};
printf("%d\n",countof(a));
}

void test_FSTOUPPER(){

char a[14] = "This is a test";
char ans_up[14];
char ans_low[14];

for (int i = 0;i<14;i++){
ans_up[i] = FS_TOUPPER(a[i]);
printf("%c",ans_up[i]);
}

printf("\n");

for (int j = 0; j<14; j++){
ans_low[j] = FS_TOLOWER(ans_up[j]);
printf("%c",ans_low[j]);
}
}

void test_SWAP(){
uint16_t x = 0x1234;
uint32_t y = 0x12345678;

printf("%x\n",SWAP16(x));
printf("%x\n",SWAP32(y));
}

void test_MAKE_WORD(){

uint8_t a = 0x12;
uint8_t b = 0x34;
uint8_t c = 0x56;
uint8_t d = 0x78;

printf("%x\n",MAKE_WORD(a,b));
printf("%x\n",MAKE_DWORD(a,b,c,d));
}

void test_GET_WORD(){

uint32_t a = 0x12345678;

printf("%x\n",GET_WORD_HIGH(a));
printf("%x\n",GET_WORD_LOW(a));

printf("%x\n",GET_WORD_HIGHBYTE(a));
printf("%x\n",GET_WORD_LOWBYTE(a));
}

typedef struct _test
{
int x;
int y;
char z;
}test_t;

void test_OFFSET()
{
int a = mymacro(test_t, x);
int b = mymacro(test_t, y);
int c = mymacro(test_t, z);

printf("a = %d\n", a);
printf("b = %d\n", b);
printf("c = %d\n", c);
}

void main(void) {

test_countof();

test_FSTOUPPER();

test_SWAP();

test_MAKE_WORD();

test_GET_WORD();

test_OFFSET();
}

原文链接:本人CSDN博客