一、指针函数
1、定义
指针函数是指带指针的函数,即本质是一个函数。函数返回类型是某一类型的指针

函数返回值类型 函数名(参数表)
int * f(int x,int y);
//函数返回值类型是int *,即返回一个地址,该地址指向int型数据
//主调函数中必须用int *型变量来接收该函数
//函数名为f,两个形参为x y

2、举例
float *fun();
float *p;
p = fun(a);
备注:1、指针函数一定有返回值,且该返回值是一个地址
2、在函数调用中,指针函数实际是返回一个地址给调用函数
3、指针函数和函数指针最简单的辨别方式就是看函数名前面的*有没有被()包含,如果被包含就是函数指针,反之则是指针函数。

3、应用
当然了,由于返回的是一个地址,所以类型说明符一般都是int。
函数返回的是一个地址值,经常使用在返回数组的某一元素地址上。

int * GetDate(int wk,int dy);

main()
{
int wk,dy;
do
{
printf(Enter week(1-5)day(1-7)\n);
scanf(%d%d,&wk,&dy);
}
while(wk<1||wk>5||dy<1||dy>7);
printf(%d\n,*GetDate(wk,dy));
}

int * GetDate(int wk,int dy)
{
static int calendar[5][7]=
{
{1,2,3,4,5,6,7},
{8,9,10,11,12,13,14},
{15,16,17,18,19,20,21},
{22,23,24,25,26,27,28},
{29,30,31,-1}
};
return &calendar[wk-1][dy-1];
}
程序应该是很好理解的,子函数返回的是数组某元素的地址。输出的是这个地址里的值。

二、函数指针
1、定义
函数指针是指向函数的指针变量,即本质是一个指针变量。
  int (*f) (int x); /* 声明一个函数指针 */
  f=func; /* 将func函数的首地址赋给指针f */

备注:1、*和函数名f外面的括号改变了默认的运算符优先级;
如果没有这个括号,就变成了一个指针函数。对比:
int * f(int x); //指针函数
int (*f)(int x); //函数指针
2、这里的函数名f本质上应叫指针变量名;
这个特殊的指针指向了一个函数,即把函数首地址赋给该指针;
该函数返回值为int型;
3、语句定义了一个指针,同时定义了一个函数

2、举例
(1)指针赋值
void (*fptr)();
把函数的地址赋值给函数指针,可以采用下面两种形式:
fptr=&Function;
fptr=Function; //&可以不要,Function是函数名,代表函数首地址
(2)函数调用
x=(*fptr)();
x=fptr();
第二种格式看上去和函数调用无异。但是有些程序员倾向于使用第一种格式,因为它明确指出是通过指针而非函数名来调用函数的。

3、程序举例
void (*funcp)();
void FileFunc(),EditFunc();

main()
{
funcp=FileFunc;
(*funcp)();
funcp=EditFunc;
(*funcp)();
}

void FileFunc()
{
printf(FileFunc\n);
}

void EditFunc()
{
printf(EditFunc\n);
}

程序输出为:
FileFunc
EditFunc

主要的区别是一个是指针变量,一个是函数。使用时务必搞清楚

三、指针的指针
指针的指针看上去有些令人费解。它们的声明有两个星号。例如:
char ** cp;
如果有三个星号,那就是指针的指针的指针,四个星号就是指针的指针的指针的指针,依次类推。当你熟悉了简单的例子以后,就可以应付复杂的情况了。当然,实际程序中,一般也只用到 二级指针,三个星号不常见,更别说四个星号了。
指针的指针需要用到指针的地址。
char c='A';
char *p=&c;
char **cp=&p;
通过指针的指针,不仅可以访问它指向的指针,还可以访问它指向的指针所指向的数据。下面就是几个这样的例子:
char *p1=*cp;
char c1=**cp;
你可能想知道这样的结构有什么用。利用指针的指针可以允许被调用函数修改局部指针变量和处理指针数组。

void FindCredit(int **);

main()
{
int vals[]={7,6,5,-4,3,2,1,0};
int *fp=vals;
FindCredit(&fp);
printf(%d\n,*fp);
}

void FindCredit(int ** fpp)
{
while(**fpp!=0)
if(**fpp<0) break;
else (*fpp)++;
}

首先用一个数组的地址初始化指针fp,然后把该指针的地址作为实参传递给函数FindCredit()。FindCredit()函数通过表达式**fpp间接地得到数组中的数据。为遍历数组以找到一个负值,FindCredit()函数进行自增运算的对象是调用者的指向数组的指针,而不是它自己的指向调用者指针的指针。语句(*fpp)++就是对形参指针指向的指针进行自增运算的。但是因为*运算符高于++运算符,所以圆括号在这里是必须的,如果没有圆括号,那么++运算符将作用于二重指针fpp上。

四、指向指针数组的指针
指针的指针另一用法旧处理指针数组。有些程序员喜欢用指针数组来代替多维数组,一个常见的用法就是处理字符串。

char *Names[]=
{
Bill,
Sam,
Jim,
Paul,
Charles,
0
};

main()
{
char **nm=Names;
while(*nm!=0) printf(%s\n,*nm++);
}

先用字符型指针数组Names的地址来初始化指针nm。每次printf()的调用都首先传递指针nm指向的字符型指针,然后对nm进行自增运算使其指向数组的下一个元素(还是指针)。注意完成上述认为的语法为*nm++,它首先取得指针指向的内容,然后使指针自增。
注意数组中的最后一个元素被初始化为0,while循环以次来判断是否到了数组末尾。具有零值的指针常常被用做循环数组的终止符。程序员称零值指针为空指针(NULL)。采用空指针作为终止符,在树种增删元素时,就不必改动遍历数组的代码,因为此时数组仍然以空指针作为结束。

