【时时三省】(C语言基础)对被调用函数的声明和函数原型

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省

在一个函数中调用另一个函数(即被调用函数)需要具备如下条件

( 1 )首先被调用的函数必须是已经定义的函数(是库函数或用户自己定义的函数),但仅有这一条件还不够。

( 2 )如果使用库函数,应该在本文件开头用# include指令将调用有关库函数时所需用到的信息“包含”到本文件中来。

例如:

# include < stdio.h >

其中,“stdio.h”是一个“头文件”。在stdio.h文件中包含了输入输出库函数的声明。如果不包含“stdio.h”文件,就无法使用输入输出库中的函数。同样,使用数学库中的函数,应该用# include < math.h >。h是头文件所用的后缀,表示是头文件(headerfile)。

( 3 )如果使用用户自己定义的函数,而该函数的位置在调用它的函数(即主调函数)的后面(在同一个文件中),应该在主调函数中对被调用的函数作声明(declaration)。声明的作用是把函数名、函数参数的个数和参数类型等信息通知编译系统,以便在遇到函数调用时,编译系统能正确识别函数并检查调用是否合法。

例题:

输入两个实数,用一个函数求出它们之和。

解题思路:

两个数相加的算法很简单。现在用add函数实现它。首先要定义add函数,它为float型,它应有两个参数,也应为float型。特别要注意的是:要对add函数进行声明。

编写程序:

运行结果: 

 

这是一个很简单的函数调用,函数add的作用是求两个实数之和,得到的函数值也是实型。程序第3行是对被调用的add函数作声明:

float add ( float x , float y ) ;

从程序可以看到:main函数的位置在add函数的前面,而程序进行编译时是从上到下逐行进行的,如果没有对函数add的声明,当编译到程序第7行时,编译系统无法确定add是不是函数名,也无法判断实参( a和b )的类型和个数是否正确,因而无法进行正确性的检查。

如果不作检查,在运行时才发现实参与形参的类型或个数不一致,出现运行错误。但是在运行阶段发现错误并重新调试程序,是比较麻烦的,工作量也较大。应当在编译阶段尽可能多地发现错误,随之纠正错误。

现在,在函数调用之前对add作了函数声明。因此编译系统记下了add函数的有关信息,在对“c = add ( a,b );”进行编译时就“有章可循”了。编译系统根据add函数的声明对调用add函数的合法性进行全面的检查。如果发现函数调用与函数声明不匹配,就会发出出错信息,它属于语法错误。用户根据屏幕显示的出错信息很容易发现和纠正错误。

可以发现,函数的声明和函数定义中的第1行(函数首部)基本上是相同的,只差一个分号(函数声明比函数定义中的首行多一个分号)。因此写函数声明时,可以简单地照写已定义的函数的首行,再加一个分号,就成了函数的“声明”。

函数的首行(即函数首部)称为函数原型( function prototype )。为什么要用函数的首部来作为函数声明呢?这是为了便于对函数调用的合法性进行检查。因为在函数的首部包含了检查调用函数是否合法的基本信息(它包括了函数名、函数值类型、参数个数、参数类型和参数顺序),在检查函数调用时要求函数名、函数类型、参数个数和参数顺序必须与函数声明一致,实参类型必须与函数声明中的形参类型相同(或赋值兼容,如实型数据可以传递给整型形参,按赋值规则进行类型转换)。否则就按出错处理。这样就能保证函数的正确调用。

说明:

使用函数原型作声明是C的一个重要特点。用函数原型来声明函数,能减少编写程序时可能出现的错误。由于函数声明的位置与函数调用语句的位置比较近,因此在写程序时便于就近参照函数原型来书写函数调用,不易出错。实际上,在函数声明中的形参名可以省写,而只写形参的类型,如上面的声明可以写为

float add ( float , float );/ /不写参数名,只写参数类型

编译系统只关心和检查参数个数和参数类型,而不检查参数名,因为在调用函数时只要求保证实参类型与形参类型一致,而不必考虑形参名是什么。因此在函数声明中,形参名可写可不写,形参名是什么都无所谓,如:

float add ( float a , float b );/ /参数名不用x,y,而用a,b。合法

根据以上的介绍,函数声明的一般形式有两种,分别为

( 1 )函数类型函数名(参数类型1参数名1,参数类型2参数名2 ,...,参数类型n参数名n );

( 2 )函数类型函数名(参数类型1,参数类型2,...,参数类型n );

有些专业人员喜欢用不写参数名的第(2 )种形式,显得精练。有些人则愿意用第(1 )种形式,只须照抄函数首部就可以了,不易出错,而且用了有意义的参数名有利于理解程序,如:

void print ( int num , char sex , float score );

