目录
1.函数指针
int (*p)(int ,int );
当这个指针指向一个函数的首地址时,就调用这个函数
2.回调函数
函数指针最常用的地方在于将一个函数作为参数传递给另一个函数的时候要用函数指针
将一个函数作为参数传递给另外一个函数,将这个函数称为回调函数。
#include<stdio.h>
//两数相加
int add(int a,int b)
{
return a+b;
}
//两数相减
int sub(int a,int b)
{
return a-b;
}
//两数相乘
int cheng(int a,int b)
{
return a*b;
}
//两数相除
int ave(int a,int b)
{
return a/b;
}
//两数取余
int yu(int a,int b)
{
return a%b;
}
int caculator(int (*p)(int,int),int a,int b)//将函数指针作为一个函数的入参,这是回调函数
{
return p(a,b);
}
int main()
{
int a = 20;
int b = 10;
int (*p)(int,int);//定义一个函数指针,这个指针指向的函数返回值是int型,入参是两个int型
int (*q)(int ,int);//相同类型的指针可以相互赋值
p = add;//函数名表示函数的首地址
//两数相加返回的函数
int ret = caculator(add,a,b);
printf("%d\n",ret);
//两数相减返回的函数
ret = caculator(sub,a,b);
printf("%d\n",ret);
//两数相乘返回的函数
ret = caculator(cheng,a,b);
printf("%d\n",ret);
//两数相除返回的函数
ret = caculator(ave,a,b);
printf("%d\n",ret);
//两数取余返回的函数
ret = caculator(yu,a,b);
printf("%d\n",ret);
return 0;
}
3.函数指针数组
函数指针数组的本质是一个数组,数组中存储的是函数的首地址
返回值类型 (*函数指针变量名[函数指针的个数]) (形参列表)
int (*p[10])(int,int)
以下是加减乘除取余的函数,然后将这些函数首地址存入数组中,再用for循环依次调用
#include<stdio.h>
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int mod(int a, int b);
int main()
{
int a = 20;
int b = 3;
//定义一个函数指针数组
//数组有五个元素,数组中的每个元素都是一个函数指针,指针指向一个函数的首地址
//函数的返回值 是int型,有两个int型入参
int (*p[5])(int, int) = {add, sub, mul, div, mod};
for(int i = 0; i < 5; i++)
{
printf("%d\n", p[i](a, b));
}
return 0;
}
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return a / b;
}
int mod(int a, int b)
{
return a % b;
}
4. 只读指针变量
只读指着变量不能被重新赋值,地址不能被修改,但是值可以被修改
数据类型 *const 变量名 = 变量的地址;
int *const p = &a;
用const修饰的指针变量地址不能被修改,但是它所对应的地址的值可以被修改
#include<stdio.h>
int main()
{
int a = 20;
int b = 10;
int *const p = &a; //只读指针变量的定义
printf("%p\n", p);
printf("%d\n", *p);
// p = &b;//用const修饰的指针变量地址不能被修改
// printf("%p\n", p);
// printf("%d\n", *p);
*p = 100;//用const修饰的指针变量它指向地址的值是可以改变的
printf("%p\n", p);
printf("%d\n", *p);
return 0;
}
5.只读变量指针
只读变量指针是能修改指针指向的地址,不能修改指针指向的值
数据类型 const *变量名 = 变量的地址;
int const *p = &a;
它指向了一个地址,就可以把这个地址的值当成一个用const修饰的变量的值,不可以进行修改,但是可以修改地址,让它指向另一个变量
//只读变量指针,与只读指针变量相反
//它的地址可以被修改,但是值只能读不可以改
#include<stdio.h>
int main()
{
int a = 20;
int b = 10;
//只读变量指针,从const往左看,休先结合int,说明是只读指针变量
int const * p = &a; //定义一个只读变量的指针
printf("%d\n",*p);
printf("%p\n",p);
printf("%d\n",a);
p = &b;//用const修饰的指针变量地址可以被修改,但是它所对应的地址的值被修改
printf("%d\n",*p);
printf("%p\n",p);
printf("%d\n",b);
printf("%d\n",a);
// *p = 200; // 不能修改只读变量指针的值
// printf("%d",*p);
// printf("%p",p);
// printf("%d",a);
return;
}
只读变量
数据类型 const *const 变量名 = 变量的地址;
int const *p = &a;
如果去修改它指向的地址或者修改值,就会报错
6. malloc
malloc是一个动态的空间,需要程序员自己分配,用完要释放掉,并将指针指向NULL
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *p;
int a = 10;//系统自动分配,申请的空间在栈上
p = malloc(512);//需要程序员自己分配,用完释放掉,申请的空间在堆上
if(p == NULL)
{
return -1;
}
*p = 100;
printf("%d\n", *p);
free(p);
p = NULL;
return 0;
}
7.万能指针
万能指针 void *(也称空类型指针)
void *指针可以指向任意变量的内存空间,但是在使用的时候,就需要将指针类型强制转换成对应的指针类型
#include<stdio.h>
int main()
{
int a = 4396;
char c = 'k';
float b = 4396.77;
double d = 777.777777;
void *p;
p = &a;
*(int *)p = 777;
printf("%d\n", *(int *)p);
p = &c;
*(char *)p = '*';
printf("%c\n", *(char *)p);
p = &b;
*(float *)p = 77.7777;
printf("%.4f\n", *(float *)p);
return 0;
}