目录
指针类型强转的本质是,原指针指向的内存数据类型会被转换为所转换指针的类型,其范围是该指针类型的大小,而不是原指针指向的整块内存。
指针类型的大小与指向对象类型无关--->在32位系统下占4个字节,在64位系统下占8位系统.
而指向对象类型决定了指针向前/向后走“多大的距离”(字节)
1、大小端
在此之前还需要了解一下-->什么是大小端?
Windows系统的存储方式为小端存储模式
小端存储模式:数据中的低字节,存储在低地址中;数据中的高字节,存储在高地址中.
大端存储模式:数据中的高字节,存储在低地址中;数据中的低字节,存储在高地址中.
2、强转类型转换
我们还需要了解什么是强制类型转换?
C语言中的强制转换也称为显式转换,是一种把一种数据类型转换为另一种数据类型的方式。这种转换的目的是在需要某个特定类型时,将一个表达式的值强制转换成该类型。
2.1 常规强制转换
常规强制转换的语法方式如下:
(type_name) expression
其中,type_name 表示要转换到的数据类型,expression 是要进行转换的表达式。强制转换的一个例子:
int a = 10;
float b = 2.5;
// 把 a 转换成 float 类型
float c = (float)a;
// 把 b 转换成 int 类型
int d = (int)b;
printf("c:%.1f\n",c);
printf("d:%d\n", d);
结果:
需要注意的是,强制转换可能会导致数据精度的丢失或溢出,因此需要谨慎使用。
2.2 指针类型强制转换
指针类型强制转换的语法方式如下:
(type_name *) expression;
其中,type_name 表示指针的目标数据类型,expression 是要被转换的指针变量(地址)
要注意的是,需要在强制转换之前检查指针的合法性,否则可能会出现未定义的行为。因此,在进行指针类型强制转换时,建议进行类型检查、指针合法性检查等操作。下面是一个指针类型强制转换的例子:
int a = 0x12345678;
int* p = &a;
printf("%#x\n",*p);
// 把指向 int 类型的指针强制转换为指向 char 类型的指针
char* q = (char*)p;
printf("%#x\n", *q);
结果:
3、在M4中的应用
往AT24C02中存储结构体,并且读出
typedef struct book
{
u8 name[15];
u8 writer[15];
u8 number[15];
u32 hot;
u32 sc;
float price;
}BK;
int main(void)
{
u8 start_val;
u8 set_flag = 0;
BK send_book = {"西游记","吴承恩","W201955",0,30,55.5};
BK rec_book;
NVIC_SetPriorityGrouping(5); //设置优先级分组
Usart1_init(115200);//串口初始化
at24c02_init();
//把结构体类型的指针强制转换为指向 char 类型的指针
//往AT24C02中储存结构体数据
at24c02_write_bytes(0,sizeof(send_book),(u8 *)&send_book);
//从AT24C02中读取数据
at24c02_read_bytes(0,sizeof(rec_book),(u8 *)&rec_book);
while(1)
{
//打印数据
printf("name:%s writer:%s number:%s hot:%d sc:%d price:%.1f\r\n",rec_book.name,rec_book.writer,rec_book.number,rec_book.hot,rec_book.sc,rec_book.price);
timer11_delay_ms(200);
}
}
/************************************************
*函数名 :at24c02_write_bytes
*函数功能 :对at20c02的存储空间开始连续写 可跨页
*函数参数 :u8 inner_addr 起始地址
u16 num_byte 要读的字节数
u8 *str 要写的数据的首地址
*函数返回值 :u8
*函数描述 :
*************************************************/
void at24c02_write_bytes(u8 inner_addr,u16 num_byte,u8 *str)
{
u8 less_byte;
while(1)
{
//计算本页还剩多少空间可写 less_byte = 8 - inner_addr % 8
less_byte = 8 - inner_addr % 8;
//如果要写的内容不需要跨页 less_byte >= num_byte
if(less_byte >= num_byte)
{
//调用发送页写函数(inner_addr,num_byte,str)
at24c02_write_page(inner_addr,num_byte,str);
break;
}
//如果要写的内容需要跨页 less_byte < num_byte
else
{
//调用发送页写函数把本页剩下的空间写完(inner_addr,less_byte,str)
at24c02_write_page(inner_addr,less_byte,str);
//计算出剩下多少个字节:num_byte = num_byte - less_byte
num_byte = num_byte - less_byte;
//下一页的首地址: inner_addr = inner_addr + less_byte
inner_addr = inner_addr + less_byte;
//剩余要写的内容数据的地址:str = str + less_byte
str = str + less_byte;
}
}
}