C指针内存对齐之强制类型转换

一、左值和右值

定义一个uint8_t temp[10] 的数组并赋初值.

uint8_t temp[10] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa};

1.1 概念

左值 = 右值

1.2 释义

通俗来说
左值就表示 “=” 左边的值,右值就表示 “=” 右边的值

具体来说
左值:表示一个变量的地址内存空间,强调的是内存地址
右值:表示一个变量的地址内存空间所存储的数据,强调的是数据

1.3 举例

以temp举例来说

①左值
当temp[0]作左值时,代表的意义的是temp[0]的内存地址空间
给temp[0]赋值0xff,就相当于在temp[0]的内存地址空间里,写入数据0xff.

temp[0] = 0xff;

②右值
当temp[0]作右值时,代表的意义是 取出 temp[0]的内存地址空间里保存的数据
以十六进制打印temp[0]的值,相当于取出temp[0]保存的数据以十六进制格式打印输出。

printf("temp[0]=0x%02x\r\n",temp[0]);
//输出结果为:temp[0]=0xff

二、指针的左值和右值

指针使用的三部曲,定义、绑定(注册)、解引用(调用)

指针的使用分为两个部分:左值调用右值调用

左值表示当前指针指向的地址内存空间
右值表示当前指针指向的地址内存空间存放的数据内容
将指针名看做一个变量,而这个变量存储的数据就表示当前指针指向的内存地址

2.1 定义指针和数组

定义一个uint8_t * buff = NULL的指针.
定义一个uint8_t temp[10] 的数组并赋初值.

uint8_t * buff   = NULL;
uint8_t temp[10] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa};

2.2 绑定(注册)指针

将buff与temp绑定在一起,在指针的使用过程中,应先绑定有效地址,否则就为 野指针
要么在定义时、要么在定义后有且仅有这两个选项

①定义时

uint8_t temp[10] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa};
uint8_t * buff   = temp;

②定义后

uint8_t temp[10] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa};
uint8_t * buff   = NULL;
buff = temp;

就相当于buff指针指向的地址与temp数组的首地址都指向同一个地址

2.3 解引用(使用)

解引用(取出使用)必须用指针名符号“ * ” 合起来,这个操作称为解引用(取出使用)

对于*buff的解释就是 取出变量buff内存地址存储的数据内容

① 作为右值—取出数据
定义一个变量tempBuf,取出指针buff指向temp数组的首元素并赋值

//将temp[0]的值赋值给tempBuf
uint8_t tempBuf = 0;
tempBuf = *buff;

② 作为左值—内存空间
定义一个变量tempBuf,并赋值为0xff,将指针buff指向地址内存空间存储的数据内容修改为0xff

uint8_t tempBuf = 0xff;
*buff = tempBuf;

2.4 指针的偏移访问

对指针名这个变量进行数值的加减就实现了指针的偏移访问

uint8_t  buf[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
uint8_t * databuff = NULL;
databuff = buf;

左值偏移
指针名+=n运算之后,当前指针就指向偏移运算之后的地址,可理解为,对指针名这个变量赋值

databuff++; //偏移1个地址之后当前databuff指向buf[1]
databuff+=2;//偏移2个地址之后当前databuff指向buf[3](加上第一次)

右值偏移
*(指针名+n) 运算之后,取出的值就是当前指针指向偏移运算之后内存地址存储的数据,而当前指针指向的地址不变,
可理解为,将指针当做数组来使用 *(指针名+n) n就相当于数组下标

*(databuff++); //偏移1个地址之后当前databuff指向buf[1]
*(databuff+2);//偏移2个地址之后当前databuff指向buf[3](加上第一次)

三、指针强制类型转换

定义uint8_t 单字节类型的数组data[10]

uint8_t data[10] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa}

强制类型转换 小端模式

 uint8_t *buff = data;//*buff = 0x11;
uint16_t *buff = (uint16_t)data;//*buff = 0x2211;
uint32_t *buff = (uint32_t)data;//*buff = 0x44332211;
uint64_t *buff = (uint64_t)data;//*buff = 0x8877665544332211;

Flash的写入程序

void OPENBL_FLASH_Write(uint32_t Address, uint8_t *Data, uint32_t DataLength)
{
  uint32_t index  = 0U;
  uint32_t length = DataLength;
  uint64_t read_data;
  if (length & 7U)
  {
    length = (length & 0xFFFFFFF8U) + 8U;
  }
  /* Unlock the flash memory for write operation */
  OPENBL_FLASH_Unlock();
  for (index = 0U; index < length; (index += 8U))
  {	
        OPENBL_FLASH_ProgramDoubleWord((Address + index), (uint64_t)(*((uint64_t *)((uint32_t)Data + index))));
        //解引用取出,uint64_t * 类型指针指向的Data地址空间内存储的数据,并强制转换为uint64_t
        read_data = *(uint64_t *)(Address + index);
        /* check data */
        if (read_data != (uint64_t)(*((uint64_t *)((uint32_t)Data + index)))) 
        {
     
        }                
  }
  /* Lock the Flash to disable the flash control register access */
  OPENBL_FLASH_Lock();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值