详解 万恶之源——指针(2)

本文详细解释了数组名的概念,指针如何访问数组,二级指针和指针数组的作用,以及数组和指针在传递参数时的等效性。通过实例演示了这些概念的实际运用。
摘要由CSDN通过智能技术生成

上一篇我们讲解了指针是什么和指针变量相关内容,这篇我们讲解指针和数组的故事。

一.数组名的理解

明白指针与数组之间的关系,我们先要明白数组名的到底是什么。

int arr[1,2,3,4,5];
arr
&arr[0]

arr表示的其实就是arr数组的首个元素的地址,说白了,数组名就是数组首个元素的地址。上述两个式子表示的都是一个东西。

但是数组名表示数组首个元素的地址这个是有两个例外的:

sizeof(arr);
&arr

sizeof(arr)中的数组名arr表示的是整个数组,我们可以通过输出该值来验证,如果输出该值的话是20(int  4个字节,数组有5个值)所以说我们求一个未知数组的长度是可以用sizeof(arr) / sizeof(arr[0])  。

&arr取的也是整个数组,我们可以通过下发的代码来验证。

int main()
{
	int arr[5] = { 1,2,3,4,5 };
	printf("%p\n", &arr);
	printf("%p\n", &arr + 1);
	return 0;
}
//输出的结果
000000DF324FF618
000000DF324FF62C

我们在上一篇讲到指针与整数加减,加减的数是根据int*的类型来到,因此加1应该是加上4个字节,但是上述的结果并不是加上4个字节。通过计算,我们发现,它是直接将数组越过。

另外,数组的传参本质上也是讲数组的首元素地址传过去。所以传参的部分既可以写成数组的形式,也可以写成指针的形式。

二.使用指针访问数组

了解数组名后,我们可以进一步了解指针和数组的关系。指针是怎么访问数组的呢?

int a[5] = { 1,2,3,4,5 };
int* p = a;
for (int i = 0; i < 5; i++)
{
	printf("%d ", *(p + i));
}

使用上述的办法可以将数组里的每个元素打印出来,所以说 p[i] 其实等价于*(p+i)。其实编译器在处理时也是讲数组转化成指针,再去解引用的。我们可以拓展一下,[ ]这个符号是下标引用操作符,其实p[i]还可以写成i[p],对的,没错,这样写也行。因为编译器在编译的时候会讲数组名转换成指针形式,如上述的两个,转化完后是*(p+i)和*(i+p)其实没有什么区别,当然我们平时也没有必要用第二种解法,这里只做例子拓展。

三.二级指针与指针数组

二级指针说白了就是指向指针的指针。

int a[5] = { 1,2,3,4,5 };
int* p = a;
int** pp = &p;

pp存储的是指针p的地址,要也应用pp要解引用两次,*(*pp),*pp这个星号是取出了p的地址,对p在解引用才能求出a[0]的值。

指针数组,存储指针的数组。

int a1[] = { 1,2 };
int a2[] = { 3,4 };
int* a[] = { a1,a2 };

指针数组可以模拟二维数组。

int a1[] = { 1,2 };
int a2[] = { 3,4 };
int* a[] = { a1,a2 };
for (int i = 0; i < 2; i++)
{
	for (int j = 0; j < 2; j++)
	{
		printf("%d ", a[i][j]);
	}
}

为什么可以这样呢?那个a[i][j]其实就等于*(*(a+i)+j)所以说可以那样写先a+i解引用,再让解引用完的值加上j再解引用,这样就可以成功输出了。

以上就是本篇的全部内容了,创造不易,如果喜欢的话点个赞,点个关注^-^

谢谢大家^_^

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值