一、奇数位与偶数位互换
1、题目介绍
实现一个宏,将一个整数的二进制补码的奇数位与偶数位互换。输出格式依旧是十进制整数。示例:

2、分析
既然想要交换奇数位和偶数位上的数字,那么我们就要先得到奇数位和偶数位上的数字,那么如何得到呢。我们可以使用以下方法(以下的二进制都是补码):

将目的转换数字按位与上一个偶数位全是1奇数位全是0的特殊数字,就可以得到一个数字,这个数字奇数位上都为0,偶数位上的数字与目的转换数字的偶数位上一样,这里的特殊数字为01010101 01010101 01010101 01010101 转换为十进制为1431655765,这里可以直接使用十六进制0x55555555。同理,得到奇数位使用下面的方法,但是这个特殊的数字就是一个负数了:

这里的特殊数字为10101010 10101010 10101010 10101010 由于这里是补码,符号位为1,为负数,转换为原码为11010101 01010101 01010101 01010110 ,转换为十进制为-1431655766。我们这里可以直接使用十六进制,十六进制的话就不用从补码转换为原码了,可以直接使用补码转换为十六进制0xaaaaaaaa。
这样我们就得到了目的转换数字的奇数位和偶数位上的数字了,然后我们就要将奇数位和偶数位调整一下位置,将奇数位移到偶数位置,也就是右移一位,将偶数位移到奇数位置,也就是左移一位:

然后将调整位置后的两个奇数位和偶数位的数字按位或,就可以得到结果,结果为00000000 00000000 00000101 11011101 ,转换为十进制就是1501,与上面的示例结果相同。
3、代码
以下为具体代码实现:
#include <stdio.h>
// 定义宏来交换奇数位和偶数位
#define SWAP_ODD_EVEN_BITS(n) (((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1))
int main() {
    int num = 2798;
    int result = SWAP_ODD_EVEN_BITS(num);
    printf("Original number: %d\n", num);
    printf("Number after swapping odd and even bits: %d\n", result);
    return 0;
}运行结果:

二、将空格替换为%20
将一个字符串中的空格全部替换成%20。
1、方法一
只要读取到一个空格则将空格后面的字符串向后移两位,然后从空格这里加入%20。
代码:
#include <stdio.h>
#include <assert.h>
#include <string.h>
void Convert(char* str) {
	assert(str);
	char* string = str;
	while (*string) {
		if (*string == ' ') {
			int len = (int)strlen(string);
			char* temp = string + len + 2;
			while(len) {
				*temp = *(temp - 2);
				temp--;
				len--;
			}
			*string = '%';
			*(string + 1) = '2';
			*(string + 2) = '0';
			string += 2;
		}
		string++;
	}
}
int main() {
	char str[120] = "i love you.  olive juice";
	Convert(str);
	printf("%s\n", str);
	return 0;
}运行结果:

2、方法二
首先统计空格的个数,然后使用两个下标,因为一个空格扩充到%20就多出两个字符,所以第一个下标在字符长度加上二乘上空格的个数处,第二个下标在字符串的 \0 字符处,然后从后向前遍历字符串,当前面的下标遇到空格,则后面的下标开始填充%20,直到两个下标相遇。
代码:
#include <stdio.h>
#include <assert.h>
#include <string.h>
void Convert(char* str) {
	assert(str);
	char* string = str;
	int space_num = 0;
	while (*string) {
		if (*string == ' ') {
			space_num++;
		}
		string++;
	}
	int left = (int)strlen(str);
	int right = (int)strlen(str) + space_num * 2;
	while (left != right) {
		if (str[left] == ' ') {
			str[right] = '0';
			str[right - 1] = '2';
			str[right - 2] = '%';
			right -= 2;
		}
		else {
			str[right] = str[left];
		}
		left--;
		right--;
	}
}
int main() {
	char str[120] = "i love you.  olive juice";
	Convert(str);
	printf("%s\n", str);
	return 0;
}运行结果:




















