C语言交换奇偶位与offsetof宏的实现方法

目录
  • 交换奇偶位
  • offsetof 宏
  • 总结

交换奇偶位

题目内容:写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。

注:二进制补码的最低位为第一位,最高位为第三十二位。

示例 1:
输入:10
输出:5
解释:10的二进制补码为00000000000000000000000000001010,交换奇偶位后为00000000000000000000000000000101,该二进制补码为5的二进制补码,故输出为5

思路:交换奇偶位,其实就当于将偶数位右移了一位,奇数位左移了一位。那现在的问题就转化成了如何得到偶数位和奇数位上的数字。如果想要得到奇数位上的数字,只需要让该数字和奇数位都为 1 的数字按位与,就能得到奇数位上的数字。同理,只需要让该数字和偶数位都为 1 的数字按位与,就能得到偶数位上的数字。得到这两个数字之后,对它们进行相应的移位,就能得到交换奇偶位后的结果了。

奇数位上都为 1 的数字
01010101010101010101010101010101
0x55555555
偶数位上都为 1 的数字
10101010101010101010101010101010
0xaaaaaaaa

#include <stdio.h>
#define SWAP(N) ((N & 0xaaaaaaaa) >> 1) + ((N & 0x55555555) << 1)
int Swap(const int num)
{
	return ((num & 0xaaaaaaaa) >> 1) + ((num & 0x55555555) << 1);
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret1 = Swap(n);
	int ret2 = SWAP(n);
	printf("ret1 = %d\n", ret1);
	printf("ret2 = %d\n", ret1);

	return 0;
}

offsetof 宏

题目内容:写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明。

示例 1:
输入:

输出:
offsetof(struct S, a) = 0
offsetof(struct S, b) = 0
offsetof(struct S, c) = 0
offsetof(struct S, d) = 0

struct S 的结构体内存对齐示意图

如果对结构体内存对齐这个知识点不熟悉的话。

思路:根据上面的struct S 的结构体内存对齐示意图可以知道,其实偏移量就是相对于起点的位置。所以,我们需要确定一个基准地址(起点)。为了方便,博主将 0 作为基准地址,当然也可以用任意一个数字作为基准地址。确定好基准地址后,我们就需要找到成员变量的地址,那么用成员变量的地址减去基准地址就能够得到结构体中某变量相对于首地址的偏移。

成员变量的地址
&( ( (struct_name*)0 )->mem_name)

#include <stdio.h>
#define OFFSETOF(struct_name, mem_name) (int)&( ( (struct_name*)0 )->mem_name)
struct S
{
	int a;
	short b;
	int c;
	char d;
};

int main()
{
	printf("%d\n", OFFSETOF(struct S, a));
	printf("%d\n", OFFSETOF(struct S, b));
	printf("%d\n", OFFSETOF(struct S, c));
	printf("%d\n", OFFSETOF(struct S, d));

	return 0;
}

总结

本篇文章主要讲解了如何交换二进制补码的奇偶位和模拟实现offsetof宏。其中模拟实现offsetof宏是百度曾经考过的原题,希望大家能过掌握。

