C语言中数组指针和指针数组的区别

上传人:pu****.1 文档编号:472468746 上传时间:2024-02-03 格式:DOCX 页数:4 大小:72.43KB
返回 下载 相关 举报
C语言中数组指针和指针数组的区别_第1页
第1页 / 共4页
C语言中数组指针和指针数组的区别_第2页
第2页 / 共4页
C语言中数组指针和指针数组的区别_第3页
第3页 / 共4页
C语言中数组指针和指针数组的区别_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《C语言中数组指针和指针数组的区别》由会员分享,可在线阅读,更多相关《C语言中数组指针和指针数组的区别(4页珍藏版)》请在金锄头文库上搜索。

1、数组指针和指针数组的区别数组指针(也称行指针) 定义 int (*p) n;()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。 也就是说执行p+1时,p要跨过n个整型数据的长度。如要将二维数组赋给一指针,应这样赋值:int a34;int (*p)4; 该语句是定义一个数组指针,指向含4个元素的一维数组。p=a;将该二维数组的首地址赋给p,也就是a0或&a00P+ + ;该语句执行过后,也就是p=p+1;p跨过行a0指向了行a1所以数组指针也称指向一维数组的指针,亦称行指针。指针数组定义 int *p n;优先级高,先与p结合成为一个数组,

2、再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里 执行p+1时,则p指向下一个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表示,只存在p0、p1、 p2.pn-1,而且它们分别是指针变量可以用来存放变量地址。但可以这样*p=a;这里*p表示指针数组第一个元 素的值,a的首地址的值。如要将二维数组赋给一指针数组:int *p3;int a34;p+ + ; 该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针for(i=0;i*出处:http:/ 都是一个指针,在32位系统下任何类型的指针永远是占4个字节。它是储存指针的数组的简称。数组指针:首先它

3、是一个指针,它指向一个数组。在32位系统下任何类型的指针永远是占4个字节,至于它指 向的数组占多少字节,不知道,具体要看数组大小。它是指向数组的指针的简称。下面到底哪个是数组指针,哪个是指针数组呢:A)int *pl10;B)int (*p2)10;每次上课问这个问题,总有弄不清楚的。这里需要明白一个符号之间的优先级问题。“的优先级比“*要高。pl先与“结合,构成一个数组的定义,数组名为pl, int *修饰的是数组的内容,即 数组的每个元素。那现在我们清楚,这是一个数组,其包含10个指向int类型数据的指针,即指针数组。至于 p2就更好理解了,在这里“()的优先级比“高,“*号和p2构成一个

4、指针的定义,指针变量名为p2, int修 饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚p2是一个指 针,它指向一个包含10个int类型数据的数组,即数组指针。我们可以借助下面的图加深理解:二、int (*)10 p2也许应该这么定义数组指针这里有个有意思的话题值得探讨一下:平时我们定义指针不都是在数据类型后面加上指针变量名么?这个指针 p2的定义怎么不是按照这个语法来定义的呢?也许我们应该这样来定义p2:int (*)10 p2;int (*)10是指针类型,p2是指针变量。这样看起来的确不错,不过就是样子有些别扭。其实数组指针的原型 确实就是这样子的

5、,只不过为了方便与好看把指针变量p2前移了而已。你私下完全可以这么理解这点。虽然编 译器不这么想。人人三、再论a和&a之间的区别既然这样,那问题就来了。前面我们讲过a和&a之间的区别,现在再来看看下面的代码:int ma in()char a 5=A,B,C,D;char (*p3)5 = &a;char (*p4)5 = a;return 0;上面对p3和p4的使用,哪个正确呢? p3+1的值会是什么? p4+1的值又会是什么?毫无疑问,p3和p4都是 数组指针,指向的是整个数组。&a是整个数组的首地址,a是数组首元素的首地址,其值相同但意义不同。在 C语言里,赋值符号“号两边的数据类型必须

6、是相同的,如果不同需要显示或隐式的类型转换。p3这个定义的 “=号两边的数据类型完全一致,而p4这个定义的“=号两边的数据类型就不一致了。左边的类型是指向整个数 组的指针,右边的数据类型是指向单个字符的指针。在Visual C+6.0上给出如下警告:warning C4047: initializing : char (*)5 differs in levels of indirection from char *。还好,这里虽然给出了警告,但由于&a和a的值一样,而变量作为右值时编译器只是取变量的值,所以运行并 没有什么问题。不过我仍然警告你别这么用。既然现在清楚了 p3和p4都是指向整个数

