首页 > 其他分享 >C之位域分析

C之位域分析

时间:2023-11-09 20:56:37浏览次数:17  
标签:分析 struct unsigned reg11 printf 位域 bit

1.首先回忆结构体

我们都知道定义一个结构体可以这样的方式定义:

struct Point {
    float x;
    float y;
} point;                      //等价于: struct  Point  point;

除此之外,如果不想声明结构体,只想定义结构体的话,还可以这样:

struct  {
    float x;
    float y;
} point;                      //等价于:  struct  Point  point;

2.位域之简单应用

做低层时,经常会读写寄存器,比如操作某位,设置为0或1,而在C语言中便为我们提供一种数据结构”位域”,使得我们通过读写”位域”来实现操作某位.

例如一个常见的位域的结构体,操作如下所示:

#include <stdio.h>
 
struct {                                                  
         unsigned mode:8;          //bit[0,7]:模式选择
         unsigned en:1;            //bit[8]   :使能选择
         unsigned reserved:1;      //bit[9]    :保留reserved  (也可以写成unsigned reserved:1;)
         unsigned clk_select:4;    //bit[10,13]:时钟选择
         unsigned ch_select:3;     //bit[14,15]:通道选择
}reg11;            //定义一个reg11变量,不声明结构体的好处在于确保变量唯一性
 
int main()
{      
         reg11.en =1;                     //bit8=1 --> 256
         printf("reg11=%d\n",reg11);         //打印 256
 
         reg11.mode =50;
         printf("reg11=%d\n",reg11);         //打印 256+50
         return 0;
}

打印:

reg11=256
reg11=306

3.位域之越界处理

比如,我们定义的某个位域只有固定1位,如果向该位写入超过1位的值.会自动保留最低1位.

#include <stdio.h>
struct {                                                  
         unsigned mode:8;          //bit[0,7]:模式选择
         unsigned en:1;            //bit[8]   :使能选择
         unsigned reserved:1;      //bit[9]    :保留reserved(也可以写成unsigned reserved:1;)
         unsigned clk_select:4;    //bit[10,13]:时钟选择
         unsigned ch_select:3;     //bit[14,15]:通道选择
}reg11;     //定义一个reg11变量,不声明结构体的好处在于确保变量唯一性
 
int main()
{     
         reg11.en =1;                     //bit8=1 --> 256
         printf("1st:reg11=%d\n",reg11);  //打印 256
 
         reg11.en =5;                     //5(b'101) 保留低1位: b'1
         printf("2st:reg11=%d\n",reg11);  //打印 256
 
         reg11.en =6;                     //6(b'110) 保留低1位: b'0
         printf("3st:reg11=%d\n",reg11);  //打印 0
 
         return 0;
}

打印:

1st:reg11=256
2st:reg11=256
3st:reg11=0

4.注意, 使用位域的结构体的长度默认最小值为int型(4字节),如果超过4字节(32位),则会是64位

示例:

#include <stdio.h>
 
struct {
         unsigned a:4;
         unsigned b:2;
         unsigned c:1;
}reg1;        //位域总长度只有7位
 
struct reg{
         unsigned a:4;
         unsigned b:2;
         unsigned c:32;
}reg2;
 
int main()
{      
         printf("%d\n",sizeof(reg1));
         printf("%d\n",sizeof(reg2));
         return 0;
}

打印:

4
8

#include <stdio.h>
 
typedef union{
unsigned char val;
 
struct {                                                  
         unsigned a:4; 
         unsigned b:1; 
         unsigned c:2;
         unsigned d:1;
       }bit;       
 
}reg11;
 
int main()
{      
        reg11 reg;
 
        reg.val=0;
        reg.bit.b = 1; 

        printf("bit size = %d\n",sizeof(reg.bit));
        printf("val size = %d\n",sizeof(reg.val));
        printf("reg11 size = %d\n",sizeof(reg));
        printf("\nval = %d\n",reg.val);
 
        return 0;
}

打印:

bit size = 4
val size = 1
reg11 size = 4

val = 16

5.如果某个寄存器只有8位(1字节),该如何使用位域处理?

直接定义为unsigned char

#include<stdio.h>
typedef struct
{
  unsigned char bit0:1;
  unsigned char bit1:1;
  unsigned char bit2:1;
  unsigned char bit3:1;
  unsigned char bit4:1;
  unsigned char bit5:1;
  unsigned char bit6:1;
}bitValue;

typedef union
{
  unsigned char bytedata;
  bitValue  bitdata;
}regValue;

int main()
{
  regValue data;

  data.bytedata= 0xBF;
  printf("bit6 = %d\n\n",data.bitdata.bit6);
  printf("bitValue size = %d\n",sizeof(data.bitdata));
  printf("regValue size = %d\n",sizeof(data));

  return 0;
}

