高级指针1



在之前学习数组的时候接触过指针,我们可以了解到指针和数组之间并没有关系,看前面的文章回顾一下https://blog.csdn.net/snowyuuu/article/details/79999829

那么到底什么是指针数组 ,数组指针 ,函数指针, 函数指针数组, 指向函数指针数组的指针呢?接下来我们就深入的学习下指针。

指针数组

一.定义:简单来说就是存放指针的数组。首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。

二.代码表示定义:

int *arr1[10];
char *arr2[5];
char **arr3[5];

int *arr1[10]的理解 :这里需要明白一个符号之间的优先级问题。“[]”的优先级比“*”要高。arr1先与“[]”结合,构成一个数组的定义, 数组名为arr1,int* 修饰的是数组的内容,即数组的每个元素;所以int *arr1[10] 就是一个数组,其包含10个指向int类型数据的指针。

【数组指针】

一.定义:数组指针就是指针。首先它是一个指针,它指向一个数组。在32位系统下永远是占4个字节,至于它指向的数组占多少字节,不知道。它是“指向数组的指针”的简称。

二.代码表示定义:


int (*p)[10];

int (*p)[10]的理解:在这里“()”的优先级比“[]”高,“*”号和p构成一个指针的定义,指针变量名为p,int修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。所以p是一个指针,它指向一个包含10个int类型数据的数组,即数组指针。

注意:只要数组指针int (*p)[10],其中10不可以改为其他数字,更不可以不写,因为数组大小也是判定数组类型相同的一个指标,比如在数组传参时第二个维数不可以省略一样。

三.指针数组的应用:


#include<stdio.h>
#include<windows.h>
int main()
{
	int arr[10] = { 0 };
	int *p1 = arr;
	int(*p2)[10] = &arr + 1;

	printf("%p\n", arr);//整个数组地址;00D3FA2C
	printf("%p\n", arr+1);//下一个元素的地址;00D3FA30(首元素加4)
	printf("%p\n", &arr+1);//下一个数组的地址,即数组指针;00D3FA54(首元素加40)

	printf("%p\n", p1);//00D3FA2C
	printf("%p\n", p2);//00D3FA54

	system("pause");
	return 0;
}

从上面代码可以看出,p2是数组指针,指向的是下一个数组。它 是存放数组地址的。

【函数指针】

一.定义:就是函数的指针,它是一个指针,指向一个函数。

二.代码表示定义:

char *(*fun)(char *p1, char *p2);

fun与*结合,是一个指针变量,它指向一个函数。这个函数有两个指针类型的参数,函数的返回值也是一个指针。

三.函数指针的使用:

#include<stdio.h>
#include<windows.h>
#include <string.h>

char * fun(char * p1, char * p2)
{
	int i = 0;
	i = strcmp(p1, p2);
	if (0 == i)
	{
		return p1;
	}
	else
	{
		return p2;
	}
}
int main()
{
	char * (*pf)(char * p1, char * p2)=fun;//定义一个函数指针pf
	//pf=&fun;
	char* ret=(*pf) ("aa", "bb");
	printf("%s\n", ret);//bb

	system("pause");
	return 0;
}

我们使用指针的时候,需要通过*(解引用)来取其指向的内存里面的值,函数指针使用也如此。通过用(*pf)取出存在这个地址上的函数,然后调用它。

注意:给函数指针赋值时,可以用&fun或直接用函数名fun。这是因为函数名被编译之后其实就是一个地址,所以这里两种用法没有本质的差别。

【函数指针数组】

一.定义:把函数的地址存到一个数组中,那么这个数组就叫函数指针数组。

二.代码表示定义:


int main()
{
	int(*parr1[10])();
	//int *parr2[10]();//语法报错“parr2”数组元素类型不能是函数
	//int (*)() parr3[10];//语法错误:“)”

	system("pause");
	return 0;
}

所以正确定义函数指针数组为int(*parr1[10])(),它是一个数组,数组名为parr1,int (*)()是函数指针,则数组内存储了10个指向函数的指针。

三,函数指针数组的应用:转移表

编写一个计算器,可以使用switch循环语句选择case 来实现,但是这样运算量大,现在使用函数指针数组来实现,使之优化。

//计算器(函数指针数组):
#include<stdio.h>
#include<windows.h>
//选择运算:
int my_add(int x, int y)
{
	return x + y;
}
int my_sub(int x, int y)
{
	return x - y;
}
int my_mul(int x, int y)
{
	return x * y;
}
int my_div(int x, int y)
{
	if (0==y)
	{
		printf("Error");
		return -1;
	}
	else
	{
		return x / y;
	}
}

void menu()
{
	printf("**************************\n");
	printf("***1.add          2.sub***\n");
	printf("***3.mul          4.div***\n");
	printf("***              0.quit***\n");
	printf("**************************\n");
	printf("please select");
}
int main()
{
	int(*p[5])(int x, int y) = { 0,my_add, my_sub, my_mul, my_div };//定义函数指针数组直接可以内访问数组内的函数指针。
	int input = 0;
	int ret = 0;
		
	do{
		menu();
		scanf_s("%d", &input);
		if (input >= 1 && input <= 4)
		{
			int x, y;
			printf("Please Input Your Data For Cal<x,y>:");
			scanf_s("%d%d", &x,&y);
			ret = (*p[input])(x, y);
			printf("Result:%d\n", ret);
		}
		else if (input == 0)
		{
			printf("Bye!\n");
			break;
		}
		else
		{
			printf("You Input Error,Please Inpue[1,4]\n");
		}

	} while (1);
	system("pause");
	return 0;
}

打印结果是:

【指向函数指针数组的指针】

一,定义:函数指针数组指针就是一个指针。只不过这个指针指向一个数组,这个数组里面存的都是指向函数的指针。

二.代码表示定义:

char (*(*pf)[10])(char *p)

理解:pf是指针。这个指针指向一个包含了10个元素的数组;这个数字里面存的是指向函数的指针<char (*)()>;这些指针指向一些返回值类型为指向字符的指针、参数为一个向字符的指针的函数。









猜你喜欢

转载自blog.csdn.net/snowyuuu/article/details/80395161