转载于:https://www.cnblogs.com/shuaishuaidefeizhu/p/5880177.html

初论函数指针、指针函数、指针的指针相关推荐

  1. C语言项目实战:24点游戏计算器(基于结构体、指针、函数、数组、循环等知识点)

    文章目录 C语言项目实战:24点游戏计算器(基于结构体.指针.函数.数组.循环等知识点) 前言:24点游戏计算器的规则如下 一.项目的创建标 1.选择项目 2.输入项目名称和路径 3.创建头文件Mai ...

  2. C++ 笔记(14)— 指针(指针声明、取地址、取值、new/delete、NULL指针、指针运算、指针数组、数组指针、指针传递给函数、从函数返回指针)

    1. 声明指针 指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址.就像其他变量或常量一样,您必须在使用指 针存储其他变量地址之前,对其进行声明. 指针变量声明的一般形式为: type * ...

  3. C++ 笔记(13)— 函数(函数声明、函数定义、函数调用[传值、指针、引用]、函数参数默认值、函数重载)

    每个 C++ 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数. 1. 函数声明 函数声明告诉编译器函数的名称.返回类型和参数.函数声明包括以下几个部分: ret ...

  4. Go 学习笔记(13)— 指针定义、指针特点、空指针、指针数组、指向指针的指针、指针作为函数入参

    1. 复合数据类型 Go 语言基本的复合数据类型有指针.数组.切片.字典.通道.结构和接口等.格式如下: * pointerType // 指针类型, [n]elementType // 数组类型, ...

  5. C指针7:指针作为函数返回值

    C语言允许函数的返回值是一个指针(地址),我们将这样的函数称为指针函数.下面的例子定义了一个函数 strlong(),用来返回两个字符串中较长的一个: #include <stdio.h> ...

  6. C++ 函数参数传递:传值,传指针,传引用

    PS:首先理解形参   实参概念.形参是在函数定义的括号内定义的专用变量,它们的目的是保存按实参传递给它们的信息,实参被列在函数调用语句的括号内. int func(int x)//x是形参 {ret ...

  7. 双重指针作为函数参数的妙用

    双重指针作为函数参数,可以在函数函数内部修改外部指针的值.主要用法包括: 1. 在函数内部分配内存,作为函数参数返回: 2. 在函数内部设置指针为空: #include <stdio.h> ...

  8. 使用指针做函数返回值

    使用指针做函数返回值 1.当使用指针做为函数的返回值时,主函数处的char *p;将获得调用函数char *pf;的值,即一个地址值,如oxAE72.此时需要我们注意的是该地址值所指向的空间是否存在( ...

  9. C++利用二级指针做函数形参来进行修改实参的实例分析

    在学C/C++的时候,我们都会了解到一级指针,int* i = NULL;   和二级指针int ** pp = NULL; 但是具体的一些应用我们可能很难理解,如果我们要取int*的地址,我们就需要 ...

  10. 【C++】用指针做函数参数

    此篇博客程序运行环境为:VS2017!!! 函数的参数不仅可以是整型.浮点型.字符型等数据,还可以是指针类型. 它的作用是将一个变量的的地址传给被调用函数的形参. e.g. 输入两个数,按由大到小顺序 ...

最新文章

  1. RocketMq 的最佳实践
  2. TensorFlow安装 通过Anaconda Prompt Win10 64位安装 cpu版 tensorflow
  3. mysql数据库有几种连接方法_几种常见的数据库连接方法
  4. Matlab:成功解决 Inner matrix dimension must agree
  5. 如何修改Vue打包后文件的接口地址配置
  6. docker+jenkins+maven+svn
  7. AC日记——简单密码 openjudge 1.7 10
  8. Linux网络服务器epoll模型的socket通讯的实现(一)
  9. NLP学习—17.基于BM25、tfidf和SIF的检索系统实现
  10. Hibernate的HibernateUtil类补充
  11. UIView animateWithDuration 使用详解
  12. blob 在线解码_roon、NAS图文全攻略 | 试听欧博旗舰RDS1电池数字界面转盘+旗舰RDB1电池解码器(三)。...
  13. 谷歌翻译器 6.2.620 电脑版
  14. et200s模块接线图讲解_西门子S7-1500使用ET200S 1SI模块实现自由口通信
  15. spring 实现小程序抖音去水印后台
  16. 政务大数据的上下文范围
  17. html5+连连看+抽奖,html 大转盘抽奖
  18. ESP32设备驱动-MicroSD Card驱动
  19. NDM(Neat Download Manager)删除所有下载记录
  20. Android项目开发教程之OpenGL ES

热门文章

  1. mysql galaxy_优化mysql
  2. java 网络实验_Java实验五网络编程与安全
  3. 控制工程matlab实验报告小结,控制工程MATLAB实验报告.doc
  4. Java设计模式(代理模式-模板方法模式-命令模式)
  5. 本是同根生,相煎何太急?
  6. 高压桥电路-驱动旧式电话机振铃
  7. python mac地址转换_Python MAC地址 获取,过滤,转换 Python MYSQL 数据获取,比较
  8. windows 将python源代码加密_对源代码进行pyd加密
  9. oracle mysql 适配器_Oracle协议适配器错误解决办法
  10. 西安交通大学2019计算机复试方案,西安交通大学2019年招收硕士研究生复试体检通知...