C语言函数与指针

C语言函数与指针

指针函数

函数指针是什么

指针函数:就是用到指针的函数,它是一个函数

  • 指针当作函数参数(如何修改实参)
    • 值传递
    • 址传递(一般用来修改普通变量和指针变量)
	#include<stdio.h>
void change1(int p)//传入的值无法被修改
{
	p = 111;
}
void change2(int* p)//可以修改传入地址所对应的值
{
	*p = 666;
}
int main()
{
	int num = 0;
	change1(num); 值传递
	printf("%d\n", num);
	change2(&num);址传递
	printf("%d\n", num);
	return 0;
}
  • 子函数想要修改普通变量实参,需要传入普通变量地址:一级指针,在修改的是普通变量
  • 子函数想要修改指针变量实参,需要传入指针变量地址: 二级指针,在修改的是一级指针
#include<stdio.h>
int num1 = 2002;
void change(int* p)
{
	*p = 666;//修改普通变量的值
}
void change1(int** p)
{
	*p = &num1;//修改了一级指针变量的值
}
int main()
{
	int num = 1992;
	int* p = &num;
	printf("%d\n", *p);
	change(&num);
	printf("%d\n", *p);
	change1(&p);
	printf("%d\n", *p);
	return 0;
}
  • 指针当作函数返回值
//关于返回的错误做法
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
int* returnPoint()
{
	int num = 100;		
	return &num;//要返回的是局部变量, 100会被回收,无法返回
}
int main()
{
	int* result = returnPoint();
	printf("%d\n", *result);
	printf("%d\n", *result);
	printf("%d\n", *result);
}
#include<stdio.h>
#include<malloc.h>
#include<assert.h>

int* returnPoint2(int* p)
{
	*p = 520;
	return p;
}
int* returnMalloc()
{
	//申请的是堆区内存,不会自动回收,能够被返回
	int* p = (int*)malloc(sizeof(int));
	assert(p);
	*p = 1314;
	return p;
}
int main()
{
	int count = 1;
	int* p = &count;
	int*  result = returnPoint2(p);
	printf("%d\n", *result);
	result = returnMalloc();
	printf("%d\n", *result);
	free(result);
	result = NULL;
	return 0;
}

函数指针

函数指针是什么

函数指针: 指向函数的指针,(函数名就是函数指针,&函数指针)

作用: 用来指向函数,调用函数

如何创建一个函数指针变量

用(*指针名)替换函数名 剩下照抄,形参名可以省略,这就是函数指针

int (*p)(int, int) = NULL;	//p 就是一个函数指针

通过和函数指针调用函数

  • 直接用指针名替换函数去调用函数
  • (*指针名)替换函数名调用函数
#include <stdio.h>
int max(int a, int b) 
{
	return a > b ? a : b;
}
int main()
{
	int (*p)(int, int) = NULL;
	p=max;
	//p=&max;//与上一行一样,写哪一种都行
	printf("%d\n", p(2, 3));
	printf("%d\n", max(2, 3));
	printf("%d\n", (*p)(2, 3));
	return 0;
}

函数指针一般是用在充当函数的参数

(专业术语叫做回调函数)

#include <stdio.h>
int max(int a, int b) 
{
	return a > b ? a : b;
}
int min(int a, int b) 
{
	return a > b ? b : a;
}
int sum(int a, int b) 
{
	return a + b;
}
//以函数指针为参数的函数
void print(int (*pFunc)(int, int), int a, int b) 
{
	printf("%d\n", pFunc(a, b));
}
int main()
{
	//回调函数显著特点: 一个函数的调用实现不同功能
	print(max, 1, 2);
	print(min, 1, 2);
	print(sum, 1, 2);
	//(*指针名) 替换函数名
	//void print(int (*pFunc)(int, int), int a, int b) 
	void (*p)(int (*)(int, int), int , int ) = NULL;
	p = print;
	p(max, 1, 2);
	p(min, 1, 2);
	p(sum, 1, 2);
	return 0;
}

typedef与函数指针

  • typedef基本用法
//No.1 给基本数据类型起别名
	typedef int INT;
	int a1 = 1;
	INT a2 = 1;			//等同于int  a2 = 1
	//typedef unsigned int  size_t;
	size_t a3 = 1;
	//No.2 数组起别名
	typedef int ARRAY[3];
	ARRAY arr = { 1,2,3 };					// int arr[3];   
	for (int i = 0; i < 3; i++) 
	{
		printf("%d\n", arr[i]);
	}
	ARRAY array[3] = { 1,2,3,4,5,6,7,8,9 };	// int array[3][3];
	typedef int A2D[3][3];
	A2D array2d;							// int array2d[3][3];
  • typedef与函数指针
void print(int(*p)(int, int), int a, int b) 
{
	printf("%d\n", p(a, b));
}
//和上面函数一样的
typedef int(*FUNC)(int, int);
void print2(FUNC p, int a, int b)   //FUNC p	 int(*p)(int, int);
{
	printf("%d\n", p(a, b));
}

万能指针充当函数指针

  • 万能指针: 使用必须做强制类型转换
  • 指针类型: 去掉变量名
#include <stdio.h>
void print()
{
	printf("xxxoooo\n");
}
int main()
{

	void* p = print;		//void (*Func)() -->去掉变量名得指针类型:void(*)()
	((void(*)())p)();
	//正常调用:p()
	//void*指针使用必须要做类型转换
	//((指针类型)p)()		((void(*)())p)()
	return 0;
}
  • 复杂函数指针–>通过函数指针推导函数原型(了解就行,一般面试题会考)
#include <stdio.h>

void printArray(int(*Array)[4], int row, int cols)//以数组指针为参数的函数
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			printf("%d\t", Array[i][j]);
		}
		printf("\n");
	}
}

void Func(void (*p)(int(*)[4], int, int), int(*Array)[4], int row, int cols)//以上面那个函数指针为参数的函数
{
	p(Array, row, cols);
}
typedef int(*ARRAY)[4];
ARRAY returnArray(int(*p)[4])//返回数组指针的函数
{
	return p;
}
//int(*p)[4] -->p的指针类型:int(*)[4]
void test()
{
	ARRAY(*F2)(int(*p)[4]) = NULL;
	//ARRAY returnArray(int(*p)[4])
}
int main()
{
	int array[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	printArray(array, 3, 4);
	//void Func(void (*p)(int(*)[4],int ,int ), int(*Array)[4], int row, int cols) 
	//(*指针名)替换函数,剩下照抄,形参名省略
	void (*pFunc)(void (*)(int(*)[4], int, int), int(*)[4], int, int);
	//void printArray(int(*Array)[4], int row, int cols)
	//void Func(void (*p)(int(*)[4], int, int), int(*Array)[4], int row, int cols)
	int aa = 1;
	pFunc = Func;
	pFunc(printArray, array, 3, 4);
	//typedef void (*F1)(int(*p)[4], int a, int b);
	//void (*pFunc)(F1 f, int(*)[4], int, int);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值