6.指针数组做函数参数

一维数组名也是一个地址,即指针,只不过数组名是一个常量指针,常量指针即不能修改该指针的值!所以看字符数组的赋值与字符指针的赋值就明白了!

void main() {
	int a[5] = { 0,1,2,3,4 };
	//a++;a--这些操作都是错误的!
	char buf[32] = "hello world"; //这是可以的,hello world以字符的形式拼接成的,存储在栈区
	char buf1[32];
	//buf1 = "hello world"; // 这是不可以的,hello world是字符常量在支付常量区,这样赋值,修改的a的指向,是不允许的
	//那么这时候给buf1赋值,需通过strcpy来完成;
	strcpy(buf1, "hello world");
	buf1[0] = 'b';//可以修改

	char *ptr = NULL;
	ptr = "hello world"; //这是可以的,ptr指向字符常量区的地址,ptr的值可以修改
	//ptr[0] = 'b';不允许的,不能修改字符常量区中的内容;

	system("pause");
}

其实理解了内存四区和数组名的含义,上面的代码就很好理解!

1.一维数组做函数参数

一维数组做函数参数,被调函数的参数怎么定义呢?最简单的方式,如果不知道怎么写参数,来最直接的!

void change(int a[5]) { //直接定义一个数组来做参数
	int i = 0;
	for (i = 0; i < 5; i++) {
		a[i] = i + 10;
	}

}

void main() {
	int a[5] = { 0,1,2,3,4 };
	int i = 0;
	change(a); //传递数组名
	for (i = 0; i < 5; i++) {
		printf("%d\n", a[i]);
	}
	
	system("pause");
}

当然,这种写法如果在公司,会显示你的代码能力很low,对C语言的理解估计还没有入门;利用sizeof看一下被调函数中的形参数组的大小是多少?

void change(int a[5]) { //直接定义一个数组来做参数
	int i = 0;
	printf("%d\n", sizeof(a)); // 看一下形参这个数组名的大小是多少

	for (i = 0; i < 5; i++) {
		a[i] = i + 10;
	}

}

void main() {
	int a[5] = { 0,1,2,3,4 };
	int i = 0;
	change(a); //传递数组名
	for (i = 0; i < 5; i++) {
		printf("%d\n", a[i]);
	}
	
	system("pause");
}

通过上面代码可以知道,形参数组名的大小为4个字节;也就是说,数组名作为参数,数组名退化成一个指针,那么使用指针来作为被调函数的参数即可!

void change(int *a) { //直接定义一个数组来做参数
	int i = 0;
	printf("%d\n", sizeof(a)); // 看一下形参这个数组名的大小是多少

	for (i = 0; i < 5; i++) {
		a[i] = i + 10;
	}

}

void main() {
	int a[5] = { 0,1,2,3,4 };
	int i = 0;
	change(a); //传递数组名
	for (i = 0; i < 5; i++) {
		printf("%d\n", a[i]);
	}
	
	system("pause");
}

2.指针数组做函数参数

指针数组也是一个一维数组,只不过数组中的元素是指针罢了,通过数组名即可遍历数组:

void main() {
	int a = 10, b = 20, c = 30, d = 40, e = 50;
	int *arr[5] = {&a,&b,&c,&d,&e};
	int i = 0;
	//change(a); //传递数组名
	for (i = 0; i < 5; i++) {
		printf("%d\n", *arr[i]);//a[i]是数组中的元素,但是元素是地址,想要取出地址中的值,必须是*arr[i];
	}
	
	system("pause");
}

指针数组作为函数参数,被调函数的参数该如何定义?由前一章可知,指针数组的数组名相当于一个二级指针!如果对二级指针不熟悉,还是老办法,直接定义一个指针数组来接收实参即可:

void change(int *a[5]) { //直接定义一个数组来做参数
	int i = 0;
	for (i = 0; i < 5; i++) {
		*a[i] = i + 100;
	}

}

void main() {
	int a = 10, b = 20, c = 30, d = 40, e = 50;
	int *arr[5] = {&a,&b,&c,&d,&e};
	int i = 0;
	change(arr); //传递数组名
	for (i = 0; i < 5; i++) {
		printf("%d\n", *arr[i]);//a[i]是数组中的元素,但是元素是地址,想要取出地址中的值,必须是*arr[i];
	}
	
	system("pause");
}

还是那句话,这样的代码很low,指针数组的数组名相当于一个二级指针,那么使用二级指针来接收实参:

void change(int **a) { //直接定义一个数组来做参数
	int i = 0;
	for (i = 0; i < 5; i++) {
	//a指向指针数组的首地址,a+1指向第二个元素,a+i指向数组的第i个元素,那么*(a+i)就是数组的第i个元素,
		//由于数组的元素是指针,所以**(a+i)才是数组的指针元素指向的内存的值;
		**(a + i) = i + 1000; 
	}

}

void main() {
	int a = 10, b = 20, c = 30, d = 40, e = 50;
	int *arr[5] = {&a,&b,&c,&d,&e};
	int i = 0;
	change(arr); //传递数组名
	for (i = 0; i < 5; i++) {
		printf("%d\n", *arr[i]);//a[i]是数组中的元素,但是元素是地址,想要取出地址中的值,必须是*arr[i];
	}
	
	system("pause");
}

3.字符指针数组做函数参数

看下面的代码,如果我们想要通过函数调用来修改修改数组其中的某一个元素的值,即假如需要将buf[2]的值修改成“studeng”,该怎么修改?

void main() {
	char *buf[] = { "hello","world","welcome","profect" };
	char **ptr = buf;
	int i = 0;

	for (i = 0; i < 4; i++) {
		printf("%s\n", *(ptr +i)); //使用二级指针来遍历字符指针数组;
	}
	
	system("pause");
}

也就是被调函数的参数该如何定义?先思考一下!

解答之前先回忆一下前面的内容;

char *buf[] = { "hello","world","welcome","profect" }

char *ptr = NULL;

对这个字符指针数组来说,&buf[0]与&buf[1]之间相差几个字节?

ptr与ptr+1相差几个字节?

这个问题搞清楚以后,就知道函数传递该如何定义了

void change(char **ptr) {
	//下面的哪行代码是正确的?
	//ptr[2] = "student";
	//*ptr[2] = "student";
}

void main() {
	char *buf[] = { "hello","world","welcome","profect" };
	char **ptr = buf;
	int i = 0;

	change(buf);

	for (i = 0; i < 4; i++) {
		printf("%s\n", *(ptr +i)); //使用二级指针来遍历字符指针数组;
	}
	
	system("pause");
}

总结:

由上面可知,指针数组名相当于一个二级指针,那么在定义被调函数的参数的时候,需要使用二级指针(type **ptr)来接收函数名,这时候二级指针就相当于是函数名了,ptr+i指向数组的第i个元素,

*(ptr+i)就是数组的第i个元素的值,由于指针数组的元素就是一个指针,所以**(ptr+i)才是这个数组的指针元素所指向的内存中的值!

你可能感兴趣的:(C语言高级)