#define 机制包括了一个规定:允许把参数替换到文本当中:这种实现通常称为 宏 宏定义的声明方式: #define ( parament-list ) stuff 其中 parament 是一个由逗号隔开的符号表,可能出现在buff中 注意: 参数列表的左括号必须与#define 相连,不然会被视为stuff的一部分
这里我们用一个简单的例子进行示范:
#include<stdio.h>
#define add(x,y) x+y
int main()
{
int a = 10;
int b = 20;
int sum = add(a, b);
printf("%d\n",sum);
}
其结果如图:
这个程序在预编译之后,add(a,b) 就已经被替换成 **a + b **,这里我们可以类比一下函数
既然我们已经知道宏定义是什么,和怎么写了,那么如何利用宏,实现将一个整数的二进制位的奇数位和偶数位交换?
要实现将一个整数的二进制位的奇数位和偶数位交换,我们可以先把二进制数的奇数位 和 偶数位上的每一个信息提取出来
这里我们了解一个二进制操作符:
& 和 | 都是对二进制形式进行操作
& : 与操作 ,如果 & 左右两边 均为 1,&的结果才为1 (&1 = 本身,& 0 = 0) | :或操作,如果 | 左右两边 均为 0, | 的结果才为 0
如果我们要保留奇数位的信息,可以 让奇数位的每一位& 1,让偶数位 & 0
同理,如果我们要保留偶数位的信息:让偶数位的每一位 & 1,让奇数位 & 0
我们以十六进制数进行表示:
一个十六进制数 表示四位二进制数,即 4byte,一个字节有 8 byte,整数类型 有四个字节,所以一共是8个16进制数表示一个整形
奇数位全为0,偶数位全为1 = 1010 = a 奇数位全为1,偶数位全为0 = 0101 = 5
所以我们可以这样:
偶数位信息:num & aaaaaaaa; 奇数位信息:num & 55555555;
这样我们就得到了整数的奇数位信息和 偶数位信息。
但是我们要进行交换,所以奇数位和偶数位的位置也应该交换
这时候我们需要了解移位操作符:
移位操作符也是对 二进制格式 进行操作 >> 表示是 对整形的二进制位向右边移动n位,移动之后 右边超出界限的丢弃,左边补原符号位 << 表示的是 对整形的二进制位向左边移动n位, 移动之后 左边超出界限的丢弃,右边补0 eg: 7的二进制为 0000 0000 0000 0110, 7<< 1之后其二进制位 :0000 0000 0000 1100 = 14;
#include<stdio.h>
//移位操作符的案例:
int main()
{
int a = 7 << 1;
printf("%d\n",a);
return 0;
}
所以我们可以让奇数位信息左移一位,让偶数位信息右移一位
因为补位补的是 0 ,0不会影响数据信息
#include<stdio.h>
//写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。
// 用n&(0xaaaaaaaa) a = 1010 只保留偶数位, 用n&(0x55555555) 5 = 0101 只保留奇数位
#define swap(n) (n = ((n&0xaaaaaaaa)>>1) + ((n&0x55555555)<<1))
int main()
{
int a = 10;
swap(a);
printf("%d\n",a);
return 0;
}
10的二进制格式: 0000 0000 0000 1010; 0000 0000 0000 0101 = 5;
输出结果:
0000 0000 0000 1010; 0000 0000 0000 0101 = 5;
输出结果: