个人理解—数据结构 1 指针

        接触计算机这一块,基本都要去学习一门科目—数据结构与算法,毫无疑问,这是两个方面的知识一为数据结构,二为算法。

        那么为什么要把他俩放一块,个人看来是因为,数据结构与算法是相辅相成的,一定程度上数据结构决定了一个算法的优劣。甚至,在不同平台,同一的算法可能就从优势转为了劣势。

        在向下说明之前,先插入一个相关而又不太相关的话题,那就是指针与数据之间的关系。在我深入了解C语言之前,对指针的概念是比较模糊的,初认为指针是类似int,double一类的东西,但在之后,我才逐渐明白,指针可以说是一种“方法”。

        先来确定一点,去定义一个指针的方法是“int *p=NULL”,在此,我们应该理解为定义了一个int类型的指针,其变量名为p,指向地址为NULL。也因为如此定义也可写作“int* p=NULL”,感觉这样与前面的解释更贴切(“int * p=NULL”也可以,无所谓都行看个人习惯),但初始化时建议初始化为NULL或者一个确切的地址,否则为野指针。

       现在我们知道,在“int *p=NULL”中,p是变量,int*是指int类型的指针,那么为什么要加一个int呢?答案是读取方式与读取大小。这就与数据存储方式相关了,我们可以将char,short,int分为一个"字家族"类型(自己取地名字),float,double分为浮点数类型。由于浮点数存储方式与“字家族”存储方式不同,所以在解析方面也就不同。那么我们回到”字家族中“。char是1个字节,short占2个字节,int占4个字节。其中,不难看出其大小排列关系,之所以要将这仨分为一类,是因为char可以通过指针方式对short和int进行间接访问。

        我们定义如下(编译器环境为:WIN10,CPU:7-10h):

int hext_i[3]={0x00112233,0x44556677,0x8899aabb};
unsigned char * p_i=NULL;
p_i=&hext_i;

short hext_s[3]={0x0011,0x2233,0x4455};
unsigned char * p_s=NULL;
p_s=&hext_s;

for(int i=0;i<12;i++)
    {
         printf("p[%d]_i=%x\n",i,*(p_i+i));
    }

for(int i=0;i<6;i++)
    {
        printf("p[%d]_s=%x\n",i,*(p_s+i));
    }

        输出结果为:

p[0]_i=33
p[1]_i=22
p[2]_i=11
p[3]_i=0
p[4]_i=77
p[5]_i=66
p[6]_i=55
p[7]_i=44
p[8]_i=bb
p[9]_i=aa
p[10]_i=99
p[11]_i=88

p[0]_s=11
p[1]_s=0
p[2]_s=33
p[3]_s=22
p[4]_s=55
p[5]_s=44

        由于所使用CPU为小端(低位放低地址),所以当我们存储数据为0X00112233时,33为低位,所以放在低地址,被指针优先访问到,而33占有1字节空间(),char*代表解析1字节空间,所以33这个数据被取了出来即p[0]_i=33。(打印方式换为%d,p[0]_i=51,16进制33为10进制51,数据无误)

        但是,若使用char*类型指针,去访问浮点数,那么访问的结果将是不正确的。

float doub=12;
unsigned char * p=NULL;
p=&doub;
printf("doub=%x\n",*p);

        结果为:

doub=0

        原因是,对于浮点数而言存储方式是符号位+指数位+有效数字位,使用char*类型进行间接访问是无法对数据进行全面读取的,只能读取到其中的一位的一字节数据。那么能用char*对浮点类型进行逐一读取再进行拼接进行转义吗?是可以的,但编译器不是以及干了这活了吗?

float doub=12;
float * p1=NULL;
p1=&doub;
printf("doub=%f\n",*p1);

结果为:

doub=12.000000

        先写道这里吧,再写一个注意事项,之所以使用unsigned char *指针类型进行定义,是因为若使用char * 指针,在printf解析过程将会按照有符号类型进行数据解析,对于0x88来说转译为二进制就是1000 1000,会将高位的1作为符号位,按照规则将符号位做高位部分的填充位,则最终数据为0xffffff88。(0x11的二进制为0001 0001,高位为0)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值