关于牛客网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从入门到架构师 人工智能躺过的坑 ...
随机推荐
- Java并发读书笔记:如何实现线程间正确通信
目录 一.synchronized 与 volatile 二.等待/通知机制 等待 通知 面试常问的几个问题 sleep方法和wait方法的区别 关于放弃对象监视器 三.等待通知典型 生产者消费者模型 ...
- 题解 【[MdOI2020] Decrease】
\[ \texttt{Preface} \] 感觉 C 比 B 还简单? \[ \texttt{Description} \] 给定一个 \(n×n\) 的矩阵,你可以进行若干次操作. 每次操作,你可 ...
- 1 深入Web请求过程
1.1 B/S网络架构概述 B/S 网络架构从前端到后端都得到了简化,都基于统一的应用层协议HTTP来交互数据,与大多数传统C/S互联网应用程 序采用的长连接的交互模式不同,HTTP采用无状态的短连接 ...
- 一. 数据分片和路由 <<大数据日知录>> 读书笔记
本章主要讲解大数据下如何做数据分片,所谓分片,即将大量数据分散在不同的节点,同时每个存储节点还要做副本备份. 而一般的抽象分片方法是, 先将数据映射到一个分片空间,这是多对一的关系,即一个数据分片区间 ...
- 《Head first设计模式》之抽象工厂
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类. 确保原料的一致 披萨店成功的关键在于新鲜.高质量的原料.要如何确保每家加盟店使用高质量的原料?你打算建造一家生成原料的 ...
- javascript canvas全部API
HTMLCanvasElement//canvas elem对象 属性 height//高 width//宽 方法 getContext()//获取<canvas>相关的可绘制的上下文 t ...
- pytoch之 encoder,decoder
import torch import torch.nn as nn import torch.utils.data as Data import torchvision import matplot ...
- 并发编程之线程池ThreadPoolExecutor
前言 在我们平时自己写线程的测试demo时,一般都是用new Thread的方式来创建线程.但是,我们知道创建线程对象,就会在内存中开辟空间,而线程中的任务执行完毕之后,就会销毁. 单个线程的话还好, ...
- Shiro -- (四) 数据库支持
主要就是JdbcRealm这个类 先看一下部分源码: 先建表:users(用户名 / 密码).user_roles(用户 / 角色).roles_permissions(角色 / 权限),并且往use ...
- Java数据结构--双向链表的实现
#java学习经验总结------双向链表的实现 双向链表的建立与单链表类似,只是需要使用pre指针指向前一个结点,并且在删除添加时不仅仅考虑next package datastructure; p ...