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 = #
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 #//要返回的是局部变量, 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;
}