指针类型强转的本质

  

目录

1、大小端

2、强转类型转换

2.1 常规强制转换

2.2 指针类型强制转换

3、在M4中的应用


         指针类型强转的本质是,原指针指向的内存数据类型会被转换为所转换指针的类型,其范围是该指针类型的大小,而不是原指针指向的整块内存。

指针类型的大小指向对象类型无关--->在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;
		}
		
	}
	
	
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值