数组指针和指针数组、指针函数和函数指针、指针常量、常量指针、函数指针数组

  1. 数组指针:指向数组的指针
    int (*p)[n]
    “()”的优先级高于“[]”,因此,p和“*”结合,构成一个指针,该指针名为p,int修饰的是数组的内容,即数组的每个元素。也就是说p是个指针,该指针指向具有n个整型的一维数组。
int (* arrPtr)[10] = NULL;	// 一个指针,它指向一个有10个int元素的数组
int matrix[3][10];          // 数组名称是一个指向第一个元素的指针,也就是第一行的指针
arrPtr = matrix;            // 使得arrPtr指向数组的第一行,在这种情况下,使用 arrPtr 获取元素的方式与使用 matrix 完全一样。例如,赋值运算(*arrPtr)[0]=5 等效于 arrPtr[0][0]=5 和 matrix[0][0]=5。
(*arrPtr)[0] = 5;       	// 将5赋值给第一行的第一个元素
++arrPtr;                  	// 将指针移动到下一行

int arr[5]={12345};
int (*p1)[5] = &arr;	//&arr 是指整个数组的首地址,而 arr 是指数组首元素的首地址,虽然所表示的意义不同,但二者之间的值却是相同的
/*下面语句会有警告:从不兼容的指针类型初始化*/
int (*p2)[5] = arr;		//左边的类型是指向整个数组的指针,而右边的数据类型是指向单个字符的指针
  1. 指针数组:具有指针类型元素的数组 (常常作为二维数组的一种便捷替代方式)
    int *p[n]
    “[]”的优先级高于“*”,因此,p先与“[]”结合,构成一个数组,数组名为p,(int * )修饰的是数组的内容,即数组的每个元素。也就是说p是个数组,该数组的元素是n个指向整型的指针。

  2. 函数指针:函数指针是一个指针,指向的是一个函数的地址。
    函数指针是需要把一个函数的地址赋给它,比如:

int (*fun)(int x, int y);
fun = &Function;	//或者  fun = Function;
x = (*fun)();		//或者	x = fun();

取址运算符&不是必须的,因为一个函数名就可以表示了它的地址,如果是函数调用,还必须包含一个圆括号包起来的参数表。

int add(int x, int y)
{
    return x + y;
}
int sub(int x, int y)
{
    return x - y;
}
//函数指针
int (*fun)(int x, int y);
int main(int argc, char *argv[])
{
    fun = add;	//第一种写法
    int num1 = (*fun)(1,2);
    printf("num1 = [%d]\n", num1);
    
    fun = ⊂	//第二种写法
    int num2 = fun(3,4);
    printf("num2 = [%d]\n", num2);
    return 0;
}
int (*f)();	//所指向的函数返回整型值
int *(*f)();	//所指向的函数的返回值是一个整型指针,必须对其进行间接访问才能得到一个整型值
int *f[];	//指针数组,元素类型是指向整型的指针
int (*f[])();	//f是一个数组,数组元素的类型是函数指针,它所指向的函数的返回值是一个整型值
int *(*f[])();	//这个声明创建了一个指针数组,指针所指向的类型是返回值为整型指针的函数

//把g声明为一个数组,数组的元素类型是一个函数指针,它所指向的函数接受两个参数,并返回一个整型指针
int *(*g[])(int , float);
//next是一个指针,它指向一个函数,该函数返回另一个指针,该指针指向一个类型为char的常量指针。
char * const *(*next)();
  1. 指针函数:指针函数是一个函数,是返回值为指针的函数。
    注意:在调用指针函数时,需要一个同类型的指针来接收其函数的返回值。
    普通的函数声明:int fun(int x , int y);
    指针函数的声明:int* fun(int x, int y);

  2. 指针常量和常量指针

int *pi;	//pi是一个普通的指向整型的指针。
int const *pci;	//pci是一个指向整型常量的指针(指针常量)。可以修改指针的值,但不能修改它所指向的值。
int *const cpi;	//cpi是一个指向整型的常量指针(常量指针)。指针是常量,它的值无法修改,但可以修改它所指向的整型的值。
int const *const cpci;	//指针本身和它所指向的值都是常量,不能修改。

根据下标运算符的规则,表达式(*arrPtr)[i] 等同于 *((*arrPtr)+i)

  1. 函数指针数组
    函数指针数组的作用是什么呢?它最大的作用就是可以简化代码,减少很多重复的不必要的代码。
    例如下面这段代码
int main()
{
	int x, y;
	int input = 1;
	int ret = 0;
	do
	{
		printf("*************************\n");
		printf(" 1:add           2:sub \n");
		printf(" 3:mul           4:div \n");
		printf("*************************\n");
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = add(x, y);
			printf("ret = %d\n", ret);
			break;
		case 2:
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = sub(x, y);
			printf("ret = %d\n", ret);
			break;
		case 3:
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = mul(x, y);
			printf("ret = %d\n", ret);
			break;
		case 4:
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = div(x, y);
			printf("ret = %d\n", ret);
			break;
		case 0:
			printf("退出程序\n");
			breark;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

在switch中有很多完全重复的代码,如果我们用函数指针数组优化后是这样的。

int main()
{
	int x, y;
	int input = 1;
	int ret = 0;
	int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; 
	while (input)
	{
		printf("*************************\n");
		printf(" 1:add           2:sub \n");
		printf(" 3:mul           4:div \n");
		printf("*************************\n");
		printf("请选择:");
		scanf("%d", &input);
		if ((input <= 4 && input >= 1))
		{
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = (*p[input])(x, y);
		}
		else
			printf("输入有误\n");
		printf("ret = %d\n", ret);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值