强制转换的使用技巧(keil下的C51)

本文介绍了一系列强制类型转换的实用技巧,包括长整型到字符型、数组到长整型、数组到结构体、数组到浮点型等转换方法,并探讨了不同端模式下的转换区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//************** 强制类型转换实用技巧(地址类型转换)******************
//(A)将long型变量a(值:0x12345678)的第3个字节(值:0x56)赋给char型变量b。
// (B) 将数组的4个字节拼成1个long型变量
// (C) 将数组的4个字节转换成2个整数
// (D) 将数组的4个字节转换成1个float小数
// (E) 将float型变量各个字节取出
// (F) 将void型指针强制转换成任意类型指针
#include "STC15W4K.H"   // 注意宏定义语句后面无分号
unsigned long a;
unsigned char b;
int c,d;
unsigned char f1,f2; 
float f;
void *p;     // 定义指向类型不明确的数据的指针(指针就是数据存放的地址)
unsigned char array[]={0x11,0x22,0x33,0x44}; 
struct stru
{
    int a;
    int b; 
};
struct stru *pstru;       //定义指向结构体的指针变量
void main()
{
    // ********************  长 整 型 转 字 符 型    ******************
    a=0x12345678;    
    b=((unsigned char *)&a)[2];  //执行后b=0x56
    // 解释:长整型地址转字符型地址,(地址)[2],()是括号运算符,即先计算括号里面的内容,
    //       地址[2],表示取出当前地址加2地址中的内容。

    // ***********************  数 组 转 长 整 型    *********************
    a=*((unsigned long *)array);    //执行后a=0x11223344 (数组的名字就代表数组首地址)
    // 解释:数组型地址转长整型地址,*(地址),()是括号运算符,即先计算括号里面的内容,
    //       * 是取内容运算符。

    // ***********************  数 组 转 结 构 体    *********************
    pstru=(struct stru *)array; 
    //解释:数组型地址转结构体地址。pstru本来就是已定义好的专门存放地址的变量,即指针
    //     变量
    c=pstru->a;                 //执行后c=0x1122
    d=pstru->b;                 //执行后d=0x3344
    // 解释:使用"结构体变量地址->成员名"或"结构体变量名->成员名"的方法都可以访问结
    // 构体中的数据

    // ***********************  数 组 转 浮 点 型    *********************
    f=*((float *)array);           //执行后f=0x11223344,对应小数是1.279534e-028
    //解释:数组型地址转浮点型地址。

    // ***********************  数 组 转 字 符 型    *********************
    p=array;
    //解释:数组型地址转空类型地址。
    b=((unsigned char *)p)[0];           //执行后b=0x11

    // ***********************  浮 点 型 转 字 符 型  ********************
    f1=((unsigned char *)&f)[0];                 //执行后f1=0x11   
    //解释:浮点型地址转字符型地址。
    //或f1=*(((unsigned char *)&f)+0);            //执行后f1=0x11
    f2=((unsigned char *)&f)[1];                 //执行后f2=0x22   
    ((unsigned char *)&f)[0] ^= 0x80;           // 将4字节浮点数的符号位取反,注意^=数
    //写不要错误
    // *******************  void 型 指 针 转 任 意 类 型 指 针*************
    p= array;
    f1= ((unsigned char *)p)[0];      // 执行后f1=0x11,访问数组中第1个字节的内容
}
学到一个东西:一个变量比如 char a, 
对a取地址后 &a的类型为(unsigned char *), 
此时( (unsigned char *)a)[2]  
(举个例子而已,不要较真)  
地址[2],表示取出当前地址加2地址中的内容
unsigned char a _at_ 0x0001;     
unsigned char b[]={0,1,2,3,4,5,6,7,8,9};   
unsigned char c[][2]={{0,1},{2,3},{4,5}};  

void main()
{
    a=b[3];      // a=3
    b[2]=100;    // b= {0,1,100,3,4,5,6,7,8,9};
    *(b+2)=200;  // b= {0,1,200,3,4,5,6,7,8,9}; 
    b[-1]=4;     // a=4;
    ((unsigned char *)(((unsigned long *)b)+1))[0]=250;
                 // b={0,1,200,3,250,5,6,7,8,9};
    while(1);   
}

特别注意:

((unsigned char *)(((unsigned long *)b)+1))[0]=250;
                 // b={0,1,200,3,250,5,6,7,8,9};

地址是long+1 也就是第5个字节,然后选择第五为250

还有一个有关大小端的强制转换。。。。<大小端详细看这里>

上代码

keil 大端模式下

#include <stdio.h>
#include <reg52.h>

void main()
{
    unsigned char b, c;
    unsigned long a;

    while(1)
    {
        a = 0x12345678;
        b = (unsigned char)a; //0x78
        c = ((unsigned char *)&a)[0]; //0x12
    }
}

这里写图片描述


CB小端模式下:

#include <stdio.h>
#include <reg52.h>

void main()
{
    unsigned char b, c;
    unsigned long a;

    while(1)
    {
        a = 0x12345678;
        b = (unsigned char)a; //0x78
        c = ((unsigned char *)&a)[0]; //0x78
    }
}

这里写图片描述


总结一下:

当不涉及地址时,强制转化就是我们平时所理解的,直接取最低字节就行了。
当涉及地址时候,务必要考虑低地址存的是高字节(大端)还是低字节(小端)!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值