指针初阶(指针类型转换的使用、指针数组)

一.指针基础

0.指针的大小

        指针指向的是一块地址,所以指针存储的是地址,例如在32位系统中。定义了一个int32_t类型的变量。使用int32_t *定义一个指针,使其指向该变量。

        设该变量存储在地址为00000000000000000000000000000001(32位地址)中,指针指向该变量,其实就是指针P存储了该变量的首地址

        既然指针P里面存储的是首地址(存储空间第一个字节的地址),在32位地址系统中,那么显然指针P里面要存32位二进制数,所以指针P的大小就是4个字节。同理在64位系统中,指针的大小为8个字节。

1.指针的步长

①.char、uint8_t 类型指针

若定义一个char或uint8_t类型的数组,用char*/uint8_t*定义的指针指向该数组


#include <stdio.h>
#include <stdint.h>

int main()
{
	uint8_t buf[8] = {1,2,3,4,5,6,7,8};
	uint8_t *p = buf;
	
	printf("p    :%p\n",p);        //打印P初始指向的地址
	printf("p+1:%p\n",p+1);        //P+1后的地址
	printf("p+2:%p\n",p+2);        //P+2后的地址
   
   return 0;
}

        根据打印出的值来看,uint8_t类型的指针每次加1,则其内部存储的地址值也加1

即跳过了一个字节)

     

②.int16_t类型的指针

        若定义一个uint16_t类型的数组,用uint16_t*定义的指针指向该数组

#include <stdio.h>
#include <stdint.h>

int main()
{
	uint16_t buf[8] = {1,2,3,4,5,6,7,8};
	uint16_t *p = buf;
	
	printf("p    :%p\n",p);
	printf("p+1:%p\n",p+1);
	printf("p+2:%p\n",p+2);
   
   return 0;
}

        

        根据打印出的值来看,uint16_t类型的指针每次加1,则其内部存储的地址值加2

即跳过了两个字节)

③.int32_t类型的指针

#include <stdio.h>
#include <stdint.h>

int main()
{
	uint32_t buf[8] = {1,2,3,4,5,6,7,8};
	uint32_t *p = buf;
	
	printf("p    :%p\n",p);
	printf("p+1:%p\n",p+1);
	printf("p+2:%p\n",p+2);
   
   return 0;
}

        根据打印出的值来看,uint32_t类型的指针每次加1,则其内部存储的地址值加4

即跳过了四个字节)

总结

        规律其实已经出来了,当执行指针P+1时,P内存储的地址不一定也只加1。地址具体的变化要看该指针是什么类型的,uint8_t(一个字节)则P+1时,其内部地址会跳过一个字节;uint16_t(两个字节)则P+1时,其内部地址会跳过两个字节。以此类推......

二.指针类型转换

        前面已经提到,指针内部存储的是地址。

        指针的类型有uint8_t,uint16_t,uint32_t,float等等,现在来定义一个uint8_t类型的数组,再定义uint8_t,uint16_t,uint32_t类型的指针。

#include <stdio.h>
#include <stdint.h>

int main()
{
	uint8_t buf[8] = {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
	uint8_t *u8_p = buf;
	uint16_t *u16_p = buf;
	uint32_t *u32_p = buf;
	
	printf("u8_p[0]    :%d\n",u8_p[0]);
	printf("u16_p[0]   :%d\n",u16_p[0]);
	printf("u32_p[0]   :%d\n",u32_p[0]);
   
   return 0;
}

        指针的类型其实起到了一个“翻译”的作用,不同的指针类型指向同一块地址。“翻译”出来的结果是不一样的。

1.翻译的步骤

        “翻译”的步骤大概是这样:

        假设有一块地址内的数据如下:

        用不同的指针去指向该地址的首地址       

        ①.uint8_t 

        

                已知 uint8_t 类型的指针,其步长为 1 个字节,所以 u8_p 每次  + 1 ,都是跳过 1 个字节。u8_p[0] 也就是该地址首地址的内容,当作 uint8_t 类型的数据来看,就是 1 。

        ②.uint16_t 

                 已知 uint16_t 类型的指针,其步长为 2 个字节,所以 u16_p 每次  + 1 ,都是跳过 2 个字节。u16_p[0] 也就是该地址中前 2 个字节的内容,一起当作 uint16_t 类型的数据来看,就是 257 。

        ③.uint32_t

        

                 已知 uint32_t 类型的指针,其步长为 4 个字节,所以 u32_p 每次  + 1 ,都是跳过 4 个字节。u32_p[0] 也就是该地址中前 4 个字节的内容,一起当作 uint32_t 类型的数据来看,就是 16843009 。

2.总结

        (1)

        其他 float 等类型的指针也是一样,要是这段地址,你想以float类型去翻译它,只需定义一个   float * float_p 类型的指针指向首地址,然后 float_p[0] 就是我们需要的数据。
   

     (2)

        如果给你了一个 uint8_t 类型的数组如下:

uint8_t buf[8] = {0xc3,0xf5,0x48,0x40,0x9a,0x99,0xb1,0x40};

        要把这个数组里面的数据变成 float 类型的数据,并存储起来,则需要这么做

float value1,value2;

value1 = ((float *)buf)[0];        //指针类型转换
value2 = ((float *)buf)[1];

        以上,就是将 uint8_t 类型的数组里面的值,转换成 float 类型的数据

三.指针数组

1.定义

    指针数组,其强调的是数组,这个数组里面存的是指针。

    假设在存储空间中,有一条字符串 "hello" ,它是这么存储的:

    要找到这条字符串,就得知道它的地址,也就是首字节(首个字符)的地址。

                而字符串指针数组,里面存的其实就是对应字符串的首地址

                            buf[0] = 0X00000000;
                            buf[1] = 0X00000006;

              

        

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值