0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

浅谈嵌入式C语言各种数据类型的内存映像

工程师进阶笔记 来源:工程师进阶笔记 2023-12-28 18:21 次阅读

嵌入式 C 语言各种数据类型的内存映像(32位平台),如下图所示。

6249b2c2-a567-11ee-8b88-92fbcf53809c.png

1 - signed char


#include 


intmain()
{
charmin=1<<7;
    char max = (1<<7)-1;   
    for(int i=min;i<=max;i++)
    
    if(i<0)printf("%.2X ",(unsignedchar)i);
    else{
        printf("%c ",i);
        if(i%32==0)
        printf("
%d ",i);
    }
    getchar();
}

output :

625d616e-a567-11ee-8b88-92fbcf53809c.png

2 - 整型的signed和unsigned


#include 


int main()
{
signedintsmin=1<<31;
    signed int smax = (1<<31)-1;
    printf("%d
",smin);    // -2147483648


    printf("%d
",smax);    // 2147483647
    unsigned int umax = -1;    printf("%u
",umax);    // 4294967295
    umax = (1<<32)-1;    printf("%u
",umax);    // 4294967295


}

如果一个表达式同时包含signed和unsigned整型,signed会提升为unsgined,可能会隐藏一些意想不到的错误,特别是用在比较运算时:

unsigned int a=4294967290;    
int b=-6; 
printf("%d
",a==b);//1,bpromotestounsigned

3 - double的二进制位显示


#include 


void printByte(double d)
{
intbs=sizeofd;
unsignedchar*ch=(unsignedchar*)&d;
for(inti=0;i

将double分成4部分显示:

#include


typedefstructpacked_double{
    unsigned int low32;    // 小数位 低32位
    unsigned int low20:20; // 小数位 低33-52位
    unsigned int exp11:11; // 指数位 低53-63位,移码1023+二进制整数位-1
    unsigned int sign:1;  // 符号位} packed_double;typedef union {    double d;
    packed_double b;
} packed;


int main()
{
    packed pd;
    pd.d = -15.75;
    pd.d = 12.3;


    printf("%u %u %u %u
",pd.b.sign,pd.b.exp11,pd.b.low20,pd.b.low32);


    getchar(); 
    return 0;
}/*


0 1026 1015808 0
*/


0 1026 1015808 0
*/

4 - 数组是相同数据类型的依次存储

数组名是一个存储数据首元素地址具有常量性质的特殊指针,成员是相对于基址的偏移:


#include 


void printArr(short arr[],int len)
{
for(inti=0;i

5 - 枚举只是枚举可以取值的一些符号常量的一个特殊整型


#include 


int main()
{

    enum Nm{LOSS,TIE,WIN}nm; // 实质是一个整型,成员只是可能的右值(符号常量)的枚举


    nm = LOSS;    printf("%d ",nm); // 0
    nm = TIE;    printf("%d ",nm); // 1
    nm = WIN;    printf("%d ",nm); // 2
    nm = (enum Nm)3;  
    printf("%d ",nm); // 3
    printf("
%d",sizeof(enum Nm)); // 4
    getchar();
}

枚举让相关符号常量内聚为一组,相对于#define,枚举对数据的描述性更清晰。

6 - 共用体成员的起始地址相同,共用一块内存空间,值相互覆盖


#include 


int main()
{

    union Nn{int a; double b;}nn;// 成员的起始地址相同,值相互覆盖


    nn.a = 123; // 
    printf("起始地址:%X,内存空间占用:%d
",&nn.a,sizeof nn.a);
    nn.b = 12.3;    printf("起始地址:%X,内存空间占用:%d
",&nn.a,sizeof nn.b);
    nn.a = 12;    printf("起始地址:%X,内存空间占用:%d
",&nn.a,sizeof nn.a);
    getchar();
}/*
起始地址:12FF40,内存空间占用:4
起始地址:12FF40,内存空间占用:8
起始地址:12FF40,内存空间占用:4
*/

当一些事物具有更多共性,但有少量差异时,可以只用一个内嵌一个共用体的结构体来描述:


#include
#include
#define MAXPARTS 12


structParts
{ // 零件


  int cost;


  char supplier[12];


  char unit[12] ;


};


structAssembly
{ // 装配件


  int n_parts;


  struct {


    char partno[12];
    short quan;
  }parts[MAXPARTS];


};


structInventory
{//存货类型,或是零件,或是装配件


  char partno[10];


  int quan;


  enum{PART,ASSEMBLY}type; // 存货类型


  union {


    struct Parts parts;


    struct Assembly assembly;
  }info;
};


intmain()
{

  struct Inventory screen;


  strcpy(screen.partno,"p001");
  screen.quan = 12;
  screen.type = Inventory::PART;
  screen.info.parts.cost = 122;


  strcpy(screen.info.parts.supplier,"hw");  strcpy(screen.info.parts.unit,"pcs");  


  struct Inventory shell;
  strcpy(shell.partno,"a001");
  shell.quan = 4;
  shell.type = Inventory::ASSEMBLY;
  shell.info.assembly.n_parts=22;  strcpy(shell.info.assembly.parts[0].partno,"d001");
  shell.info.assembly.parts[1].quan = 5;  int costs;  if(shell.type == Inventory::ASSEMBLY)
    costs = shell.info.assembly.n_parts;  
  printf("%d
",costs); //22
  getchar();  return 0;
}

7 - 结构体是不同数据类型的数据依次存储在一起

结构体各数据成员的引用可以通过其内存大小和字节对齐来相对于基址偏移来计算。结构体通常用于描述某一事物,用其成员来描述该事物的某些关键属性。让该事物既可以用结构体变量整体表示,也可以对其成员分别引用来处理该事物的各个属性。

#include 
int main()
{
structdemo
{
chara;
shortb;
intc;
    } abc; // 成员相对于基址偏移,字节对齐


    abc.b=12;


short*p=(short*)((int)&abc+sizeof(short));//模拟编译器计算第2个成员的偏移地址
    printf("%d %d
",abc.b,*p); // 12 12
    printf("%d
",sizeof(struct demo));// 8
    getchar();
}

8 - 位域是对整型数据的按位处理

(一次可以处理n个位,1<=n<=整形长度),位域(全局)二进制位显示:


#include 


voidprintBinM(unsignedintn)
{
for(inti=31;i>=0;i--)
printf("%d",(n&1<>i);
printf("
");
}


structBf{
    unsigned a:3;    
    unsigned b:4;    
    unsigned c:5;
}bf;


intmain()
{
    bf.a =1;
    bf.b=15;
    bf.c=3;    int *p = (int*)&bf; // 505
    printf("%d
",*p);
    printBinM(*p);//00000000000000000000000111111001
    getchar();
}

位域(局部)二进制位显示:


#include 


voidprintBinM(unsignedintn)
{
for(inti=31;i>=0;i--)
        printf("%d",(n & 1<>i);


printf("
");
}


intmain(){
structBf{
        unsigned a:3;    
        unsigned b:4;    
        unsigned c:5;
    }bf;
    bf.a =1;
    bf.b=15;
    bf.c=3;    int *p = (int*)&bf; // -858996231
    printf("%d
",*p);
    printBinM(*p);//11001100110011001100000111111001
    getchar();
}
审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    4982

    文章

    18281

    浏览量

    288459
  • C语言
    +关注

    关注

    180

    文章

    7530

    浏览量

    128712
  • 数据类型
    +关注

    关注

    0

    文章

    227

    浏览量

    13498

原文标题:嵌入式 C 语言,各种数据类型的内存映像

文章出处:【微信号:工程师进阶笔记,微信公众号:工程师进阶笔记】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Labview各种数据类型

    Labview各种数据类型
    发表于 12-11 11:27

    超实用的读写ini文件VI,支持各种数据类型

    支持各种数据类型的读写ini文件
    发表于 02-18 09:58

    嵌入式基础之C语言全套视频教程分享

    嵌入式C语言是作为嵌入式Linux开发的基础语言,也是学习嵌入式的必备
    发表于 05-02 13:28

    嵌入式 C 语言

    目录基础知识数据类型const 用法作用域与 static 用法extern 用法基础知识嵌入式C语言和普通C
    发表于 07-01 08:58

    如何获取F28335各种数据类型所占的字节数?

    如何获取F28335各种数据类型所占的字节数?
    发表于 10-22 06:59

    嵌入式开发的C语言代码中数据类型

    嵌入式开发中的C语言代码中,经常可以看到类似uint8_t、uint16_t、uint32_t、uint64_t这种数据类型,在教材中却从来没见过。实际上这些
    发表于 12-15 07:43

    嵌入式软件程序设计

    ,可以直接操作寄存器等硬件设备,运算速度快,相对于机器语言来说开发效率相对好,但对于高级语言来说开发效率仍低。各种程序语言的特点程序语言
    发表于 12-21 08:28

    C预处理与C语言基本数据类型

    指令表:注意:宏名的书写由标识符与两边各两条下划线构成。C语言基本数据类型不同操作系统中数据类型所占字节数图解数据类型的其他分类:变量常量(
    发表于 12-21 08:29

    嵌入式开发常用数据类型有哪些

    嵌入式开发中的常用数据类型嵌入式开发主要用到的是C语言C
    发表于 12-24 08:15

    整型的signed和unsigned详解 double的二进制位显示

    C语言各种数据类型内存映像(32位平台)
    的头像 发表于 06-06 17:01 1996次阅读

    C语言各种数据类型内存映像

      C语言各种数据类型内存映像(32位平台): 0 signed char   #include stdio.hint main(){    char min = 17;    ch
    的头像 发表于 07-06 14:49 817次阅读

    C语言数据类型-2

    对于一个计算机程序,它所做的所有运算的本质都是数据的处理。但是数据的样式并不单一,因此就有了各种各样的数据类型。在C语言中,为了处理这些复杂
    的头像 发表于 02-21 14:44 544次阅读
    C<b class='flag-5'>语言</b>的<b class='flag-5'>数据类型</b>-2

    Verilog最常用的2种数据类型

    Verilog 最常用的 2 种数据类型就是线网(wire)与寄存器(reg),其余类型可以理解为这两种数据类型的扩展或辅助。
    的头像 发表于 05-29 16:27 1213次阅读
    Verilog最常用的2<b class='flag-5'>种数据类型</b>

    PostgreSQL中可用的各种数据类型

    PostgreSQL是一种功能强大的开源关系型数据库管理系统,具有广泛的数据类型支持。在本教程中,我们将介绍PostgreSQL中可用的各种数据类型,包括数值、字符串、几何、时间、日期、布尔、货币
    的头像 发表于 09-19 14:08 1025次阅读

    redis的五种数据类型

    Redis是一种高性能的内存数据库,常用于缓存、任务队列、分布式锁等场景。它提供了多种数据类型来满足各种不同的需求,包括字符串(string)、哈希(hash)、列表(list)、集合
    的头像 发表于 11-16 11:06 345次阅读