指针的基础进阶
Posted 宣哲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针的基础进阶相关的知识,希望对你有一定的参考价值。
指针的进阶应用
一、指向函数的指针(函数指针)
1、什么是函数指针?
首先,函数是会占内存空间的。在程序中定义了一个函数,在编译时,编译系统会为函数代码分配一段存储空间,这段存储空间就是函数的地址,这段地址的起始地址(又称入口地址)就称为这个函数的指针(或函数的首地址)。
既然函数也有地址,那么我们能不能用一个指针指向函数的地址呢?
既然都是地址,那么就可以用指针指向它。
指向整型变量地址的指针是整型指针,指向字符型变量地址的指针是字符型指针,指向单精度变量地址的指针是float型指针,那指向函数的指针是什么指针呢?
这就是接下来要接触到的函数指针了。
2、函数指针的定义
//简单来说,函数指针就是指向函数的指针。
//定义函数指针的一般格式:数据类型 (*函数名)(函数参数列表);
int (*funp)(int,char);
//定义了一个指针函数,用于指向返回值类型为int型、函数参数为(int,char)型的函数
3、指针的初始化及使用
int funsum(int x,int y)
//求和函数
return x+y;
int funmax(int x,int y)
//求最大值函数
return x>y?x:y;
int funmin(int x,int y)
//求最小值函数
return x<y?x:y;
int main()
int (*funp)(int,int)=funsum; //定义一个函数指针funp,初始化赋值指向函数funsum
int a=10,b=20,c; //函数指针有以下两个赋值方式和两种调用方式
c=(*funp)(a,b); //通过函数指针funp调用函数funsum,(*)区分funp是个函数指针
funp=&funmax; //改变函数指针funp的指向,&取函数地址,使其指向函数funmax
c=funp(a,b); //此时是通过函数指针funp调用函数funmax
funp=funmin; //改变函数指针funp的指向,可以省略&取址符,使其指向函数funmin
c=funp(a,b); //通过函数指针funp调用函数funmin
return 0;
4、使用函数指针作为函数参数(回调函数)
回调函数:通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就称这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
int funsum(int x,int y)
//求和函数
return x+y;
int funmax(int x,int y)
//求最大值函数
return x>y?x:y;
//回调函数:在函数里运用函数指针间接调用其他函数
int center(int x,int y,int (*fun)(int,int))
//这里的函数形式参数fun为函数指针类型
return (fun)(x,y); //可以通过函数fun调用其所指向的函数
typedef int (a)(int,int);
center(1,2,funsum); //调用时直接以函数名作为函数参数
center(10,20,funmax);
实例:简易计算器
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int sum(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 mub(int a, int b)
return a / b;
int center(int x,int y,int (*f)(int ,int))
return f(x, y);
void function()
while (1)
int (*funp)(int, int) = NULL;
int n, a, b;
printf("输入0:退出\\t 输入1:相加\\t 输入2:相减\\t 输入3:相乘\\t 输入4:相除\\n");
scanf("%d", &n);
switch (n)
case 0: exit(0);
case 1: funp = sum; break;
case 2: funp = sub; break;
case 3: funp = mul; break;
case 4: funp = mub; break;
printf("请输入值\\n");
scanf("%d %d", &a, &b);
printf("%d \\n", center(a, b, funp));
int main()
function();
system("pause");
return 0;
5、使用typedef给函数指针取别名
typedef int (*funp)(int,int); //给 int (*)(int,int)类型的函数指针取一个别名为funp,这里跟一般取别名不同
funp *p1; //用别名funp定义(*)(int,int)类型的函数指针p1
p1 = sum; //函数指针p1指向函数sum
p1(1,2); //通过函数指针p1调用函数
//#define无法给复杂的类型取别名,但带参宏可以:#define pf(n) int (*n)(int ,int)
//(不推荐)
pf(q); //用带参宏定义函数指针q
q = sum;
q(1,2);
6、指针函数与函数指针的区别
所谓的指针函数,其本质上是个函数,是返回值为指针类型(地址)的函数。
所谓的函数指针,其本质上是个指针,是指向函数的指针。
int* f(int* x) //指针函数
return x;
int* (*fp)(int*); //函数指针
fp = f; //函数指针指向指针函数
二、指针数组和数组指针
1、指针数组
(1)什么指针数组
所谓指针数组,其本质上是一个数组,数组中的每一个元素都是指针类型的,都可以指向对应数据类型的地址。
(2)指针数组的定义
定义的一般格式:数据类型 *指针数组名[数组元素个数];
int *p[6]; //定义一个指针数组,有6个元素,分别可以指向六个地址
(3)指针数组的使用
//使用指针数组指向二维字符数组
char arr[10][10],*p[10];
for(int i=0;i<10;i++)
p[i]=arr[i]; //指针数组p中的每个元素指向二维数组arr的每一行
for(int i=0;i<10;i++)
scanf(“%s”,p[i]); //使用指针数组p给二维数组arr赋值
for(int i=0;i<10;i++)
printf(“%s”,p[i]); //使用指针数组p输出二维数组arr
//使用指针数组存储字符串的形式代替二维字符数组,达到省空间的目的
char *p[6]=“abc”,”123456”,”abcdefg”,”hello world!”,”xiaowei”,”x”
2、数组指针
(1)什么是数组指针?
所谓的数组指针,其本质上是一个指针,是一个用于指向数组地址的指针.
(2)数组指针的定义
定义的一般格式:数据类型 (*指针变量名)[所指向数组的大小];
int a[3][4];
int (*p)[4]; //定义一个整型数组指针p,用于指向大小为4的整型数组
p=a; //将整型数组指针p指向二维数组a的第一行
(3)数组指针的使用
//使用数组指针完成二维数组的输入和输出
int a[3][6];
int (*p)[6];
p = a;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 6;j++)
scanf("%d",&p[i][j]);
for (int i = 0; i < 3; i++)
for (int j = 0; j < 6;j++)
printf("%d\\t",p[i][j]);
用数组指针用于接受二维数组的地址,将二维数组作为函数参数传递需要用到数组指针接受:
void Print(int (*arr)[4],int n,int m) //也可以写成 Print(int arr[][4],int n,int m)
for(int i = 0;i<n;i++)
for(int j=0;j<m;j++)
printf("%d\\t",arr[i][j]);
printf("\\n");
int arr[3][4] = 1,2,3,4,5,6,7,8,9,10,11,12;
Print(arr,3,4);
或者也可以不用函数指针(不推荐,不好用)
void Print1(int* arr,int n)
for(int j=0;j<n;j++)
printf("%d\\t",arr[j]);
int arr[3][4] = 1,2,3,4,5,6,7,8,9,10,11,12;
Print1(&arr[0][0],12);//传入二维数组的首地址,以一维数组形式输出
(4)数组指针的移动
p++; //移动一整行
*(*(p+i)+j) //可以把数组指针理解成为一个二级指针,通过两次解引用得到元素值
p[i][j]; //指针带数组下标的形式访问数组元素
int arr[3] = 1,2,3;
int(*q)[3] = &arr; //指向大小为3的数组
三、指针常量与常量指针
1、指针常量
指针常量就是指向常量的指针
const int *p;
它的指向能够被改变,但是不能够改变值
2、常量指针
常量指针就是指针的指向不能够被改变的指针
int * const p;
它的能够改变值,但是不能够改变指向
示例:
int a = 10,b=20;
const int *p;
p = &a;
printf("%d\\n",*p);
//*p=30; //值不能被改变
p = &b; //可以改变指向
printf("%d\\n",*p);
int * const q = &a; //必须初始化指针指向
*q = 30; //可以改变值
//q = &b; //不能改变指向
printf("%d\\n",*q);
指针常量和常量指针一般用于函数参数的传递,为了使在函数使用中不改变值以及指针的指向。
const int * const p=&a;//指针常量指针,都不能改变
以上是关于指针的基础进阶的主要内容,如果未能解决你的问题,请参考以下文章