C語言進階:指針的進階(3)

數組傳參和指針傳參

實踐之中不免會碰到數組和指針作函數參數而如何設計形參的問題。

一維數組傳參

一維數組傳參,下列接收方式是否可行呢?

//1.
void test(int arr[]) 
{}
//2.
void test(int arr[10]) 
{}
//3.
void test(int* arr) 
{}
int main()
{	
	int arr[10] = { 0 };
	test(arr);
	return 0;
}

1.數組傳參數組接收,可行但其實都會降級優化成指針,編譯器不會真正創建一個數組。

2.由於形參數組形同虛設,所以數組大小無意義,任意大小或無。(有歧義)

3.數組傳參本質就是首元素地址,首元素類型為int,所以指針的類型為int*。

所以可以看出[]和*()是等價的。我願稱之為*和[]的愛恨情仇!(‐^▽^‐)

//1.
void test2(int* arr[2])
{}
//2.
void test2(int** arr) 
{}
int main()
{	
	int* arr2[10] = { 0 };
	test2(arr2);
	return 0;
}

指針數組,每個元素類型為int*,故用二級指針接收數組名。

一維數組傳參,數組和指針接收。

二維數組傳參

//1.
void test(int arr[3][5]) 
{}
//2.
void test(int arr[][])
{}
//3.
void test(int arr[][5])
{}
int main() {
	int arr[3][5] = { 0 };
	test(arr);
}
  • 二維數組傳參用二維數組接收,行可省略,但列不可以
//4.
void test(int* arr)
{}
//5.
void test(int* arr[5])
{}
//6.
void test(int(*arr)[5])
{}
//7.
void test(int** arr)
{}
int main() {
	int arr[3][5] = { 0 };
	test(arr);
}

4.整型指針接收的應該是整型變量的地址,而二維數組數組名為首行的數組地址。

5.指針數組和二維數組無關。

6.二維數組傳參用首行數組大小的數組指針接收。

7.二級指針和二維數組無關。

  • 二維數組數組名arr為首行“一維數組”的地址,數組的地址用數組指針接收。

int(*)[5]型數組指針指向元素個數為5的一維數組。指針+1訪問到下一行,每次跳一行。再解一層引用訪問一行裡每個元素。

一級指針傳參

反向思考,若函數形參為指針,傳參時實參可以如何設計呢?

void test(int* ptr, int sz)
{}
void test(int arr[],int sz)
{}
int main()
{
    //1.
    int a = 10;
    test(&a);
    //2.
	int arr[10] = { 0 };
	test(arr);
	return 0;
}
  • 一級指針傳參,形參用指針和數組都行,但不提倡用一維數組。
  • 若形參為指針,實參也可以是指針(地址),也可以是數組。

二級指針傳參

當二級指針作參數時,形參如何設計呢?

void test(int** pp) {
	printf("%d\n", **pp);
}
void test(int* arr[]) {//用法不好
	printf("%d\n", *arr[0]);
}
int main() {
	int a = 10;
	int* p = &a;
	int** pp = &p;
	test(pp);
	return 0;
}
  • 當二級指針作函數參數時,形參可以是二級指針和指針數組。

當形參為二級指針,實參可以傳什麼呢?

void test(int** pp) {
	printf("%d\n", **pp);
}
int main() {
	int a = 10;
	int* p = &a;
	int** pp = &p;
	int* arr[10] = { &a };
    //1.
	test(&p);
    //2.
	test(pp);
    //3.
	test(arr);
	return 0;	
}
  • 當形參為二級指針時,實參可以是:二級指針(一級指針地址),指針數組首元素的地址。

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: