内存对齐之强制类型转换
一、左值和右值
定义一个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();
}