函数的概念

每个C程序都至少有一个函数,即主函数 main() ,如果程序的任务比较简单,全部的代码都写在main()函数中,但是,在实际开发中,程序的任务往往比较复杂,如果全部的代码都写在main()函数中,main()函数将非常庞大臃肿,结构复杂,代码重复。

我们可以根据程序的逻辑和任务的分工把代码划分到不同的自定义函数中,main()更关心业务逻辑和处理流程,需要执行具体任务的时候,调用这些自定义的函数就可以了。

为了方使理解,我们把函数分为两种:一种是库函数,一种是自定义函数。

库函数是C语言提供的,或系统提供的,实现了某些基本的功能,例如scanf、printf,在程序中可以直接使用。

自定义函数是程序员为了完成某项任务而编写的函数,目的是为了实现某项的功能或让主程序更简洁。程序员在使用自定义函数之前,必须先声明和定义。

自定义函数的声明

自定义函数声明就是告诉编译器函数名称及如何调用函数,包括函数返回值的数据类型、函数名称、参数列表。

有些程序员也将函数声明说成是函数原型,只是用词不同,意思是一样的。

C语言中的声明函数的语法如下:

返回值的数据类型return_type:函数执行完任务后,可以返回一个值,return_type是函数返回的值的数据类型,可以是int、char、double或其它自定义的数据类型。有些函数只执行任务而不返回值,在这种情况下,return_type用是关键字 void表示。

无返回值的函数的声明语法如下:

函数名称function_name:函数名称是标识符,命名规则与变量名称的命名规则相同。

函数的参数列表parameter list:当函数被调用时,调用者需要向函数的参数传递值。参数列表包括参数的类型、顺序。参数列表是可选的,也就是说,函数可以没有参数。

无参数的函数的声明语法如下:

函数声明示例:

声明了一个函数,返回值是int类型,函数名是checksc,函数只有一个参数int height,注意,函数的声明语句最后的分号不能少。

如果把自定义函数比喻成工具,函数的声明就是这个工具的设计图纸。

自定义函数的定义

自定义函数是工具,如果想让这个工具能被使用,光有设计图纸还不行,要把工具制造出来,函数的定义就是这个工具的实体,提供了函数的实际主体,为了实现函数的功能,程序员为需要函数编写代码。

C语言中的函数定义的语法如下:

函数定义的return_type、function_name和parameter list必须与函数声明一致。

函数主体包含为了完成任务需要执行语句的集合,放在花括号内。

示例:

注意,不要在函数定义后面加分号,以下是错误的,初学者容易犯这种错误。

自定义函数声明和定义的方式

如果自定义函数只在调用者程序中使用,可以在调用者程序中声明和定义,声明一般为调用者程序的上部,定义一般在调用者程序的下部,这并不是C语言的规定,而是为了让程序更方便阅读,程序员约定的写法。

自定义函数在调用者程序中声明和定义的示例(book45.c):

在book45.c中,判断超女身材的函数checksc不是公共的功能,只是选秀程序使用,所以声明和定义在book45.c中。

如果自定义函数是一个公共的功能模块,例如比较两个数的大小,就可以在其它的头文件中声明(如_public.h),调用者程序需要用#include预处理指令包含该函数声明的头文件。

如果自定义函数是一个公共的功能模块,就可以在其它的程序文件中定义(如_public.c),编译的时候,要把调用者程序和自定义函数的程序文件一起编译。

在以下的示例中,函数max在_public.h头文件中声明,在_public.c程序文件中定义,在book46.c程序中被调用。

自定义函数的头文件(_public.h):

自定义函数的程序文件(_public.c):

调用者程序文件(book46.c)

编译命令如下:

注意:

1)在book46.c的第6行

这里包含头文件是用双引号,不是尖括号<>。一般来说 #include <> 用于包含C语言提供的库函数的头文件,#include ""用于包含程序员自定义的头文件。

2)编译调用者程序的时候,把调用者程序和自定函数的程序文件一起编译。否则编译的时候会出现以下错误。

正确的编译指令应该是gcc -o book46 book46.c _public.c

3)自定义函数的头文件_public.h和_public.c的命名没有规定,由程序员自己命名,就像变量的命名一样,为了增加程序的可读性,尽可能采用一些有意义的名称。

库函数

C语言提供了一些已声明和定义的函数,调用这些函数可以完成一些基本的功能,我们把这些函数称为C 标准函数(C standard library),简称库函数,例如printf、scanf、memset、strcpy等。CC语言的库函数有几百个,常用的不过十分之二三,不需要记住,在以后的章节中我将详细介绍一些常用库函数的使用,用多了就熟了。

C语言标准库函数的声明的头文件存放在/usr/include目录中,如下:

C语言库函数的定义的文件是/usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc.a(不同编译器的版本目录名有所不同),这是一个打包好的静态链接库文件,静态链接库的知识我们以后再介绍。

