C语言指针的一些知识点
指针
1、指向对象的指针
int *p = new int(10);
delete p;
2、指向数组的指针
int *p = new int[n];
delete[]p;
3、指向指针的指针
int *p = new (int)[1];
p[0] = new int[6];
delete[]p[0];
指针数组和数组指针的概念
1、指针数组
实际上,是一个数组,数组中的每一个元素存放的都是一个指针类型的元素。
int *arr[3]; //arr是一个含有8个int*指针的数组
int* | int* | int* |
---|
2、数组指针
实际上,是一个指针,指向一个数组。
int (*arr2)[3]; //指针arr是一个指向大小为8的数组的指针
int | int | int |
---|
看文字很苍白,举个例子,代码一看就懂了。
//定义一个二维数组三行四列
int a[3][4] = {{0, 1, 2, 3}, {8, 9, 10, 11}, {7, 6, 5, 4}};
//定义一个数组指针,指向数组a
int (*arr3)[4] = a;
那么分析:
(*arr3 + 1): 表示第0行第1列元素的地址。
*(*arr3 + 1):表示第0行第1列元素的值,取值为1
*(arr3 + 1): 表示第1行第0列元素的地址。
**(arr3 + 1): 表示第1行第0列元素的值,取值为8
**arr3 +5 : 表示表示第0行第0列元素的值加5
代码就不一一敲了,感兴趣的还是要自己动手试试。
函数指针,函数指针数组,函数指针数组的指针
定义:如果在程序中定义一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,
这段存储空间的首地址称为这个函数的地址
,而函数名表示的就是这个地址。那么用来存储这个地址的指针,就叫做函数指针
。
ok,看到这里或许你只有一个模糊的概念,那咱们上代码,看完代码就了然了。
void test(char *str)
{
printf("%s\n",str);
}
void test2(char *str)
{
printf("%s\n", str);
}
int main()
{
// 定义函数指针pfun, pfun2; (char *)表示函数传参的类型
void (*pfun)(char *) = test;
void (*pfun2)(char *) = test2;
//定义一个函数指针数组pfunArr
void (*pfunArr[2])(char *);
pfunArr[0] = pfun;
pfunArr[1] = pfun2;
//下面这种写法也行,因为函数名就是函数首地址
/*
pfunArr[0] = test;
pfunArr[1] = test2;
*/
//定义一个指向函数指针数组的指针ppfunArr
void *(*ppfunArr[2])(char *) = &pfunArr;
//调用
char msg[10] = "hello";
//如果要通过ppfunArr来调用test2(), 应该有两种方法
//(1)
(*(*ppfunArr[1]))(msg);
//(2)
(*(*ppfunArr + 1))(msg);
return 0;
}
搞个图看一下会跟清晰
应该画个箭头的,可是windows自带的画图软件,我实在是用的不太熟练,凑合看吧
回调函数
定义:函数test()调用函数test2()时,通过参数给test2()传递了另一个函数test3()的指针,在函数test2()执行的过程中,test2()调用了test3(),这个动作就叫做回调。
回调函数最大的好处是解耦
。
注意:主函数将回调函数作为参数传递给库函数,只要改变参数就可以实现不同的功能,而不必修改库函数,其本质就是函数指针的传递。
代码搞起来
int CallBack1(int x)
{
printf("%d\n", x);
}
int CallBack2(int x)
{
printf("%d\n", (x+2));
}
int CallBack3(int x)
{
printf("%d\n", (x+3));
}
int Handle(int y, int (*CallBack)(int)) //函数指针作为参数
{
CallBack(y); //调用回调函数
}
int main()
{
int a = 1, b = 2, c = 3;
Handle(a, Callback1);
Handle(b, Callback2);
Handle(c, Callback3);
]
好了,看到这里,你是不是对于指针的应用有了更深一层的感悟了,如果没有的话,就是写的不够,赶快去写代码吧!!!
有问题欢迎大家留言哦,一起交流更有助于提高。