关于牛客网C语言结构体位域(bit-fields)的一道题
题目链接地址:
https://www.nowcoder.com/questionTerminal/f4e20747a2dd4649bac0c028daa234f4
来源:牛客网
| 低地址字节 | Byte | Byte |
| 高地址字节 | Byte | Byte |
x86是小段模式,LSB(最不关键的字节)存放在低地址,MSB(最关键的字节)存放在最高位。
大小端模式都是针对于字节而非位来说的,对于字节,顺序如平常书写顺序。
这种“:4”的写法,是结构体位域(bit-fields)语法。
题目中的a,b,c按照内存的地址自然的从低往高分配。
分配结果如下:
| 低地址字节 | b3b2b1b0 | a3a2a1a0 |
| 高地址字节 | c6c5c4c3 | c2c1c0b4 |
a=a3a2a1a0=2=(0010)2
b=b4b3b2b1b0 =3=(00011)2
c=0
| 低地址字节(LSB) | 0011 | 0010 |
| 高地址字节(MSB) | 0000 | 0000 |
因而最后这一段内存中的数据视作short的时候为0x(0032)=50.
另外,纠正一下其它题解的一些错误。
1. 大端小端是针对字节而非位。
2. 这道题和栈的内存分配是从高位到低位分配没有任何关系。
为什么说和栈的内存分配没关系。
因为首先test这个结构体是全局变量,占用的是堆空间而非栈空间。其次,即使test放在main函数内部声明,依旧和栈的内存分配没关系,因为test是一个struct mybitfields类型的结构体,栈分配内存地址的时候是作为一个整体,而test内部的内存布局依然是要遵循结构体成员变量的内存分布,和栈的内存分配没有关系。只有多个mybitfields结构体的时候才需要考虑这一点。
例如——
#include <stdio.h>
#include <stdlib.h>
struct mybitfields {
unsigned short a : 4;
unsigned short b : 5;
unsigned short c : 7;
};
int k, i; /*使用全局变量,占用堆空间,避免干扰下面的栈分配地址的输出分析。其实放进去也不是不能分析,主要是懒 */
int main(void) {
struct mybitfields high, test, low;
/* high,test,low在栈中占用的空间由高到低。但是它们内部的空间占用仍然符合结构体的位域的规则。*/
test.a = 2;
test.b = 3;
test.c = 0;
high.a = 4;
high.b = 5;
high.c = 0;
low.a = 1;
low.b = 2;
low.c = 0;
i = *((short *)&test);
printf("short test: %08X\n", i);
k = *((int *)&test);
printf("int test: %08X\n", k);
k = *((int *)&high);
printf("int high: %08X\n", k);
k = *((int *)&low);
printf("int low: %08X\n", k);
}
输出如下
| short test: 00000032 int test: 00540032 int high: CCD00054 int low: 00320021 |
其中high由于在栈中的高地址(占据16位),更高的16位未知,所以输出的高16位是CCDD.
关于牛客网C语言结构体位域(bit-fields)的一道题的更多相关文章
- 牛客网_Go语言相关练习_判断&选择题(6)
本文共34道题目 一.判断题 此题考查编码规范. 反射最常见的使用场景是做对象的序列化(serialization,有时候也叫Marshal & Unmarshal). 例如:Go语言标准库的 ...
- 牛客网_Go语言相关练习_选择题(1)
声明:题目源自牛客网. 一.单项选择题 解析:作为形参时,可以要求单向,只读或只写. 解析:Go语言的内存回收机制规定,只要有一个指针指向引用一个变量,那么这个变量就不会被释放(内存逃逸),因此在Go ...
- 牛客网_Go语言相关练习_判断&选择题(4)
题目来源于牛客网 一.判断题 成员变量或者函数的首字母表示是否对外部可见. switch后面的声明语句和表达式语句都是可以选择的.例如: //可以什么都不加 switch: break; 错误指的是可 ...
- 牛客网_Go语言相关练习_选择题(3)
题目来源于牛客网 一.选择题 Go语言自带垃圾回收机制. 如果是值传递的话子函数对map修改不会影响父函数中的map,如果是地址传递则会影响. go语言编译器会自动在以标识符.数字字面量.字母字面量. ...
- 牛客网_Go语言相关练习_选择题(2)
注:题目来源均出自牛客网. 一.选择题 Map(集合)属于Go的内置类型,不需要引入其它库即可使用. Go-Map_菜鸟教程 在函数声明中,返回的参数要么都有变量名,要么都没有. C选项函数声明语法有 ...
- C语言结构体--位域
有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可.比如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位.正是基于这种考虑,C语言又提供了一种叫做位域 ...
- C语言结构体位域
demo: typedef struct { int a:2; int b:2; int c:1; }test; int main() { test t; t.a=1; t.b=3; t.c=1; / ...
- 牛客网_Go语言相关练习_判断&选择题(5)
一.判断题 defer应该在if后面,如果文件为空,close会崩溃. package main import ( "os" "fmt" ) func main ...
- 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响
不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号: 大数据躺过的坑 Java从入门到架构师 人工智能躺过的坑 ...
随机推荐
- eclipse 连接sql sever
https://www.cnblogs.com/newen/p/4428541.html 和eclipse连接mysql相似,只是 String url="jdbc:sqlserver:// ...
- Linux系统资料
Linux的心得: 1)Linux由众多微内核组成,其源代码完全开源: 2)Linux继承了Unix的特性,具有非常强大的网络功能,其支持所有的因特网协议,包括TCP/IPv4. TCP/IPv6和链 ...
- python库之numpy学习---nonzero()用法
当使用布尔数组直接作为下标对象或者元组下标对象中有布尔数组时,都相当于用nonzero()将布尔数组转换成一组整数数组,然后使用整数数组进行下标运算. nonzeros(a)返回数组a中值不为零的元素 ...
- JAVA编程思想——分析阅读
需要源码.JDK1.6 .编码风格参考阿里java规约 7/12开始 有点意识到自己喜欢理论大而泛的模糊知识的学习,而不喜欢实践和细节的打磨,是因为粗心浮躁导致的么? cron表达式使用 设计能力.领 ...
- 总结JavaScript对象的深浅拷贝
十四.对象的浅拷贝与深拷贝 什么是对象的拷贝? 将一个对象赋值给另外一个对象, 我们称之为对象的拷贝 什么是深拷贝, 什么是浅拷贝? 我们假设将A对象赋值给B对象 浅拷贝是指, 修改B对象的属性和方法 ...
- Python socket 基础(Server) - Foundations of Python Socket
Python socket 基础 Server - Foundations of Python Socket 通过 python socket 模块建立一个提供 TCP 链接服务的 server 可分 ...
- python 中列表 元组 字典 集合的区别
先看图片解释 (1)列表 什么是列表呢?我觉得列表就是我们日常生活中经常见到的清单.比如,统计过去一周我们买过的东西,把这些东西列出来,就是清单.由于我们买一种东西可能不止一次,所以清单中是允许有重复 ...
- golang 自定义接口 和 实现接口
/* 定义: type 接口名 interface{ 方法名(可选:参数列表) 可选:返回值列表 || (可选:返回值列表) } 例:type Writer interface { Write(p [ ...
- Tomcat 配置2 tomcat-users.xml
Tomcat的配置 Tomcat的主要配置文件有3个,分别是: Tomcat-users.xml. web.xml server.xml. 配置Tomcat-users.xml 该文 ...
- (数据科学学习手札78)基于geopandas的空间数据分析——基础可视化
本文对应代码和数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 通过前面的文章,我们已经对geopanda ...