一般来数参数的传递是值传递,也就是说实参传给形参,形参发生改变时实参并不会改变,(单向)但是数组在传递的时候是地址传递,只要形参发生了变化,实参也会发生变化(双向)。

这样传递数组就会发现一个问题,我没有办法获取到数组的长度。获取数组的长度我们一般用:

sizeof(a)/sizeof(int)
int test2(int a[]){
	int n = sizeof(a)/sizeof(int);
	for(int i=0;i<n;i++){
		printf("%d ",a[i]);
		a[i]++;
}
我们会发现n的值一直是2!为什么会这样呢!? 因为,a是函 数参数,到了本函数中,a只是一个指针(地址,系统在本函数运行时,是不知道a所表示的地址有多大的数据存储 空间,这里只是告诉函数:一个数据 空间首地址 ),所以,sizoef(a)的结果是指针变量a占内存的大小 ,一般在64位机上是8个字节。 int类型是4个字节,所以,结果永远是2, ,我们要向获取数组长度要怎么办呢?

我可以在初始化数组的地方获取到数组的长度,作为参数传递过来:

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

这样做我们可以获取到数组的长度。

二维数组:

二维数组作为参数传递是后我们不可以像以为数组那样直接,如:

void test1(int a[][]){
	for(i = 0; i < 5; i++){
		for(j = 0; j < 5; j++){
			printf("%d ",a[i][j]);
int main(){
	int a[5][5],i,j;
	for(i = 0; i < 5; i++){
		for(j = 0; j < 5; j++){
			a[i][j] = i*5 + (j +1);
	test1(a);
	return 0;	

会发现编译都编译不通过,报“[Error] declaration of 'a' as multidimensional array must have bounds for all dimensions except the first”这个错,意思是多维数组的定义必须有一个除第一个之外的所有维度的边界,比如:

void test1(int a[][5]){
	for(int i = 0; i < 5; i++){
		for(int j = 0; j < 5; j++){
			printf("%d ",a[i][j]);
}
这样就OK了,但是我们是动态分配的数组不知道这个维度是多少的时候怎么办?这时候我们可以用指针当做一维数组来操作:
void test1(int *p,int n){
	for(int i = 0; i < n; i++){
		printf("%d ",p[j]);
int main(){
	int a[5][5],i,j;
	int *p;
	p = &a[0][0];
	for(i = 0; i < 5; i++){
		for(j = 0; j < 5; j++){
			a[i][j] = i*5 + (j +1);
	test1(p,25);
	return 0;	

这样我们发现不能更灵活的去定位到某一行某一列,这样我们需要手工改变寻址方式:
void test2(int  m,int  n,int **p){//m,n是行和列,
	for(int i = 0; i < m; i++){
		for(int j = 0; j < n; j++){
			printf("%d ",*((int *)p+n*i+j));
int main(){
	int a[5][5],i,j;
	for(i = 0; i < 5; i++){
		for(j = 0; j < 5; j++){
			a[i][j] = i*5 + (j +1);
	test2(5,5,(int **)a);
	return 0;	
而将这些带有对数组元素进行操作的代码封装进一个函数时,我们应该采用地址传递的传参方式,以真正地实现对数组数据的更改
(若为值传递,改变的是函数中拷贝的临时数组,并不能真正改变原来传入数组的元素)。
C++中主要有两种能实现地址传递的方法:
此处记录了使用 指针 来传递数组进函数的一些方法。(包括一维数组的两种值传递、两种地址传递,二维数组的一种值传递、一种地址传递)
尤其需要注意函数形参的语法格式
指针 * 到底从属于形参的变量类型..
                                    2. &arr(取数组地址)和arr(数组首元素)的值虽然相同但是意义不一样,数组地址+1是加了整个数组大小,而数组首元素+1是加了一个数组元素的大小。结论:1. arr(数组名)=&arr[0](数组首元素),数组名就是数组首元素地址。(1)sizeof(数组名)-数组名表示整个数组-计算的是整个数组的大小单位是字节。(2)&数组名-数组名表示整个数组-取出的是整个数组的地址。我们在写代码的时候,会将数组作为参数传给函数。
                                    数组传参时不论字符串、字符、整形都可以使用数组和指针接收,并且利用相关知识调用
字符串数组可以不传递数组长度,其它类型的数组需要传递数组长度
我们都在for循环,区别在于你是什么情况下break的。......
如果想要在函数中传递一个一维数组作为参数,您必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。同样地,您也可以传递一个多维数组作为形式参数。
形式参数是一个指针:
void myFunction(int *param)
形式参数是一个已定义大小的数组:
void myFunction(int param[10])
                                    可以定义一个能接受数组作为函数参数的函数,然后调用这个函数时,可以将一个实际的数组传递给它。
数组作为函数参数时,其定义方式有下列三种:
/*函数名param后跟一个空的[],说明param可以接受一个数组*/
void myFunction(int param[]) {
   /*函数体 代码*/ 
/*函数名param后跟一个非空的[size],说明param可以接受一个大小为size的数...
1.sizeof(数组名),这时候计算的是整个数组的字节长度
2.&数组名,例如在32位系统中,整形数组 arr里面五个元素,输出这个数组首元素地址。末尾是00那么&arr+1 输出末尾就是4*5+4
                                    我们知道可以使用sizeof(arr) / sizeof(arr[0])来就算数组元素个数,我们使用两层循环,外侧循环是用来控制冒泡排序的趟数,内层循环是用来比较元素的,我们看内层循环,因为冒泡排序的每一趟都会使一个元素出现在正确的位置,我们这里是升序,第一趟排完后,9肯定会出现在最后一个位置,第二趟排完后,8肯定会出现在倒数第二个位置,所以我们的内层循环每次都需要减少一次比较,这样可以提高效率,所以我们使用。话题转回去再看我们的冒泡排序函数,我们传过去的是数组首元素的地址,当然计算出来的是sz=1了。
第一个int arr[]:对的
	第二个int arr[10]:不写都是对的,写上或者写错也没毛病。但是这里的10没用,没必要写
	第三个int* arr:数组名是首元素地址,那地址就可以用指针来接收,数组每个元素是int类型的,所以指针用int*
	第四个int..
void arrprint(int arr){      printf("%d\n",arr);}void main(){       int arr = 123;       arrprint(arr);       printf("aiyou");       getchar();}运行结果:123aiyou
二、传递数组的时候,需要将数组的长度也传入进去,否则只能传递一个第一个值
void arrprint(int* arr,int len){       f