大体上可猜出这是一个输出学号、性别和成绩的函数,而若写成

void print ( int , float , char ) ;

则无从知道形参的含义。

注意:

对函数的“定义”和“声明”不是同一回事。函数的定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型以及函数体等,它是一个完整的、独立的函数单位。而函数的声明的作用则是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查(例如,函数名是否正确,实参与形参的类型和个数是否一致),它不包含函数体。

如果已在文件的开头(在所有函数之前),已对本文件中所调用的函数进行了声明,则在各函数中不必对其所调用的函数再作声明。例如:

char letter ( char , char ) ;

float f ( float , float ) ;

int i ( float , float ) ;

int main ( )

{

...

}

/ /下面定义被main函数调用的3个函数

char letter ( char c1 , char c2 )

{

...

}

float f ( float x , float y )

{

...

}

int i ( float j , float k )

{

...

}

由于在文件的开头(在函数的外部)已对要调用的函数进行了声明(这些称为“外部的声明”),因此在程序编时,编译系统已从外部声明中知道了函数的有关信息,所以不必在主调函数中再重复进行声明。写在所有函数前面的外部声明在整个文件范围中有效。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/82017.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软宣布的五大重要事项|AI日报0520

微软宣布的五大重要事项 在 Build 大会上&#xff0c;微软向大家展示了微软如何构建开放的智能体网络。它正在重塑技术栈的每一层&#xff0c;微软的目标是帮助每一位开发者构建能够赋能世界各地的人们和组织的应用与智能体。消息来源 详细了解 以下是微软宣布的五大重要事项…

三、【数据建模篇】:用 Django Models 构建测试平台核心数据

【数据建模篇】&#xff1a;用 Django Models 构建测试平台核心数据 前言我们要设计哪些核心数据&#xff1f;准备工作&#xff1a;创建 Django App开始设计数据模型 (Models)1. 通用基础模型 (可选但推荐)2. 项目模型 (Project)3. 模块模型 (Module)4. 测试用例模型 (TestCase…

centos原系统安装了Python3.7.9兼用在安装一个python3.8

系统有个3.7.9版本的python 但是会遇到错误 usr/local/python3/lib/python3.7/site-packages/urllib3/connectionpool.py:1050: InsecureRequestWarning: Unverified HTTPS request is being made to host ‘www.xxx.com’. Adding certificate verification is strongly advi…

道可云人工智能每日资讯|浙江省人民政府印发《关于支持人工智能创新发展的若干措施》

道可云元宇宙每日简报&#xff08;2025年5月21日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 浙江省人民政府印发《关于支持人工智能创新发展的若干措施》 为抢占人工智能发展制高点&#xff0c;打造全球人工智能创新发展高地&#xff0c;浙江省人民政府于近日…

OpenGL ES 基本基本使用、绘制基本2D图形

OpenGL ES 绘制基础图形 OpenGL ES基本概念 OpenGL ES (Embedded-System) 是专为嵌入式设备&#xff08;如手机、平板、VR 设备&#xff09;设计的图形 API&#xff0c;是 OpenGL 的轻量级版本。 &#xff5c;下面是一个Android使用 OpenGL ES的基本框架 MainActivity 设置一…

JavaScript进阶(十二)

第三部分:JavaScript进阶 目录 第三部分:JavaScript进阶 十二、深浅拷贝 12.1 浅拷贝 12.2 深拷贝 1. 通过递归实现深拷贝 2. js库lodash里面cloneDeep内部实现了深拷贝 3. 通过JSON.stringify()实现 十三、异常处理 13.1 throw抛异常 13.2 try /catch捕获异常 1…

大疆制图跑飞马D2000的正射与三维模型

1 问题描述 大疆制图在跑大疆无人机飞的影像的时候&#xff0c;能够自动识别相机参数并且影像自带pos信息&#xff0c;但是用飞马无人机获取的影像pos信息与影像是分开的&#xff08;飞马无人机数据处理有讲&#xff09;&#xff0c;所以在用大疆制图时需要对相机参数进行设置…

探索服务网格(Service Mesh):云原生时代的网络新范式

文章目录 一、引言二、什么是服务网格基本定义形象比喻 三、服务网格解决了哪些问题微服务通信复杂性可观察性安全性 四、常见的服务网格实现IstioLinkerdConsul Connect 五、服务网格的应用场景大型微服务架构混合云环境 六、服务网格的未来发展与其他技术的融合标准化和行业规…

Electron+vite+vue3 从0到1搭建项目,开发Win、Mac客户端

随着前端技术的发展&#xff0c;出现了所谓的大前端。 大前端则是指基于前端技术延伸出来的各种终端平台及应用场景&#xff0c;包括APP、桌面端、手表终端、服务端等。 本篇文章主要是和大家一起学习一下使用Electron 如何打包出 Windows 和 Mac 所使用的客户端APP&#xff…

