电子产业一站式赋能平台

PCB联盟网

搜索
查看: 11|回复: 0
收起左侧

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

[复制链接]
匿名  发表于 2023-12-28 17:50:00 |阅读模式
我是老温,一名热爱学习的嵌入式工程师
关注我,一起变得更加优秀!嵌入式 C 语言各种数据类型的内存映像(32位平台),如下图所示。

cxbn04l5ukd64010977636.png

cxbn04l5ukd64010977636.png


1 - signed char
  • #include
    int main(){        char min = 17;    char max = (17)-1;       for(int i=min;i        if(i0)printf("%.2X ",(unsignedchar)i);    else{        printf("%c ",i);        if(i%32==0)        printf("
    %d ",i);    }    getchar();}output :

    0tqh3advasb64010977736.png

    0tqh3advasb64010977736.png


    2 - 整型的signed和unsigned
  • #include
    int main(){    signed int smin = 131;    signed int smax = (131)-1;    printf("%d
    ",smin);    // -2147483648
        printf("%d
    ",smax);    // 2147483647    unsigned int umax = -1;    printf("%u
    ",umax);    // 4294967295    umax = (132)-1;    printf("%u
    ",umax);    // 4294967295
    }
    如果一个表达式同时包含signed和unsigned整型,signed会提升为unsgined,可能会隐藏一些意想不到的错误,特别是用在比较运算时:
  • unsigned int a=4294967290;    int b=-6; printf("%d
    ",a==b); // 1 , b promotes to unsigned
    3 - double的二进制位显示
  • #include
    void printByte(double d){    int bs = sizeof d;    unsigned char *ch = (unsigned char*)&d;    for(int i=0;iprintf("%.2X ",*(ch+i));}
    int main(){    int n = 0x01020304;    if(*(char*)&n == 4)    {        printf("小端:");//小端:        double d = 15.75; // 1111.11, 指数位值:1023+3        //0 100 0000 0010 1111100000000000000000000000000000000000000000000000        printByte(d);//00 00 00 00 00 80 2F 40        // 40              2F               80        // 0100 0000 0010 1111 1000 0000        getchar();    }}将double分成4部分显示:
  • #include
    typedef struct packed_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(int i=0;i    {                printf("%d ",*(arr+i));    }
        printf("
    ");}
    int main(){    short arr[] = {1,3,2};    int len = sizeof arr / sizeof *arr;    printArr(arr,len);}
    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
    struct Parts{ // 零件
      int cost;
      char supplier[12];
      char unit[12] ;
    };
    struct Assembly{ // 装配件
      int n_parts;
      struct {
        char partno[12];    short quan;  }parts[MAXPARTS];
    };
    struct Inventory{ // 存货类型,或是零件,或是装配件
      char partno[10];
      int quan;
      enum{PART,ASSEMBLY}type; // 存货类型
      union {
        struct Parts parts;
        struct Assembly assembly;  }info;};
    int main(){
      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(){   struct demo   {        char a;        short b;        int c;    } 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位域(全局)二进制位显示:
  • #include
    void printBinM(unsigned int n){    for(int i=31;i>=0;i--)        printf("%d",(n & 1i);    printf("
    ");}
    struct Bf{        unsigned a:3;        unsigned b:4;        unsigned c:5;}bf;
    int main(){    bf.a =1;    bf.b=15;    bf.c=3;    int *p = (int*)&bf; // 505    printf("%d
    ",*p);    printBinM(*p);//00000000000000000000000111111001    getchar();}位域(局部)二进制位显示:
  • #include
    void printBinM(unsigned int n){    for(int i=31;i>=0;i--)        printf("%d",(n & 1i);
        printf("
    ");}
    int main(){    struct Bf{            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();}文章来源于网络,版权归原作者所有,如有侵权,请联系删除。
    -END-
    往期推荐:点击图片即可跳转阅读

                                                           
                                                                   
                                                                           
                                                                                   

    qvftjj5vho464010977836.jpg

    qvftjj5vho464010977836.jpg

                                                                                   
                                                                                            稚晖君的智能机器人,带火了这款嵌入式操作系统和核心板…
                                                                                   
                                                                           
                                                                   
                                                           
                                                   

                                                           
                                                                   
                                                                           
                                                                                   

    z2ivozrfxs464010977936.jpg

    z2ivozrfxs464010977936.jpg

                                                                                   
                                                                                            嵌入式工程师频繁跳槽有什么利弊?
                                                                                   
                                                                           
                                                                   
                                                           
                                                   

                                                           
                                                                   
                                                                           
                                                                                   

    yzua1g52v4s64010978036.jpg

    yzua1g52v4s64010978036.jpg

                                                                                   
                                                                                            一名嵌入式工程师的涨薪经历
                                                                                   
                                                                           
                                                                   
                                                           
                                                   

    我是老温,一名热爱学习的嵌入式工程师
    关注我,一起变得更加优秀!
  • 回复

    使用道具

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表