C++ 数组指针下标的理解【个人学习笔记用】

一、C++中传递参数的三种方法

1. 直接按值传递
形如:

 int fun1(int a){
 	printf(a);
 }

该方法会在调用函数时把传入的参数copy一份后在函数中进行操作,不会影响到原来的参数。
2. 指针(地址)传递
形如:

int fun1(int *a){
	printf(*a);
}

将参数的地址(指针)传进来,函数的操作会直接影响到原参数。函数内部使用时候需要取值操作,如 *a
3.引用传递
形如:

int fun1(int &a){
	printf(a);
}

这是c++特有的方式,很方便,能直接影响原参数的同时,在函数能可以直接用a就行。

另外附上一个对c++函数的参数传递写的比较好的博文,尤其是对引用参数的理解
https://blog.csdn.net/qq_34170700/article/details/104389168

二、数组指针,数组指针下标

形如int a[ ]={1,2,3,4}的数组,&a后取的地址为数组中首元素的地址。
可以先看下面的代码,直观理解如下:

int a[10]*pa;  //先进行定义,pa是指针变量名,通俗讲就是指针
pa=&a[0];   
//等价于
pa=a;    //这意味着数组名a也是数组的首地址
//当然也可以连续赋值
int *pa=&a[0]int *pa=a;

//等效形式,以为定义的是int型的数组a,所以对pa+1,或换句话说对指针加一等价于当前地址顺序往下偏移4个字节,正好是下个数组元素,因此很多枚举enumeration都是对指针加一来遍历元素
*pa==a[0]

//pa+1是指针运算
*(pa+1)==a[1]

*(pa+i)==a[i]

最最重要的是这四者是等价的,本质上是一模一样的
a[i]==pa[i]==*(pa+1)==*(a+i)

附一个小实验:

#include<iostream>
#include<stdio.h>
using namespace std;

int main(){
	int a[]={1,2,3};
	int *pa=a;
	cout <<"&a:  " <<&a <<endl;
	cout << "&a[0]:  "<<&a[0] <<endl;
	cout << "a:  "<<a << endl;
	cout << "*a:  "<<*a << endl;
	cout << "pa:  "<<pa << endl;
	//数组指针下标取值,其实本质和a[0]一模一样 
	cout << "pa[0]:  "<<pa[0]<<endl; 
	cout << "a+1:  "<<a+1 <<endl;
	cout << "&a +1:  "<<&a +1 << endl;
	//指针变量名所在的地址 
	cout << "&pa:  "<<&pa <<endl;
	cout << "pa+1:  "<<pa+1 <<endl;
	//指针变量所存放的是数组a的首地址
	cout << "*(&pa):  "<<*(&pa)<<endl;
	cout <<"&pa+1:  "<<&pa +1 << endl;
}
}
}

结果如下:
在这里插入图片描述

但是!!!!!上面讲的很笼统,数组名和指针还是有区别的

如下面,按照我们上面的理解,应该结果相同

	cout << a+1 <<endl;
	cout << &a +1 << endl;

结果实际上是不同的
在这里插入图片描述
原理:
原文地址:【a+1和&a+1的区别】https://mbd.baidu.com/ma/s/WGppTnOr
在这里插入图片描述
证明&a是一个指针(数组指针)

	cout << *(&a) << endl;
	cout << *(*(&a)) << endl;

结果如下:
在这里插入图片描述
很有意思的结果!!!!!!,&a是一个指针(数组指针)(无指针变量名),存放的值是数组首地址。
总结:
别的博主总结的,可能并不是完全正确的,可以参考
原文地址:https://blog.csdn.net/qq_44559016/article/details/117064724
数组名的地址数组第一个元素的地址数组名本身,这说明数组名本身就是一个地址
对指针取地址会得到指针自身的值,但是对数组名取地址会得到数组名所指元素的地址
数组一经定义数组名不可更改,但是指向这个数组名的指针是可以改变指向的
对数组名使用sizeof时,返回的是数组元素个数*元素类型占用的字节,对指针使用sizeof,返回的是系统中指针类型的大小
通过取地址&,之后进行+1操作得到的结果也不一样
当数组名作为参数传递时,就由常量指针变成了一般指针,就可以自增自减了。

【个人总结】
1.注意a+1和&a+1的不同
2.a,数组名本身是一个地址(数组首地址),&a是数组指针,存放的是数组首地址,有点特殊(见我最后一个附的小实验。
3.看图(a和pa本身可以看成等于一个地址)
在这里插入图片描述

4.小实验

#include<iostream>
#include<stdio.h>
using namespace std;

int main(){
	int a[]={1,2,3};
	int *pa=a;
	cout <<"&a:  " <<&a <<endl;
	cout << "&a[0]:  "<<&a[0] <<endl;
	cout << "a:  "<<a << endl;
	cout << "*a:  "<<*a << endl;
	cout << "pa:  "<<pa << endl;
	//数组指针下标取值,其实本质和a[0]一模一样 
	cout << "pa[0]:  "<<pa[0]<<endl; 
	cout << "a+1:  "<<a+1 <<endl;
	cout << "&a +1:  "<<&a +1 << endl;
	//指针变量名所在的地址 
	cout << "&pa:  "<<&pa <<endl;
	cout << *(&pa) <<endl;
	cout << *pa <<endl;
	cout << "pa+1:  "<<pa+1 <<endl;
	//指针变量所存放的是数组a的首地址
	cout << "*(&pa):  "<<*(&pa)<<endl;
	cout <<"&pa+1:  "<<&pa +1 << endl;
	cout << *(&a) << endl;
	cout << *(*(&a)) << endl;

}

结果
在这里插入图片描述

更新:
这个博主应该解释了我上面说的东西
原文地址:https://blog.csdn.net/w1234567465/article/details/98784566
在这里插入图片描述

三、如何传递数组给函数

方法一:
形参是指针

void fun1(int *arr){
	int t=arr[0];
}
int a[2];
fun1(a)

方法二:
形参是一个已知大小的数组

void fun2(int arr[3]){
	int t=arr[0];
int a[2];
fun2(a)

方法三:
形参是一个未知大小的数组

void fun3(int arr[]){
	int t=arr[0];
int a[2];
fun3(a)

实际调用时都是传递一个指向数组的指针作为参数
具体可以看菜鸟教程https://www.runoob.com/cplusplus/cpp-passing-arrays-to-functions.html

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值