【DevSecOps】从零到一:用OpenAI Codey与Trivy打造智能化安全扫描 CI/CD 流水线实战

背景与动机 核心概念&#xff1a;DevSecOps、OpenAI Codey 与 Trivy 什么是 DevSecOpsOpenAI Codey&#xff08;Codex&#xff09;概览Trivy 扫描器简介 架构设计与技术选型 流水线实战&#xff1a;GitHub Actions 集成示例 多平台适配&#xff1a;GitLab CI 与 Azure DevO…

Swagger、Springfox、Springdoc-openapi 到底是什么关系

记得刚开始想在 SpringBoot 应用中使用 Swagger 生成 API 文档时&#xff0c;在 Swagger 官网上想找如何在 SpringBoot 中使用的指导&#xff0c;结果肯定是找不到&#xff0c;因为当时不清楚 Swagger 的定位是什么&#xff0c;只知道可以用它生成 API 文档。所以就想写这篇文章…

目标检测DINO-DETR(2023)详细解读

文章目录 对比去噪训练混合查询选择look forward twice 论文全称为&#xff1a;DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detection 提出了三个新的方法&#xff1a; 首先&#xff0c;为了改进一对一的匹配效果&#xff0c;提出了一种对比去噪训练方法…

深度学习-162-DeepSeek之调用远程大模型API接口参数结构分析

文章目录 1 文本对话请求1.1 请求参数1.1.1 参数说明1.1.2 参数总结1.2 返回参数1.2.1 id1.2.2 choices1.2.3 usage1.2.4 created1.2.5 model1.2.6 object1.2.7 参数总结2 应用示例2.1 调用大模型API2.2 返回结果3 参考附录分析文本对话请求v1/chat/completions的参数结构含义。…

uniapp原生插件

前言 使用uniapp开发Android app时&#xff0c;一些特定的需求没办法实现的时候就只能开发原生插件或者uts插件去满足需求&#xff0c;我的需求目前uts插件没法实现&#xff0c;只能靠原生插件了&#x1f606; 需求&#xff1a;拍照不保存图片到相册&#xff0c;uniapp的API或…

CVE-2024-42323

漏洞名称 Apache HertzBeat SnakeYaml 反序列化远程代码执行漏洞&#xff08;CVE-2024-42323&#xff09; 漏洞描述 Apache HertzBeat 是一款开源的实时监控告警工具&#xff0c;支持对操作系统、中间件、数据库等多种对象进行监控&#xff0c;并提供 Web 界面进行管理。 在…

“人工智能+多学科”选题思路,2025热点AI+(180个)

给大家整理了一份超全的论文资料合集 不仅有论文创新点的干货知识、开题报告模板、文献综述模板、审稿意见回复模板、还有全套的SCI论文写作指导教程和人工智能各方向经典的论文合集以及各大热门科研和论文写作润色工具等 以及1000G人工智能资料包&#xff08;如下图&#xff…

LangChain4j入门AI(八)使用RAG增加私有知识库

前言 我们通过提示词工程提升了通用LLM的专业知识水平&#xff0c;并结合Function Calling构建了私有业务能力。为了在实际应用中有效维护私有领域的专有数据&#xff0c;我们进一步采用大模型微调或RAG检索增强技术&#xff0c;使LLM能够充分掌握私有知识库的内容。 一、微调…

使用arXiv.org上的资源进行学术研究

arXiv.org e-Print archive arXiv.org 是一个收集物理学、数学、计算机科学、定量生物学、定量金融学和统计学等领域学术论文预印本的网站&#xff0c;其使命是促进科学文献的传播与交流。以下是关于该网站的详细介绍&#xff1a; 核心定位与功能 学术预印本平台&#xff1a…

Redis 中的缓存击穿、缓存穿透和缓存雪崩是什么?

在 Redis 中&#xff0c;缓存击穿、缓存穿透和缓存雪崩是常见的缓存问题&#xff0c;它们都会影响系统的性能和稳定性。以下是针对这三个问题的详细解释&#xff1a; 一、缓存击穿&#xff08;Cache Breakdown&#xff09; 定义&#xff1a;缓存击穿是指某个热点数据在缓存中…

RabbitMQ配置环境变量

一、RabbitMQ下载 1、从官网下载 在官网中下载&#xff0c;适合自己电脑的版本。我直接下载的windows版本。 然后下载opt这个软件这个版本适合3.6.3的RabbitMQ&#xff0c;点击蓝色的字体即可下载。 2、安装erlang 当你双击安装程序并进入安装向导后&#xff0c;会看到这样…