关于牛客网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从入门到架构师 人工智能躺过的坑 ...
随机推荐
- EMC NW NMM to restore MS AG database
Following last article, how to restore MS AG database , that is in the following: You see ? Cheer u ...
- 12-MyBatis02
今日知识 1. 关联查询 2. 延时加载 3. 查询缓存 关联查询 1.一对一 resultType实现 1. 写个定单的扩展类 public class OrdersExt extends Orde ...
- Python 调用 Shell命令
python程序中调用shell命令,是件很酷且常用的事情今天来总结一下 1.使用os模块 的 system 此函数会启动子进程,在子进程中执行command,并返回comman ...
- MyBatis 与Ibatis 区别
Ibatis 是 Mybatis 的前身,两者都是优秀的持久层框架. 区别: 1.mybatis 实现接口绑定,不需要具体接口实现类.但是需要在xml文件中 的 namespace 绑定具体的接口. ...
- CVE-2020-0668-Windows服务跟踪中的普通特权升级错误
CVE-2020-0668-Windows服务跟踪中的普通特权升级错误 在这里中,我将讨论在Windows Service跟踪中发现的任意文件移动漏洞.从我的测试来看,它影响了从Vista到10的所有 ...
- 【转载】wav文件格式分析与详解
WAV文件是在PC机平台上很常见的.最经典的多媒体音频文件,最早于1991年8月出现在Windows 3.1操作系统上,文件扩展名为WAV,是WaveFom的简写,也称为波形文件,可直接存储声音波形, ...
- Xcode如何集成Pod教程
一般开发都会用到很多第三方的框架,利用好他们可以加快开发进度,为了更方便将第三方的框架集成到我们的项目中,Pod是个很好的选择,现在说一下该怎么将Pod集成到我们的Xcode中 第一种方法 命令行的方 ...
- webpack nodejs npm关系
nodejs是js后端运行平台,可以把它看成java体系中对应的jdk,是三个里面最基础的.npm是nodejs的包管理工具,可以把它看成maven中包依赖管理那部分.webpack是前端工程化打包工 ...
- AVR单片机教程——示波器
本文隶属于AVR单片机教程系列. 在用DAC做了一个稍大的项目之后,我们来拿ADC开开刀.在本讲中,我们将了解0.96寸OLED屏,移植著名的U8g2库到我们的开发板上,学习在屏幕上画直线的算法, ...
- java开发规范学习
from 慕课网-明明如月-<阿里巴巴的Java开发手册> Integer缓存问题分析 1, Integer缓存[-128, 127]的数字,除此之外,将通过new创建. Long也是缓存 ...