函数指针
函数指针是指向函数的指针变量。
通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。
函数指针可以像一般函数一样,用于调用函数、传递参数。
函数指针变量的声明:
typedef int (*fun_ptr)(int,int); // 声明一个指向同样参数、返回值的函数指针类型
示例1
#include <stdio.h>
int max(int x, int y)
{
return x > y ? x : y;
}
int main(void)
{
/* p 是函数指针 */
int (* p)(int, int) = & max; // &可以省略
int a, b, c, d;
printf("请输入三个数字:");
scanf("%d %d %d", & a, & b, & c);
/* 与直接调用函数等价,d = max(max(a, b), c) */
d = p(p(a, b), c);
printf("最大的数字是: %d\n", d);
return 0;
}
执行
请输入三个数字:1 2 3
最大的数字是: 3
回调函数
函数指针作为某个函数的参数
函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。
简单讲:回调函数是由别人的函数执行时调用你实现的函数。
实例2
实例中 populate_array 函数定义了三个参数,其中第三个参数是函数的指针,通过该函数来设置数组的值。
实例中我们定义了回调函数 getNextRandomValue,它返回一个随机值,它作为一个函数指针传递给 populate_array 函数。
populate_array 将调用 10 次回调函数,并将回调函数的返回值赋值给数组。
#include <stdlib.h>
#include <stdio.h>
// 回调函数
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void)){
for (size_t i=0; i<arraySize; i++)
array[i] = getNextValue();
}
// 获取随机值
int getNextRandomValue(void){
return rand();
}
int main(void){
int myarray[10];
populate_array(myarray, 10, getNextRandomValue);
for(int i = 0; i < 10; i++) {
printf("%d ", myarray[i]);
}
printf("\n");
return 0;
}
运行
16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709
链表
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
LinkList CreateList(int n)
{
LinkList L,p,q;
int i;
L=(LNode*)malloc(sizeof(LNode));
if(!L)return 0;
L->next=NULL;
q=L;
for(i=1;i<=n;i++)
{
p=(LinkList)malloc(sizeof(LNode));
printf("请输入第%d个元素的值:",i);
scanf("%d",&(p->data));
p->next=NULL;
q->next=p;
q=p;
}
return L;
}
void print(LinkList h)
{
LinkList p=h->next;
while(p!=NULL){
printf("%d ",p->data);
p=p->next;
}
}
int main()
{
LinkList Head=NULL;
int n;
scanf("%d",&n);
Head=CreateList(n);
printf("刚刚建立的各个链表元素的值为:\n");
print(Head);
printf("\n\n");
system("pause");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct LNode{
int data;
struct LNode *next;
}L;
//创建节点
L *creat_node(int data){
L *p=malloc(sizeof(L));
if(NULL==p){
printf("malloc error!\n");
return NULL;
}
memset(p,0,sizeof(L));
p->data=data;
p->next=NULL;
return p;
}
//尾插法
void tail_insert(L *pH,L *new){
L *p=pH;
while(NULL!=p->next){
p=p->next;
}
p->next=new;
}
//打印链表
void print_list(L *pH){
L *p=pH;
while(NULL!=p->next){
p=p->next;
printf("data=%d\n",p->data);
}
}
//反向输出链表
void trave_list(L *pH){
L *p=pH->next;
L *pBack;
while(NULL!=p->next) {
pBack=p->next;
if(p==pH->next){
p->next=NULL;
}else{
p->next=pH->next;
}
pH->next=p;
p=pBack;
}
top_insert(pH,p);
}
//头插法
void top_insert(L *pH,L *new){
L *p=pH;
new->next=pH->next;
pH->next=new;
}
int main(){
int i,n,j;
L *head=creat_node(0);
printf("请输入想要创建节点的个数:");
scanf("%d",&n);
for(i=1;i<=n;i++){
printf("第%d个节点的数据:",i);
scanf("%d",&j);
tail_insert(head,creat_node(j));
}
printf("***************************\n");
printf("刚刚创建的链表:\n");
print_list(head);
trave_list(head);
printf("***************************\n");
printf("反向输出的链表:\n");
print_list(head);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <malloc.h>
typedef struct LNode{
int data ;
struct LNode *next; // 后继
struct LNode *prior; // 前驱
}LNode, *LinkList;
LinkList CreateList(int n){
// p是当前正在声明的链表节点
// q是前一个已经完成声明的链表节点
// L是第一个链表元素
LinkList L,p,q;
int i;
// 额外声明一个节点, 保存第一个链表节点
L = (LNode*)malloc(sizeof(LNode));
if(!L)
return 0 ;
for (i=1; i<=n; i++){
p = (LinkList)malloc(sizeof(LNode));
printf("input %dth value.\n",i);
scanf("%d",&(p->data));
// 对于第一个链表元素 只需要赋值,其前驱后继都为空,进行保存
if (i == 1){
p -> next = NULL;
p -> prior = NULL;
L = p ;
q = p ;
}
// 对于后继的链表节点,将其前驱置为q,将q的后继置为p
else{
p -> next = NULL ;
p -> prior = q ;
q -> next = p;
q = p;
}
// 如果是最后一个链表节点,将其与第一个元素连接。
if (i == n){
L -> prior = q ;
q -> next = L ;
}
}
return q ;
}
void print(LinkList p,int n){
int i =1 ;
while (i <= n){
printf("%d ", p->data);
if ( p -> prior != NULL) {
printf("prior = %d\n",p->prior->data);
}
p = p -> next;
i ++ ;
}
}
int main(){
LinkList Head = NULL;
int n ;
printf("input the length of the linking table.\n");
scanf("%d",&n);
Head = CreateList(n);
printf("the value of link table:\n");
print(Head,n);
return 0 ;
}
运行: 请输入想要创建节点的个数:4 第1个节点的数据:1 第2个节点的数据:2 第3个节点的数据:3 第4个节点的数据:4 *************************** 刚刚创建的链表: data=1 data=2 data=3 data=4 *************************** 反向输出的链表: data=4 data=3 data=2 data=1