完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
声明:本文只是楼主的一家之言,只具有一点点的参考价值。如果你发现有什么不对的地方,欢迎指出,或者你可以当楼主在放一种气体。
本文将采用举例子的修辞手法,来通俗易懂的讲解指针、数组和地址之间的关系。 一、基本概念 数组:是一种数据结构,是一组相同数据元素的集合。 指针:带有类型的一个地址。 地址:芯片要存储数据,数据总要有个存储地址吧。 二、数组 首先定义一个数组int array[10];众所周知,这是一个int类型的数组,该数组有10个元素,每个元素都是一个int类型的变量。array是这个数组的数组名,但同时array也是该数组首元素的地址,所以有以下等式成立array=&array[0]。既然array是数组首元素的地址,那么一但数组定义好后,array就是一个定值。所以也就不存在array=array+1;或array++;的情况。 再看例子,int num; num=&(array[5]) - &(array[4]); 此时num=1。 原因分析:从数值上来看,array[5]的地址和array[4]的地址之间应该相差了4个字节,因为array数组是一个int类型的数组,每个元素应当占据4个字节的空间。此处就体现出来数组元素地址(其实就是指针)与真正的内存地址之间的差别。数组元素地址是有类型的,而内存地址是没有类型的。有了类型之后,两者相减,就不是数值上相减,而是计算了两者的偏移量。因为他们是int类型的,每个int类型占据4个字节,所以相当于是偏移量1个单位。 同理,um=(char*)(&(array[5])) - (char*)(&(array[4])); 此时num=4。 理由同上,不赘述。 另外sizeof(array) = 40。sizeof是在计算array数组所占据的空间,10×4=40个字节。 三、指针 带有类型的一个地址。指针的类型有其指向变量的类型决定。但void*类型的指针,是无类型的,也可以理解为它可以指向任何类型。 看例子,int *p; int array[10]; p=array; 则以下等式成立,p = &(array[0]) = &(p[0]); *p = array[0] =p[0]; 解析:根据前面介绍的,array是数组首元素的地址,那么p=array以后,p也就指向了array数组的首元素。p是一 个指针,为什么可以有p[0]这种表达形式,请自行查阅下标运算符[]的用法。 以下等式也成立,p+1 = &array[1]; 因为p是有类型的,所以p加1,是加p所指向的类型的长度,在此处是 int,所以在数值上是加4,而不是加1。 同时p也是一个变量,只不过它是一个指针变量。所以可以给p赋各种值,如p=&(array[5]);那么此时p+1就 等于&(array[6])。 关于sizeof的计算。sizeof(array)=40; 因为array数组占据40个自己;而sizeof(p)=4;因为p代表的仅仅是一个 地址,在32位机上,一个地址占4个字节。 再看例子: char array[10]; char *p; p=array; 则以下等式成立:原因如上。 (p+1) = &array[1] (int*p)+1 = &array[4]; sizeof(array)=10; sizeof(p)=4; 补充说明:当一个数组被当作参数传入函数时,其实传入的只是数组首元素的地址,并没有把整个数组都传入。 int func(int array[10]) {//因为并没有把整个数组传递进来,只是传了数组的首元素地址进来 //所以以下等式成立 sizeof(array) = 4; } 四、地址 芯片内部要存储数据,数据总要有个存储地址吧,这里所指的地址,就是这个地址啊。所以存储在芯片上的任何数据都有一个地址。那么如果我们知道某些变量存储的空间,是否能不通过变量名,而是直接通过地址就能访问到它呢。理论上是可行的。 如果想把地址0X0000500地址中的内容读取出来,其实只要 char *p; p=0X0000500; 此时p已经定位到地址0X0000500,你就可以为所欲为了。 但实际上,一般的编译器都是不允许直接给一个指针赋具体值的。只能通过间接的方式。 比如char array[10]; char *p = array; So sad! 既然芯片上所有的数据都有地址,所以一个函数也是有地址的。 根据前面所说的,把一个数组传入函数,只是把数组的首地址传进去,实际上传入了一个32位的地址而已。 同理,也可以把一个函数的地址当作参数传入进去,无非也就是传入一个32位的地址而已。 例子: int fun_add(int x,int y) { return x+y; } int precess(int x,int y,int (*fun)()) { return ((*fun)(x,y)); } int main(void) { process(5,6,fun_add); } 评分
|
||
相关推荐
8 个讨论
|
||
学习,这是C语言中最难的。
|
|
|
|
|
|
cloudboy 发表于 2016-7-29 01:00 学习学习 |
|
|
|
|
|
只有小组成员才能发言,加入小组>>
3096 浏览 3 评论
1549 浏览 3 评论
4702 浏览 1 评论
2040 浏览 1 评论
3293 浏览 2 评论
534浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 05:17 , Processed in 0.843939 second(s), Total 63, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号