再谈指针

本文详细解析指针的两个关键属性,并通过代码实例展示如何运用指针访问数组元素,同时解释了指针作为数组引用的概念及二维数组参数的正确定义方式。文章进一步探讨了指针在二维数组操作中的作用,包括指针加法的含义及其可能引发的边界问题,并提供了验证代码以加深理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面大致对指针有一定的了解,最近在往后学习 的过程中对指针这玩意儿又有了新的理解。


我认为:指针有2个属性

一:指针的值(value)

二:指针管辖的宽度(width)


# include <stdio.h>
int main (void)
{
	int arr[5]={1,2,3,4,5};
	
	int *p1=arr;
    int (*p2)[5]=&arr;
	
	return 0;
}


对指针p1来说,他的值是等于arr的(同样也等于&arr[0]),也就是p1指向数组的第一个元素。这里要强调一下的是,有些人把

数组名这个arr这个指针理解为指向数组的指针,这是错误的,它应该是指向数组的第一个元素的指针。




 对p1的宽度来说,它管理arr[0]所占的字节(图中画的是4个字节),也就是说:p1的宽度是sizeof (arr[0])


对于p2,我们从p2的类型可以看出,他是一个指向数组的指针,确切地说是指向有5个int类型元素的数组的指针。

p2的值是&arr ,有经验的coder会在脑子里第一时间想到:&arr  的 值 和   arr 是相等的。的确,因为指针的值就是

它指向的内存块的第一个字节的地址。

对于p2宽度呢?


可以看出:p2是指向数组的指针,它比p1“管得宽”一些。所以,&arr才是指向数组的指针。


这里扩展一下:p2+1  指向什么呢?

好吧,这里,我们的确是访问越界了,不过,还是有必要分析一下。

我们知道,在一个数组中,一个元素的指针+1,代表指向此元素下一个元素的地址,那么在这里,从二位数组的角度

来看,p2+1就是指向与这个数组在内存位置上相邻的下一个同样大小和类型数组的指针。也就是这样(即便这个数组不存在)

验证代码:

# include <stdio.h>
int main (void)
{
	int arr[5]={1,2,3,4,5};
	
    int (*p2)[5]=&arr;
	
	printf("%d\n",  *((int*)(p2+1)-1)  ); 
	
	
	return 0;
} 


通过上面的理解,我们又可以轻松理解一个我们知道该这样做但却不知道为什么这样做的例子

我们知道:要定义一个指针,就必须要指明指针的类型,也就是这个指针将指向什么类型的元素。

比如:

     int* p ;     //p是指向int元素的指针

     float * p   //p指向float型

     void (*p) (int ,int );    //p指向一个函数,该函数无返回值,有2个int型参数

   

好,我们写一个处理二位数组的函数,就要在函数的参数之一定义为一个指向二维数组的“第一个元素”的指针,

我们还了解,第一个元素,他是一个数组。

所以应该这样: void test  (int a[ ] [x]  ,....)

或者这样            void test  (int (*a)[x]  ,....)


我想说的 “知道该这样做却不知道为什么这样做”就是我们常常挂在嘴边的:形参的一维可以省略,但二维不能省略。

也就是上面的x不能省略,而且要是一个确定的常量。

为什么呢?到这里应该知道了吧。

上面2中定义方法本质上是第2种,也就是把参数定义为一个指向数组的指针。

既然是定义指针,当然要指明他的类型吶。上面数a是指向什么样的数组的啊?答:指向有x个int型元素的数组的。

可见,x是不可以省略的。

over







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值