7、组的,那p3+1和p4+1的值就很好理解了。但是如果修改一下代码,把数组大小改小点,会有什么问题? p3+1和p4+1的值又是多少呢?int ma in()char a 5=A,B,C,D;char (*p3)3 = &a;char (*p4)3 = a;return 0;甚至还可以把代码再修改,把数组大小改大点:int ma in()char a 5=A,B,C,D;char (*p3)10 = &a;char (*p4)io = a;return 0;这个时候又会有什么样的问题? p3+1和p4+1的值又是多少?上述几个问题,希望读者能仔细考虑考虑,并且上机测试看看结果。测试结果:.cha

8、r (*p2)5=a;必须使用强制转换,如:char (*p2)5=(char (*)5)a;(2) 把数组大小改变,都会编译不通过,提示:error C2440: i nitializi ng : cannot con vert from char (*)5 to char (*)3error C2440: i nitializi ng : cannot con vert from char (*)5 to char (*)l0(3) 把以上程序测试代码如下:int ma in()char a5=a,b,c,d;char (*p1)5= &a;char (*p2)5=(char (*)5)a

9、;prin tf(a=%dn,a);prin tf(a=%c n,a0);pri ntf(pl=%cn,*pl);pri ntf(p2=%cn,*p2);pri ntf(p1+1=%cn ,*(p1+1);pri ntf(p2+l=%cn ,*(p2+l);return 0;输出:a=1638208a=ap1=ap2=ap1+1=?p2+1=?Press any key to con ti nue结论:根据指针类型及所指对象,表示指针大小,每次加1,表示增加指针类型大小的字节-后面还会有解释说明.四、地址的强制转换先看下面这个例子:struct Testint Num;char *pcName

10、;short sDate;char cha2;short sBa4;*p;假设p的值为0x100000。如下表表达式的值分别为多少?p + 0x1 = 0x?(un sig ned Ion g)p + 0x1 = 0x?(un sig ned in t*)p + 0x1 = 0x?我相信会有很多人一开始没看明白这个问题是什么意思。其实我们再仔细看看,这个知识点似曾相识。一个指 针变量与一个整数相加减,到底该怎么解析呢?还记得前面我们的表达式“a+1与“&a+l之间的区别吗?其实这里也一样。指针变量与一个整数相加减并不是 用指针变量里的地址直接加减这个整数。这个整数的单位不是byte而是元素的个

11、数。所以:p + 0x1的值为 0x100000+sizof(Test)*0x1。至于此结构体的大小为20byte,前面的章节已经详细讲解过。所以p +0x1的 值为:0x100014。(unsigned long)p + 0x1的值呢?这里涉及到强制转换,将指针变量p保存的值强制转换成无符号的长整型数。 任何数值一旦被强制转换,其类型就改变了。所以这个表达式其实就是一个无符号的长整型数加上另一个整数。 所以其值为:0x100001。(unsigned int*)p + 0x1的值呢?这里的p被强制转换成一个指向无符号整型的指针。所以其值为: 0x100000+sizof(unsigned i

12、nt) *0x1,等于 0x100004。上面这个问题似乎还没啥技术含量,下面就来个有技术含量的:在x86系统下,其值为多少?in tmai n()int a4=1,2,3,4;int *ptr1=(int *)(&a+1);指向a数组后面的内存单元,&a+1表示向后移16个存储单元int *ptr2=(int *)(int)a+1);表示a的存储单元的地址增加一个字节printf(%x,%x,pt门-1,*ptr2);/ptr1-1其实指向的是a数组的最后一个单元,*ptr1则表示a数组的地址后 移一个字节之后的4个连续存储单元所存储的值return 0;这是我讲课时一个学生问我的题,他在网

13、上看到的,据说难倒了n个人。我看题之后告诉他,这些人肯定不懂 汇编,一个懂汇编的人,这种题实在是小case。下面就来分析分析这个问题:根据上面的讲解,&a+1与a+1的区别已经清楚。ptr1:将&a+1的值强制转换成int*类型,赋值给int*类型的变量ptr,ptr1肯定指到数组a的下一个int类型 数据了。ptr1-1被解析成*(ptr1-1),即ptr1往后退4个byte。所以其值为0x4。ptr2:按照上面的讲解,(int)a+1的值是元素a0的第二个字节的地址。然后把这个地址强制转换成int*类型的 值赋给ptr2,也就是说*ptr2的值应该为元素a0的第二个字节开始的连续4个byte的内容。好,问题就来了,这连续4个byte里到底存了什么东西呢?也就是说元素a0,a1 里面的值到底怎么存储的。 这就涉及到系统的大小端模式了,如果懂汇编的话,这根本就不是问题。既然不知道当前系统是什么模式,那 就得想办法测试。大小端模式与测试的方法在第一章讲解union

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号