深入理解指针_2_指针访问数组及传参理解

1.数组名的理解

用这段代码,看一下 arr ; &arr ; &arr[0] 有什么区别

#include<stdio.h>
int main()
{
  int arr[10]={0};
  printf("%p\n",arr);
  printf("%p\n",&arr);
  printf("%p\n",&arr[0]);
  return 0;
}

在这里插入图片描述
一样的地址,说明此时三种写法都表示数组中第一个元素的地址
直接用数组名(arr)等价于 &arr[0] ,表示第一个元素的地址(但又两个例外,写后面了)

再用这个代码看看区别:

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	printf("arr       =%p\n", arr);
	printf("arr+1     =%p\n", arr + 1);
	printf("&arr      =%p\n", &arr);
	printf("&arr+1    =%p\n", &arr+1);
	printf("&arr[0]   =%p\n", &arr[0]);
	printf("&arr[0]+1 =%p\n", &arr[0]+1);
	return 0;
}

在这里插入图片描述

&arr与&arr+1相差 40 个字节,其他两组相差 4 个字节
而arr中 10 个元素占的内存正好为 40 个字节
所以,写成&数组名 表示取整个数组的地址,而非数组首元素的地址
这是第一个例外(上面提到了)
第二个:
sizeof(arr):这里arr也表示取整个数组的地址,计算的是整个数组占的字节数

总结两例外:
1. &(数组名):表示取出整个数组的地址
2. sizeof(数组名):数组名表⽰整个数组,计算的是整个数组的⼤⼩,
单位是字节

2.使用指针访问数组

写段代码,输入数组中元素后输出

#include<stdio.h>
int main()
{
  int arr[10]={0};
  int i=0;
  int* p=arr;
  int sz=sizeof(arr)/sizeof(arr[0]);
  for(i=0;i<sz;i++)
  {
    scanf("%d",p);
    p+=i;
  }
  p=arr;
  for(i=0;i<sz;i++)
  {
    printf("%d ",*(p+i));
  }
  return 0;
}

在这里插入图片描述
此代码中,p与arr是等价的,既然arr[i]可以访问数组元素,那么 p[i] 也可以访问数组元素
在这里插入图片描述
总结一下:(准备好下巴)
arr[i] 等价于 p[i]
arr[i] 本质上是 *(arr+i) == * (p+i)
*(arr+i)= * (i+arr) 即:arr[i]=i[arr] p[i]=i[p]

*arr[i] = (arr+i)= * (i+arr) = i[arr]

再改一次验证一下:
在这里插入图片描述



看一段问题代码:

#include <stdio.h>
void test(int arr[])
{
	int sz2 = sizeof(arr) / sizeof(arr[0]);
	printf("sz2 = %d\n", sz2);
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz1 = sizeof(arr) / sizeof(arr[0]);
	printf("sz1 = %d\n", sz1);
	test(arr);
	return 0;
}
  

在这里插入图片描述
sz2的问题在于,传参时传的是首元素的地址,而sizeof 此时计算的只能是首元素的内存字节

3.传址调用

写一个函数,实现两个变量间值的交换:
问题代码:

#include<stdio.h>
void Switch(int x ,int y)
{
  int temp=0;
  temp=x;
  x=y;
  y=temp;
}
int main()
{
  int a=5;
  int b=3;
  printf("%d %d\n",a,b);
  Switch(a,b);
  printf("%d %d\n",a,b);
}

在这里插入图片描述

问题在于:实参 a,b和形参 x,y存放的不是同一块内存,函数中的 x,y只是接受了a,b的值,就算x,y的值在函数里发生交换,也不会影响a,b的值
此时就需要把 a,b的地址分别传给x,y

用指针:

#include<stdio.h>
void Switch(int* x, int* y)
{
	int temp = 0;
	temp = *x;
	*x = *y;
	*y = temp;
}
int main()
{
	int a = 5;
	int b = 3;
	printf("%d %d\n", a, b);
	Switch(&a, &b);
	printf("%d %d\n", a, b);
}

在这里插入图片描述
这就是传址调用

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值