我们在用gcc编译程序的时候并没有把libgcc.a包含进来,那是因为gcc编译器缺省会包含它,但是,程序员自定义函数的头文件和程序文件就没有这种待遇,需要手工的包含进来。

需要包含哪些头文件

我们在使用库函数的时候,如果不包含它的头文件,编译时会出现警告,如下:

该包含哪些头文件呢?有两种方法,一是上百度上查资料,二是使用Linux系统提供的帮助,以strcpy函数为例,在命令行下输入man strcpy回车,如下:

man显示了函数的声明的头文件(第5行),函数的参数、使用方法和返回值。

注意了,如果程序中使用的没有包含它头文件的库函数,编译的时候不一定是警告,也可能是报错,函数无法识别等,这个要看编译器,不同C语言的编译器不一样。

调用函数的方法

库函数是系统声明和定义的,是现成的工具。自定义函数是程序员自己声明和定义的,是程序员补充的工具,不管是现成工具的还是补充的工具,都是工具,对使用者来说都一样,没有区别。

在C语言中,函数的调用非常灵活,可以独占一行语句,也可以当成常量赋值给变量,也可以当成函数的参数。

如果函数的返回值是void,表示该函数的的任务以完成某项功能为主,一般用单行书写,独占一条语句。

如果函数的返回值不是void,如果单行书写,表示不关心它的返回值,也可以当成常量用于任何表达式中。

例如:

函数调用的过程

当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行函数体的代码,当函数的返回语句被执行时,或到达函数的结束括号时,就把程序控制权交还给调用者程序。

示例(book47.c)

运行结果

函数参数的传递

关于函数的参数,在很多教程中有很多说法,如“形参”、“实参”、“值传递”、“地址传递”、“引用”等,这些说法把简单的概念复杂化了,大家不必理会。

函数的参数可以理解为函数的局部变量,参数传递就是调用者程序把变量(或常量)的值复制一份给函数的参数,简单说来就是复制的过程。一旦完成数据的复制,调用者程序的变量和函数的参数就再也没有瓜葛了,所以,在函数调用的过程中,函数的参数的值发生改变并不会影响调用者程序的变量的值。

我们在调用函数的时候,不关心函数参数的名称,函数参数的名称是函数自己的事情,只在函数内部使用,与调用者无关。

示例(book48.c)

运行结果

const约束

const 是 constant 的缩写,意思是“恒定不变的”!它是定义只读变量的关键字,或者说 const 是定义常变量的关键字。用 const 定义常变量的方法很简单,就在通常定义变量时前面加 const 即可,如:const int a = 10;

那么用 const 修饰后和未修饰前有什么区别呢?它们不都等于 10 吗?

用 const 定义的变量的值是不允许改变的,即不允许给它重新赋值,即使是赋相同的值也不可以。所以说它定义的是只读变量。这也就意味着必须在定义的时候就给它赋初值。

在变量前加const约束,主要用于定义函数的参数,表示该参数在函数中是只读取,不允许改变,如果函数中试图改变它的值,编译的时候就会报错。

例如:

函数max在声明的时候,参数a和b都加了const约束,在函数中,a=10;和b=20;这两代码试图改变a和b的值。编译的时候如下:

编译无法通过。

应用经验

在我的课程中,会介绍常用的库函数,但也有漏掉的。查资料是程序员的基本技能。

例如要查找C语言复制字符串功能的函数,在百度上输入“C语言复制字符串”搜索就可以了,你想查什么就输入什么。

然后,打开多几个网页看看,基本上就差不多了。

注意一个问题,网上的内容太多太杂乱,重点关注百度百科的文章。

1)测试函数的功能

要使用函数,只需要关注它需要包含的头文件、函数名、返回值、参数的数据类型和参数的顺序,不必关心参数的名称。

以strcpy函数为例,函数的声明如下。char *strcpy(char *dest, const char *src);

函数名:strcpy

返回值:返回dest,一般没用,不理它。

第一个参数是目标字符串;第二个参数是源字符串,有const约束。

写代码测试一下:char strname[50];

strcpy(strname,"西施");

