#include <stdio.h>
#define GET_BYTE(address) (*(volatile unsigned char*)(address))
int main() {
unsigned char byteValue = GET_BYTE(0x12345678); // 获取地址上的一个字节
printf("Byte value: %02X\n", byteValue); // 打印字节值
return 0;
}
5.求最大、最小值
#include <stdio.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
int main() {
int num1 = 10;
int num2 = 20;
int maxNum = MAX(num1, num2);
int minNum = MIN(num1, num2);
printf("Max value: %d\n", maxNum);
printf("Min value: %d\n", minNum);
return 0;
}
6.得到一个field在结构体(struct)中的偏移量
#include <stdio.h>
#define FIELD_OFFSET(struct_type, field_name) ((size_t)(&(((struct_type*)0)->field_name)))
typedef struct {
int field1;
char field2;
double field3;
} MyStruct;
int main() {
size_t offset = FIELD_OFFSET(MyStruct, field2);
printf("Offset of field2: %zu bytes\n", offset);
return 0;
}
7.得到一个结构体中field所占用的字节数
#include <stdio.h>
#define FIELD_SIZE(struct_type, field_name) (sizeof(((struct_type*)0)->field_name))
typedef struct {
int field1;
char field2;
double field3;
} MyStruct;
int main() {
size_t size = FIELD_SIZE(MyStruct, field2);
printf("Size of field2: %zu bytes\n", size);
return 0;
}
8.按照LSB格式把两个字节转化为一个Word
#include <stdio.h>
#define BYTES_TO_WORD(lsb, msb) (((unsigned short)(msb) << 8) | (lsb))
int main() {
unsigned char lsb = 0x34;
unsigned char msb = 0x12;
unsigned short word = BYTES_TO_WORD(lsb, msb);
printf("Word: 0x%04X\n", word);
return 0;
}
9. 按照LSB格式把一个Word转化为两个字节
#include <stdio.h>
#define WORD_TO_BYTES(word, lsb, msb) \
do { \
lsb = (unsigned char)(word & 0xFF); \
msb = (unsigned char)((word >> 8) & 0xFF); \
} while (0)
int main() {
unsigned short word = 0xABCD;
unsigned char lsb, msb;
WORD_TO_BYTES(word, lsb, msb);
printf("LSB: 0x%02X\n", lsb);
printf("MSB: 0x%02X\n", msb);
return 0;
}
10. 得到一个变量的地址(word宽度)
#define GET_ADDRESS(var) ((word *) &(var))
11. 得到一个字的高位和低位字节
#include <stdio.h>
#define GET_HIGH_BYTE(word) ((unsigned char)(((word) >> 8) & 0xFF))
#define GET_LOW_BYTE(word) ((unsigned char)((word) & 0xFF))
int main() {
unsigned short word = 0xABCD;
unsigned char highByte = GET_HIGH_BYTE(word);
unsigned char lowByte = GET_LOW_BYTE(word);
printf("High byte: 0x%02X\n", highByte);
printf("Low byte: 0x%02X\n", lowByte);
return 0;
}
12. 返回一个比X大的最接近的8的倍数
#include <stdio.h>
#define ROUND_UP_TO_EIGHT(x) (((x) + 7) & (~7))
int main() {
int x = 17;
int roundedUp = ROUND_UP_TO_EIGHT(x);
printf("Original value: %d\n", x);
printf("Rounded up to nearest multiple of 8: %d\n", roundedUp);
return 0;
}
13. 将一个字母转换为大写
#include <stdio.h>
#define TO_UPPERCASE(letter) ((letter >= 'a' && letter <= 'z') ? (letter - 'a' + 'A') : letter)
int main() {
char letter = 'a';
char uppercaseLetter = TO_UPPERCASE(letter);
printf("Original letter: %c\n", letter);
printf("Uppercase letter: %c\n", uppercaseLetter);
return 0;
}
14. 防止溢出的一个方法
#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))
15. 返回数组元素的个数
#include <stdio.h>
#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof((arr)[0]))
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int length = ARRAY_LENGTH(numbers);
printf("Array length: %d\n", length);
return 0;
}
16. 对于IO空间映射在存储空间的结构,输入输出处理
#define inp(port) (*((volatile byte *) (port)))
#define inpw(port) (*((volatile word *) (port)))
#define inpdw(port) (*((volatile dword *)(port)))
#define outp(port, val) (*((volatile byte *) (port)) = ((byte) (val)))
#define outpw(port, val) (*((volatile word *) (port)) = ((word) (val)))
#define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))
这个宏的目的是将一个字节的数据写入指定的端口。它使用类型转换和指针操作来确保对端口的访问是以字节为单位的,并且使用 volatile
修饰符来确保编译器不会进行优化和缓存操作,以防止出现意外的行为。
使用此宏时,你可以通过调用 outp(port, val)
来将 val
的值写入 port
端口。例如:
outp(0x1000, 0xFF);
这将将值 0xFF
写入地址 0x1000
的端口。
17. 宏定义防止使用时错误
用小括号包含。
比如计算平方:
#define SQUARE(x) ((x) * (x))
在使用 SQUARE
宏时,将要计算平方的表达式用小括号包含起来:
int result = SQUARE((2 + 3));
用do{}while(0)语句包含多语句防止错误
#include <stdio.h>
#define MULTI_STATEMENT_MACRO(x, y) \
do { \
printf("Executing statement 1\n"); \
printf("x + y = %d\n", (x) + (y)); \
printf("Executing statement 2\n"); \
} while(0)