C语言指针运算

C语言指针运算:



C语言指针运算:

指针运算的关键是:以指针所指对象的数据类型为最小运算单位。
例如:整型占四个字节,如果一个指向整型的指针自增1,那么该指针的新的指向是当前指向后移动四个字节。这就是指针的运算,很简单吧,其实运算的关键是数据类型。OK,然后再说明两个注意事项:

(1)数组指针是不能自增的:

int a[3]={1,2,3};
a++;//这一句是不对的,数组指针不能自增

(2)(void*)的妙用:

(void*)常常用来打破指针运算必须以数据类型为最小单位的这一定律:

int a={1,2,3};
unsigned char *p=(void*)a;

int是四个字节,unsigned char 是1个字节,经过以上两句,p指向了a的首地址,但是p自增1,并不会移动四个字节,而是移动1个字节。也就是说,虽然p指向了int数据类型的地址,但是p指针的运算并不遵从int型指针每次移动四个字节,p本质上还是unsigned char指针。

到这里,大家应该就明白(void*)的原理了吧,其实就是让不同类型的指针指向同一个地址,然后指针的运算性质也发生了改变。这具体有什么用呢?举个应用的例子吧:

比如我们通过STM32往W25Q64_flash中存储数据,用的SPI协议每次传输一个字节,可是小数有多个字节啊,如何传输小数呢?比如说传输double类型的数据,可以这样做:

double buffer = 123.456;
unsigned char * p=(void*)&buffer;//然单字节运算的指针p指向buffer的地址

//sendByte函数:给定一个字节数据的指针,每次传输该指针指向的字节
while(sizeof(&buffer)--)
{
	sendByte(p)//指针p每次移动一个字节,一共移动8个字节(因为sizeof(&buffer)等于8)
	p++;
}

这样就可以成功通过SPI协议每次向flash存储一个小数,当然实际的程序还要写相应存储数据的命令,并且可能是传整个数组的数据,要比这个程序复杂的多,这里只是把存储小数的核心部分展示出来。

参考野火的历程,完整的函数是这样的:

/**
  * @brief  对FLASH按页写入数据,调用本函数写入数据前需要先擦除扇区,一次最多可以写入256个字节
  * @param	pBuffer,要写入数据的指针
  * @param  WriteAddr,写入地址
  * @param  NumByteToWrite,写入数据长度,必须小于等于SPI_FLASH_PerWritePageSize
  * @retval 无
  */
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
  /* 发送FLASH写使能命令 */
  SPI_FLASH_WriteEnable();

  /* 选择FLASH: CS低电平 */
  SPI_FLASH_CS_LOW();
  /* 写页写指令*/
  SPI_FLASH_SendByte(W25X_PageProgram);
  /*发送写地址的高位*/
  SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
  /*发送写地址的中位*/
  SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
  /*发送写地址的低位*/
  SPI_FLASH_SendByte(WriteAddr & 0xFF);

  if(NumByteToWrite > SPI_FLASH_PerWritePageSize)
  {
     NumByteToWrite = SPI_FLASH_PerWritePageSize;
     FLASH_ERROR("SPI_FLASH_PageWrite too large!"); 
  }

  /* 写入数据*/
  while (NumByteToWrite--)
  {
    /* 发送当前要写入的字节数据 */
    SPI_FLASH_SendByte(*pBuffer);
    /* 指向下一字节数据 */
    pBuffer++;
  }

  /* 停止信号 FLASH: CS 高电平 */
  SPI_FLASH_CS_HIGH();

  /* 等待写入完毕*/
  SPI_FLASH_WaitForWriteEnd();
}

使用此函数写入小数,给函数实参的时候,就要用(void*)来修饰传入的指针.

以上就是关于指针的一些个人见解,哎,我很努力地想把自己的想法表达清楚,但是奈何表达能力有限,哎,不说了。大家再见


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

GuiStar_李什么恩

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值