1、整型数组—存放整型数据的数组
int arr[10];
2、指针数组—存放指针的数组
int* arr1[10];
3、数组指针—指向一个数组的指针
怎么判断是数组指针:看p1和谁先结合,如果是
(* p1)[ ],那么最终是指针,如果*p1[ ],那么p1先和[ ]结合,最终就是数组。
int(*p1)[10] = &arr;//指向整型数组的指针
int* (*p11)[10] = &arr1;//指向指针数组的指针
4、函数指针—指向一个函数的指针
int Add(int x, int y)
{
return x + y;
}
int main()
{
int a = 10;
int b = 20;
int(*p3)(int, int) = Add;
//首先p3和*先结合,最后这是一个指针,后面的(int,int)是函数传入参数的类型,前面int是返回类型。
//(*p3)和函数Add有一样的作用。
printf("%d\r\n", p3(a, b));
printf("%d\r\n", Add(a, b));
printf("%d\r\n", (*p3)(a, b));
// 对于函数指针调用时,加不加*都可以,p3本身就指的是Add,但是加*的话必须有括号(*p3)。
return 0;
}
练习:分析下面代码
( * ( void ( * ) ( ) ) 0 )( )
//void ( * ) ( )是函数指针类型,然后把这个类型放在括号里面再放在0前面,( void ( * ) ( ) ) 0 :就是把0强制类型转换,转换成某函数的地址;
//* ( void ( * ) ( ) ) 0 前面加*就是去找这个函数;
//( * ( void ( * ) ( ) ) 0 )( )就是调用这个函数,函数类型是无参的所以最后括号不用写参数类型。
void(*signal(int, void(*)(int)))(int)
// void(*)(int)是一个函数指针类型,signal这是函数名,(int,void(*)(int))这是函数的两个参数类型;
// 去掉函数后剩下void(* )(int)还是一个函数指针类型。
// 所以这是一个函数声明,按照理解应该写为void(*)(int) signal(int, void(*)(int))
// 前面void(*)(int)是返回值类型,signal是函数名,(int, void(*)(int))是两个参数。但这种写法是不对的!!!
// 使用typedef简化一下上面代码
// 例如typedef unsigned int uint;简化为uint
// 但是函数不同,不能写成typedef void(* )(int) pfun;二是要和*放在一起:typedef void(* pfun )(int)
typedef void(* pfun )(int);
pfun signal(int,pfun);//这两句合在一起就是原题的意思。
5、函数指针数组—存放函数指针的数组
int (*p4)(int, int) = Add;// 函数指针,但是只能存Add的地址。
// 需要一个数组,可以存放四个函数的地址--函数指针数组.
int (*p4arr[4])(int, int) = {Add,Sub,Mul,Div};// 这就是一个函数指针数组
函数指针数组练习:设计计算器
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;
}
void Calc(int (*pf)(int, int))
{
int x = 0, y = 0;
printf("请输入两个操作数:");
scanf_s("%d%d", &x, &y);
printf("%d\r\n", pf(x, y));
}
int main()
{
int input = 0;
int x = 0, y = 0;
printf("-------------------------\r\n");
printf("-- 1、Add 2、Sub --\r\n");
printf("-- 3、Mul 4、Div --\r\n");
printf("-- 0、exit ---\r\n");
printf("-------------------------\r\n");
printf("请选择:>");
scanf_s("%d", &input);
printf("请输入两个操作数:");
scanf_s("%d%d", &x, &y);
//方法一
if (input <= 4 && input >= 1)
{
//把四个函数地址放到函数指针数组里面
int(*pfarr[5])(int, int) = { 0, Add, Sub, Mul, Div };
printf("%d\r\n",pfarr[input](x, y));
}
else if (input == 0)
{
printf("退出\r\n");
}
else
{
printf("输入错误!!!\r\n");
}
//方法2
switch (input)
{
case 1:
Calc(Add);
break;
case 2:
Calc(Sub);
break;
case 3:
Calc(Mul);
break;
case 4:
Calc(Div);
break;
case 0:
printf("退出\r\n");
break;
default:
printf("输入错误\r\n");
break;
}
return 0;
}
6、指向函数指针数组的指针
int (*pfarr[4])(int, int);// 函数指针数组
int (*(*ppfarr)[4])(int, int) = &pfarr;
// ppfarr 是一个数组指针,指向的数组有四个元素;
// 指向的数组的每个元素的类型是一个函数指针int (*)(int, int)
7、void * 指针–无类型指针,可指向任何类型的地址
int a = 10;
char ch = 'dd';
void* p1 = &a;
void* p2 = &ch;
p1 = 0; 会报错
void 不能进行解引用操作,无类型指针,不能判断元素字节大小
p1++; 会报错
void* 不能进行加减运算操作,无类型指针,不能判断元素字节大小
本文介绍了C语言中不同类型的指针概念,包括整型数组、指针数组、数组指针、函数指针、函数指针数组的定义和使用。通过实例展示了如何声明、赋值和调用函数指针,以及如何利用函数指针实现简单的计算器功能。同时提到了void*指针的特性,它是无类型指针,可以指向任何类型的地址,但无法进行解引用或加减运算操作。
11万+

被折叠的 条评论
为什么被折叠?