printf("=%s=

",strname);

然后,看看输出的结果是不是“=西施=”,用=号夹住输出的内容是为了看清楚有没有其它的字符。

感谢大家的阅读,希望大家收益多多。

本文转自:https://blog.csdn.net/wucz122140729/article/details/98369860

推荐教程:《C语言》

c语言自定义函数运用,C语言自定义函数(图文详解)相关推荐

  1. c语言中自定义函数返回数组,C语言自定义函数返回数组的方法(图文详解)

    C语言自定义函数返回数组的方法(图文详解) 最近看到一些同学问题,有提到说:如何在一个函数中返回数组呢? 能否直接在自定义 函数中,写成char *类型返回值,直接返回呢?,代码如下: 直接返回str ...

  2. c语言 多线程 传话,code vs1506传话(塔尖)+tarjan图文详解

    1506 传话 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 一个朋友网络,如果a认识b,那么如果a第一次收到某个消息,那么会 ...

  3. 电大计算机C语言1253,1253《C语言程序设计》电大期末精彩试题及其问题详解

    1253<C语言程序设计>电大期末精彩试题及其问题详解 (34页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 实用文档&l ...

  4. 全网最全的Windows下Anaconda2 / Anaconda3里Python语言实现定时发送微信消息给好友或群里(图文详解)...

    不多说,直接上干货! 缘由: (1)最近看到情侣零点送祝福,感觉还是很浪漫的事情,相信有很多人熬夜为了给爱的人送上零点祝福,但是有时等着等着就睡着了或者时间并不是卡的那么准就有点强迫症了,这是也许程序 ...

  5. laravel 如何 new php 类,PHP实例:laravel通过创建自定义artisan make命令来新建类文件详解...

    <PHP实例:laravel通过创建自定义artisan make命令来新建类文件详解>要点: 本文介绍了PHP实例:laravel通过创建自定义artisan make命令来新建类文件详 ...

  6. 基于Web的Kafka管理器工具之Kafka-manager的编译部署详细安装 (支持kafka0.8、0.9和0.10以后版本)(图文详解)(默认端口或任意自定义端口)...

    不多说,直接上干货! 至于为什么,要写这篇博客以及安装Kafka-manager? 问题详情 无奈于,在kafka里没有一个较好自带的web ui.启动后无法观看,并且不友好.所以,需安装一个第三方的 ...

  7. php。defined,PHP defined()函数的使用图文详解

    PHP defined()函数的使用图文详解 PHP defined() 函数 例子 定义和用法 defined() 函数检查某常量是否存在. 若常量存在,则返回 true,否则返回 false. 语 ...

  8. python装饰器函数-Python函数装饰器常见使用方法实例详解

    本文实例讲述了Python函数装饰器常见使用方法.分享给大家供大家参考,具体如下: 一.装饰器 首先,我们要了解到什么是开放封闭式原则? 软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所 ...

  9. python跨函数调用变量_对python中不同模块(函数、类、变量)的调用详解

    首先,先介绍两种引入模块的方法. 法一:将整个文件引入 import 文件名 文件名.函数名( ) / 文件名.类名 通过这个方法可以运行另外一个文件里的函数 法二:只引入某个文件中一个类/函数/变量 ...

  10. python中search和match的区别_Python中正则表达式match()、search()函数及match()和search()的区别详解...

    match()和search()都是python中的正则匹配函数,那这两个函数有何区别呢? match()函数只检测RE是不是在string的开始位置匹配, search()会扫描整个string查找 ...

最新文章

  1. GT Transceiver的复位与初始化(4)RX初始化和复位流程
  2. drive数据集_运动想象,脑电情绪等公开数据集汇总
  3. 非刚性人脸跟踪 —— 人脸跟踪
  4. 用委托实现窗体间传值
  5. BUUOJ reverse SimpleRev (爆破)
  6. java二重循环计数_java的二重循环代码样例
  7. python随机颜色代码_python绘制随机颜色太阳花
  8. linux让新生成的文件自动加锁,Linux_实用技巧一则 Linux系统对文件进行加锁,当有多个工作线程要同时对一 - phpStudy...
  9. 【Hive】hive表的文件存储格式
  10. Sklearn流水线交叉验证以及超参数网格交叉评估基础案例实战-大数据ML样本集案例实战...
  11. iOS开发网络篇—发送GET和POST请求(使用NSURLSession)
  12. 为PyCharm添加不同解释器
  13. Excel怎么锁定单元格
  14. postgres关键字、常量和数据类型
  15. Linux下DMA驱动
  16. Spring Boot 分布式事物管理
  17. 会计专硕(MPACC)毕业论文该选如何选题?
  18. 完美解决MSSQL安装问题“Polybase要求安装Oracle JRE 7更新51(64位)”方案
  19. Deepin 20 外接显示器配置
  20. 牛客网入门题--最大公约数与最小公倍数

热门文章

  1. 控制系统分析与设计(三):非线性数学模型的线性化
  2. 使用Python全栈打造淘宝客微信机器人!功能太强大了!
  3. ibms智能化系统集成服务器,智能化集成管理系统(IBMS)
  4. Codeforces 633H. Fibonacci-ish II【莫队+线段树+公式】
  5. Ubuntu20.04设置WiFi热点
  6. Java嗖嗖移动项目
  7. RAC修改IP(public/virtual/scan)
  8. 更改dockers的host文件中的ip,当主机ip改变时,dockers无法启动。
  9. 明尼苏达大学研究者为bug事件致歉
  10. veu +Apipost下拉框选项绑定数据库