打印:

bit6 = 0

bitValue size = 1
regValue size = 1

6.如果想定义并初始化

typedef struct {
    unsigned OVL     :6;
    unsigned OVOLCN :2;
}rg11;
 
rg11 reg = {57,1};            //初始化reg变量  OVL=57   OVOLCN=1 

 

标签:分析,struct,unsigned,reg11,printf,位域,bit
From: https://www.cnblogs.com/imreW/p/17822798.html

相关文章

  • 数据分析:智能企业七步曲(一)
     原创:MicroStrategy微策略中国 作者:数据杰论 时间走到2018年最后一个季度,过去几年热炒的大数据概念正在各行各业开始落地并展开实际应用,核心是关注数据如何能为企业带来价值。因此,数据分析及其种种实现手段不断被提上企业信息化建设议事日程,目标是使得决策和管理不再是过......
  • IDEA (JAVA) 内存使用高堆分析
    ====================HISTOGRAM====================Histogram.Top50byinstancecount[All-objects][Only-strong-ref]:1:[2.0M/141MB][1.75M/127MB]byte[]2:[1.99M/43.8MB][1.74M/38.3MB]java.lang.String3:[421K/15.1MB][369K/13.2MB]java.util.H......
  • Linux Media 子系统链路分析
    一、概述Media子系统是一个用于处理多媒体设备的框架,它提供了一组API和驱动程序,用于管理和控制视频、音频和其他多媒体设备。而V4L2是media子系统的一部分,用于处理视频相关的功能。了解MIPI摄像头后,发现linux系统下的流媒体驱动很复杂,而MIPI摄像头主要分为感光模组......
  • TSINGSEE青犀智能分析网关工服识别算法,如何最大限度保障工人安全?
    众所周知,TSINGSEE青犀智能分析网关算法繁多,大多数算法已经和大家讲解过了,今天就和大家聊一聊工服识别算法。工服识别算法一般应用于工地、化工、煤矿等场所,用来监督检测施工人员是否按照要求着工服,最大程度保障人员安全,具体有以下作用:1、实时监控与告警检测员工是否按照要求着工作......
  • 深入解析情感分析技术:从篇章到属性
    情感分析是自然语言处理的核心领域,专注于挖掘文本的主观情感。本文深入探讨了从篇章到属性级的情感分析技术,强调了上下文的重要性,并展示了Python和PyTorch的实践应用。通过深入了解这些技术背后的原理,我们揭示了深度学习在情感分析中的强大潜力和实际价值。关注TechLead,分享AI......
  • TSINGSEE青犀智能分析网关工服识别算法,如何最大限度保障工人安全?
    众所周知,TSINGSEE青犀智能分析网关算法繁多,大多数算法已经和大家讲解过了,今天就和大家聊一聊工服识别算法。工服识别算法一般应用于工地、化工、煤矿等场所,用来监督检测施工人员是否按照要求着工服,最大程度保障人员安全,具体有以下作用:1、实时监控与告警检测员工是否按照要求着......
  • linux文件系统与日志分析
    Linux文件系统inode表结构每一个inode表记录对应的保存了以下信息:inodenumber节点号文件类型权限UIDGID链接数(指向这个文件名路径名称个数)该文件的大小和不同的时间戳指向磁盘上文件的数据块指针有关文件的其他数据 ls -i:查看inode号 sta......
  • GlibcHeap-house-of-muney分析
    目录GlibcHeap-house-of-muney分析前言利用原理ELF文件解析符号查找利用过程POC思考参考GlibcHeap-house-of-muney分析houseofmuney的学习笔记。前言遇到了好几次hosueofmuney相关的题目,之前并没有深入地分析houseofmuney的原理,只是了解了一个大概。这次详细分析一下......
  • TSINGSEE视频智能分析人员入侵AI检测算法如何让城市管理更加高效、智慧?
    在城市管理场景中,经常面临着禁区垂钓、非法捕捞、行人闯红灯、小区盗窃、车辆乱停乱放等一系列管理难题,这给城市发展带来了不小的阻力,同时也极易增加管理的人力、物力和财力。传统的人员巡逻监管效率低并且存在时间差,很难及时发现这些违规行为,因此,利用AI智能检测技术,尤其是人员入......
  • 浙大软院2024届推免录取名单及分析
    名单分析浙大软院共录取电子信息专业推免生219人,机械专业推免生20人小Tips:浙大软院夏令营考核时间比较长,并且不发offer,但是如果夏令营能拿到优营能够直入预推免哦,以浙大为梦校并且背景不是特别好的同学可以多关注一下......