到此这篇关于C语言交换奇偶位与offsetof宏实现的文章就介绍到这了,更多相关C语言交换奇偶位与offsetof宏内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言#define定义宏的使用详解

    目录 1.宏是什么 2.宏的用法 3. 宏的注意事项 4. 宏和函数的区别 5.命名要求 6. 条件编译 常见条件编译指令及应用场景 1.宏是什么 #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro). 语法: #define name( parament-list ) stuff parament-list:是一个由逗号隔开的符号表. 2.宏的用法 #define SUM(x,y) ((x)+(y)) int main

  • C生万物C语言宏将整数二进制位的奇偶数位交换

    目录 题目分析 && 实现思路[位运算] 1.获取这个整数的奇数位和偶数位 2.使用移位运算使[奇变偶][偶变奇] 3.合并奇数位和偶数位 ⌨代码分析 1.代码展示 2.算法图解分析 总结与提炼 题目分析 && 实现思路[位运算] 首先来说一下本题的实现思路

  • 一文带你搞懂C语言预处理宏定义

    目录 预定义符号 #define #define 定义标识符 #define 定义宏 替换规则 # 和## 预定义符号 这些预定义符号都是语言内置的 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义 VS环境下未定义__STDC__ ,说明Visual Studio并未完全遵循ANSI C. #define #defi

  • C语言宏定义的扩展定义讲解

    目录 1. 常量宏定义 2. 定义宏函数 3. 宏定义和#号结合 4. 宏定义和两个#结合 5. 宏定义和do…while()的结合 6. #ifdef…#else…#endif 7. #ifndef…#else…#endif 8. #if defined() … #else … #endif 1. 常量宏定义 使用c中的#define 来定义一个常量来表示一年有多少秒 #define SECONDS_PER_YEAR (606024*365)UL 求圆的周长: #define D® (r +

  • C语言详细分析宏定义与预处理命令的应用

    目录 宏定义与预处理命令 预处理命令 - 宏定义 定义符号常量 定义傻瓜表达式 定义代码段 预定义的宏 函数 VS 宏定义 预处理命令 - 条件式编译 示例 宏定义与预处理命令 预处理阶段:处理宏定义与预处理命令: 编译期:检查代码,分析语法.语义等,最后生成.o或.obj文件: 链接期:链接所有的.o或.obj文件,生成可执行文件. 预处理命令 - 宏定义 定义符号常量 #define PI 3.1415926 #define MAX_N 10000 定义傻瓜表达式 #define MAX(a

  • C语言宏定义容易认不清的盲区梳理

    目录 1.概念 3.宏不是函数 4.宏定义不是说明或语句 5.宏不是类型定义 6.与之相关的宏定义 7.总结 1.概念 #define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本. 命令有两种格式:一种是简单的宏定义,另一种是带参数的宏定义. (1)简单的宏定义: #define<宏名> <字符串> #defineVALUE((sizeof(a))/sizeof(a[0])) (2) 带参数的宏定义 #defin

  • C语言交换奇偶位与offsetof宏的实现方法

    目录 交换奇偶位 offsetof 宏 总结 交换奇偶位 题目内容:写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换. 注:二进制补码的最低位为第一位,最高位为第三十二位. 示例 1:输入:10输出:5解释:10的二进制补码为00000000000000000000000000001010,交换奇偶位后为00000000000000000000000000000101,该二进制补码为5的二进制补码,故输出为5. 思路:交换奇偶位,其实就当于将偶数位右移了一位,奇数位左移了一位.那现在的问题

  • 详解易语言交换变量

    易语言交换变量图文解析 方便操作易语言的代码 1.新建一个易语言 2.放上1个控件 3.这里启动菜单的代码 4.写好一个用来操作的类 5.写几个自定义数据类型 6.编译成exe文件,放到桌面上 7.这里就是运行之后的效果 以上步骤很简单,大家跟着操作下,感谢大家对我们的支持.

  • Java 交换两个变量的数值实现方法

    一.参数传递方法 为解决标题问题,首先介绍参数传递方法.目前各类程序设计语言的参数传递方法主要有三种: 1.按值传递 2.按引用传递 3.按指针传递 其中按值传递表示方法(函数)接收的是调用者提供的变量的拷贝,不改变参数的值:按引用传递表示方法(函数)接收的调用者提供的变量地址:按指针传递表示方法(函数)接收的是调用者提供的指针的拷贝,不改变指针的值和地址,但可以改变指针所指向的地址. 二.Java参数传递方法 Java提供的参数传递方法,很遗憾只有一种,按值传递.也就是说,方法得到的是所有参数

  • C语言实现求最大公约数的三种方法

    目录 题目描述 问题分析 代码实现 方法一:穷举法 方法二:辗转相除法 方法三:更相减损法 题目描述 求任意两个正整数的最大公约数 问题分析 最大公因数,也称最大公约数.最大公因子,指两个或多个整数共有约数中最大的一个.a,b的最大公约数记为(a,b),同样的,a,b,c的最大公约数记为(a,b,c),多个整数的最大公约数也有同样的记号.求最大公约数有多种方法,常见的有质因数分解法.短除法.辗转相除法.更相减损法.与最大公约数相对应的概念是最小公倍数,a,b的最小公倍数记为[a,b]. --百度

  • GO语言实现列出目录和遍历目录的方法

    本文实例讲述了GO语言实现列出目录和遍历目录的方法.分享给大家供大家参考.具体如下: GO语言获取目录列表用 ioutil.ReadDir(),遍历目录用 filepath.Walk(),使用方法课参考本文示例. 具体示例代码如下: 复制代码 代码如下: package main import (  "fmt"  "io/ioutil"  "os"  "path/filepath"  "strings" )

  • Go语言扫描目录并获取相关信息的方法

    本文实例讲述了Go语言扫描目录并获取相关信息的方法.分享给大家供大家参考.具体分析如下: 前言:最近看到Go里面有一个func很容易就可以扫描整个目录,并且可以得到相应的目录和文件信息,所以我将其进行了封装,拿到file info的所有信息 这样就可以方便的做其它用途了. 直接上代码,代码基于Go version 1 复制代码 代码如下: package main import (     "path/filepath"     "os"     "fla

  • C语言中函数指针的三种使用方法总结

     C语言中函数指针的三种使用方法总结 在这里分享一下自己的心得,希望和大家一起分享技术,如果有什么不足,还请大家指正.写出这篇目的,就是希望大家一起成长,我也相信技术之间没有高低,只有互补,只有分享,才能使彼此更加成长. 定义方式:int (*p)(int x, int y); 实现代码: #include <stdio.h> int sum(int x, int y){ return x + y; } int reduce(int x, int y){ return x - y; } int

  • C语言连接并操作Sedna XML数据库的方法

    本文实例讲述了C语言连接并操作Sedna XML数据库的方法.分享给大家供大家参考.具体如下: #include "libsedna.h" #include "stdio.h" int handle_error(SednaConnection* conn, const char* op, int close_connection) { printf("%s failed: \n%s\n", op, SEgetLastErrorMsg(conn))

  • go语言通过odbc访问Sql Server数据库的方法

    本文实例讲述了go语言通过odbc访问Sql Server数据库的方法.分享给大家供大家参考.具体如下: 这里需要用到go-odbc库,开源地址为:https://github.com/weigj/go-odbc 复制代码 代码如下: package main; import (     "fmt"     "database/sql"     _"odbc/driver" ) func main(){     conn,err := sql.O

  • Go语言使用HTTP包创建WEB服务器的方法

    本文实例讲述了Go语言使用HTTP包创建WEB服务器的方法.分享给大家供大家参考,具体如下: 在Golang中写一个http web服务器大致是有两种方法: 1 使用net包的net.Listen来对端口进行监听 2 使用net/http包 这里是讨论如何使用net/http包创建一个web服务器 net/http请求提供了HTTP客户端和服务端的具体实现 http客户端 先看到的是Get,Post,PostForm三个函数.这三个函数直接实现了http客户端 复制代码 代码如下: import

随机推荐