强化C语言的指针类型学习


 由于工作需要,要把uboot中的pci扫描代码移植到自己的项目里来,本来都做好了,但是需要稍微修改下uboot里的几个专门为我们的项目使用的文件,

也就是uboot导出的函数,供项目使用,但是被告知,目前uboot已经是发布的版本,不能再改变了。

怎么办呢?其实pci系统在uboot起来的时候已经初始化好了,在代码中需要的是其中一些变量的地址,有了这些地址,转换成合适的指针,那么就可以进行操作了,

这里主要研究类型问题。

举例,由易到难:

int a = 5;
已知a的地址为 0xffff0000;
也就是 &a == 0xffff0000 成立
#define ADDR_OF_A 0xffff0000
以供使用

那么我们想使用a这个变量,也就是能读写a,但是已知的只有ADDR_OF_A

大家都会想到这么做

int *p = (int *)ADDR_OF_A


然后,对p的引用就相当于操作a,比如*p = 6; 则a的值改变为6.

有没有想过为什么能这么做呢,弄明白这里对理解指针大有裨益。

a的类型是一个整型,那么需要一个整型指针来表示其地址。

以此类推,a是什么类型,就需要一个什么类型的指针指向其地址!

下面再举个例子

int b = 1;
int *ptr = &b;

#define ADDR_OF_PTR 0xffff0000
假如现在知道ptr的地址(&ptr),该怎么进行表示它呢?

ptr是一个指针,很明显,我们需要的是一个指向指针的指针

int **temp;
temp = (int **)ADDR_OF_PTR;


这样,在进行*temp的时候就相当于对ptr 操作。

比如

int c = 3;
*temp = &c;

这样,就改变了ptr,相当于ptr = &c;

好了,上述都是基本类型。下面分析一个本项目中遇到的类型

struct fsl_pci_info *pci_info_list[5] = { NULL, NULL, NULL, NULL, NULL} ;


这个是uboot代码中定义的,现在知道了它的地址(&pci_info_list),

#define PCI_INFO_LIST_ARRAY  0x7fff0b6c

要对其进行引用,需要仔细分析下类型。

首先,pci_info_list是一个数组,该数组包含5个元素,类型为结构体指针struct fsl_pci_info *

好,根据上面的分析,我们需要一个指针,指针的类型是指向一个包含5个元素的数组,很显然是一个指向数组的指针。

应当做如下定义

struct fsl_pci_info *(*ptr)[5];
ptr = (struct fsl_pci_info * (*)[5])PCI_INFO_LIST_ARRAY;

怎么样,感到复杂吗?

其实只要分析一下,也并不是那么复杂。分析类型

struct fsl_pci_info * (*)[5];

根据运算符的优先级,()内最高,所以是一个指针,后面跟[5],所以说明了指针指向了一个数组,前面的类型是数组元素的类型!

下面是使用部分,真正需要的是要把这个数组中的元素取出来

struct fsl_pci_info *pci_info;
pci_info = (*ptr)[i];


ptr 类型是指向数组的指针,那么*ptr的类型就是数组类型啦!

本文主要讲述C语言中指针的类型。C语言中数据类型的唯一作用就是告诉编译器:变量在内存中是怎么存储的,在使用的时候要按照类型大小来。

比如char ch;

字符型,那么在取数据的时候,不如int inter = ch; 只取&ch 地址开始的一个字节。

如果是int a; int b = a;

则需要取&a开始的 sizeof(a) 也就是4个字节。

还有,一个指针的类型决定了指针在做增量的时候的步进长度。

比如

char a;
char *ptr = &a;
ptr++;

ptr++使ptr指向了下一个字节。

如果是

int a;
int *ptr =&a;
ptr++;


则ptr指向了下一个Int型数据,也就是步进长度为sizeof(a).

如果是个结构体指针,同理,变为sizeof(struct XXX).

其他类型以此类推。

 



 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值