c語言深度剖析(35)—數組參數和指針參數分析

1.思考

  • 爲什麼C語言中的數組參數會退化爲指針? 

2.退化的意義 

  • C語言中只會以值拷貝的方式傳遞參數 
  • 當向函數傳遞數組時: 
    • 將整個數組拷貝—份傳入函數(  X   )
    • 將數組名看做指針常量傳數組首元素地址 ( ✔ )
  • C語言以高效作爲最初設計目標: 
    • 參數傳遞的時候如果拷貝整個數組執行效率將大大下降 
    • 參數位於棧上,太大的數組拷貝將導致棧溢出

3.二維數組參數 

  • 二維數組參數同樣存在退化的問題 
    • 二維數組可以看作是—維數組 
    • 二維數組中的每個元素是—維數組 
  • 二維數組參數中第—維的參數可以省略

4.等價關係 

  • float *a指向的一維數組的每個元素爲float型
  •  int **a指向的一維數組的每個元素爲int*類型
  • char(*a)[4]指向的一維數組的每個元素爲int[4]類型(共3個元素)

5.被忽視的知識點

  • C語言中無法向—個函數傳遞任意的多維數組 
  • 必須提供除第—維之外的所有維長度 
    • 第一維之外的維度信息用於完成指針運算 
    • N維數組的本質是一維數組,元素是N-1維的數組 
    • 對於多維數組的函數參數只有第—維是可變的

6.編程實驗 

  • 傳遞與訪問二維數組     
#include <stdio.h>

void access(int a[][3], int row)
{
	int col = sizeof(*a) / sizeof(int);
	int i = 0;
	int j = 0;

	printf("sizeof(a) = %d\n", sizeof(a));
	printf("sizeof(*a) = %d\n", sizeof(*a));

	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf("%d\n", a[i][j]);
		}
	}

	printf("\n");
}

void access_ex(int b[][2][3], int n)
{
	int i = 0;
	int j = 0;
	int k = 0;

	printf("sizeof(b) = %d\n", sizeof(b));
	printf("sizeof(*b) = %d\n", sizeof(*b));

	for (i = 0; i < n; i++)
	{
		for (j = 0; j < 2; j++)
		{
			for (k = 0; k < 3; k++)
			{
				printf("%d\n", b[i][j][k]);
			}
		}
	}

	printf("\n");
}

int main()
{
	int a[3][3] = { {0, 1, 2}, {3, 4, 5}, {6, 7, 8} };
	int aa[2][2] = { 0 };
	int b[1][2][3] = { 0 };

	access(a, 3);
	//access(aa, 2);    /* expected'int (*)[3]', but argument is type of 'int (*)[2]' */
	access_ex(b, 1);
	//access_ex(aa, 2);  /* expected'int (*)[2][3]', but argument is type of 'int (*)[2]' */

	return 0;
}
  • 運行結果:

7.小結

  • C語言中只會以值拷貝的方式傳遞參數 
  • C語言中的數組參數必然退化爲指針 
  • 多維數組參數必須提供除第—維之外的所有維長度 
  • 對於多維數組的函數參數只有第—維是可變的​​​​​​​
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章