1. 程式人生 > 其它 >26.指標陣列和陣列指標和函式指標和指標函式

26.指標陣列和陣列指標和函式指標和指標函式

指標陣列 : 存放指標的陣列

int main()
{
	int arr[10];
	//整形陣列
	int* arr2[5];  
	//(整形)指標陣列 -->變數名是arr2型別是 int*  [5]
	return 0;
}

陣列指標 :指向陣列的指標

int main()
{
	int arr[10] = { 0 };
	int(*pArr)[10] = &arr;  //陣列指標,&arr表示整個陣列的地址

	char str[5] = { 0 };
	char(*pStr)[5] = &str;  //陣列指標,&arr表示整個陣列的地址

	return 0;
}

使用一維陣列指標

void ArrPrint(int arr[], int num) //(int* arr, int num)
{
	int i = 0;
	for (i = 0; i < num; i++)
	{
		printf("%d ",*(arr + i)); //arr[i]
	}
	printf("\n");
}

void ArrPrint1(int (*PArr)[10], int num)
{
	int i = 0;
	for (i = 0; i < num; i++)
	{
 //printf("%d ",(*parr)[i] ); 
		printf("%d ", *((*parr)+i) );
	}
	printf("\n");
}
int main()
{
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7 ,8 ,9, 10 };
	int num = sizeof(arr) / sizeof(int);
	ArrPrint(arr, num);   //arr表示陣列的首元素地址

	ArrPrint1(&arr, num);
	return 0;
}

使用二維陣列指標

void ArrPrint2(int arr[][5], int row, int col) //(int* arr, int num)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			//printf("%d ", arr[i][j]); 
			//printf("%d ", *(arr[i] + j));  
			printf("%d ", *( (*arr + i * col) + j));
		}
	}
	printf("\n");
}

void ArrPrint3(int (*PArr)[5], int row, int col)  //(二維陣列指標)指向二維陣列的指標定義時只需要寫列的[],與一維陣列指標類似
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			//printf("%d ", PArr[i][j]); 
			//printf("%d ", *(PArr[i] + j));  
			printf("%d ", *( (*(PArr + i) + j) ) );  
		}
	}
printf("\n");
}
int main()
{
	int arr[3][5] = { 1, 2, 3, 4, 5,
					  6, 7 ,8 ,9, 10,
					 11, 12, 13, 14, 15 };
	int num = sizeof(arr) / sizeof(int);
	int col = sizeof(arr[0]) / sizeof(int);
	int row = num / col;
	ArrPrint2(arr, row, col);   //arr表示二維陣列的首元素地址(此時與一維陣列首元素的意義是一樣的)

	ArrPrint3(arr, row, col);  //arr表示二維陣列首元素地址(是指二維陣列真個第一行陣列的地址)
	return 0;
}

總結:
陣列指標分一維和二維兩種
對一維陣列指標解引用有兩種方式

 (*parr)[i]
 *((*parr)+i) 

對二維陣列指標解引用有三種方式

 PArr[i][j]
 *(PArr[i] + j)
 *( (*(PArr + i) + j) ) 

函式指標 :指向函式地址的指標

int Add(int x, int y)
{
	return x+y;
}

int main()
{
	int arr[5];
	int (*pa)[5] = &arr;
	printf("%p\n", &Add);
	printf("%p\n", Add);
	int (*p)(int, int) = Add;//p是函式指標
	int ret = p(2, 3);       //注意*在這裡是不體任何作用的int ret = *p(2, 3);
	printf("%d\n", ret);
	return 0;
}
typedef struct Stu
{
	char name[20];
	int age;
	float score;
}Stu;

int main()
{
	typedef unsigned int uint;

	void (*signal(int, void(*)(int)))(int);

	//簡化
	typedef void (*pfun_t)(int);
	//void(*p)(int);

	pfun_t signal(int, pfun_t);

	//signal是一個函式宣告
	//signal函式有兩個引數,第一個引數是int型別,
	//第二個引數是函式指標型別
	//該函式指標指向的函式,引數是int,返回型別是void
	//signal函式的返回型別是一個函式指標,該函式指標指向的函式,
	//引數是int,返回型別是void

	return 0;
}

函式指標陣列

對於函式指標陣列的建立如下:

 int my_strlen(const char*str)
 {
	 int len = 0;
	 while (*(str + len++) != '\0');
	 return --len;
 }
 
 int main()
 {
 	int* arr[10];
 	char* arr2[5];
 	//函式指標陣列

	char str[] = "xiao du zhen ke ai";
 	int (*ps)(const char*) = &my_strlen;
 	int (*ps2)(const char*) = &my_strlen;
 	int (*ps3)(const char*) = &my_strlen;

 	//int (*psArr[3])(const char*) = {ps, ps2, ps3};//函式指標陣列
	int (*psArr[3])(const char*) = { &my_strlen, &my_strlen, &my_strlen };//函式指標陣列

	int ret = psArr[0](str);
	printf("length of str = %d \n",ret);
	//存放函式指標的陣列
 	
 	return 0;
 }

void menu()
{
	printf("******************************\n");
	printf("***     1. add    2. sub   ***\n");
	printf("***     3. mul    4. div   ***\n");
	printf("***     0.exit             ***\n");
	printf("******************************\n");
}

int Add(int x, int y)
{
	return x+y;
}
int Sub(int x, int y)
{
	return x-y;
}
int Mul(int x, int y)
{
	return x*y;
}
int Div(int x, int y)
{
	return x/y;
}

int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	//函式指標陣列-轉移表
	int (*pArr[5])(int, int) = {0, Add, Sub, Mul, Div};
	do 
	{
		menu();
		printf("請選擇:>");
		(void)scanf("%d", &input);
		printf("請輸入兩個運算元:>");
		(void)scanf("%d%d", &x, &y);
		ret = pArr[input](x, y);
		printf("ret = %d\n", ret);

 	} while (input);
	return 0;
}

**總結: 函式指標無需解引用就能使用,解引用多次也不影響作用 函式指標最大的優勢在於: 可以將引數個,數型別及返回值相同的函式歸為一類函式放入函式指標陣列中去,再以合適的判斷條件去呼叫,就可以極大的簡化重複使用的程式碼 **