C语言函数

深藏阁楼爱情的钟 2021-11-10 22:56 492阅读 0赞

函数的概念

  1. 每个C程序都至少有一个函数,即主函数 main() ,如果程序的任务比较简单,全部的代码都写在main()函数中,但是,在实际开发中,程序的任务往往比较复杂,如果全部的代码都写在main()函数中,main()函数将非常庞大臃肿,结构复杂,代码重复。
  2. 我们可以根据程序的逻辑和任务的分工把代码划分到不同的自定义函数中,main()更关心业务逻辑和处理流程,需要执行具体任务的时候,调用这些自定义的函数就可以了。
  3. 为了方使理解,我们把函数分为两种:一种是库函数,一种是自定义函数。
  4. 库函数是C语言提供的,或系统提供的,实现了某些基本的功能,例如scanfprintf,在程序中可以直接使用。
  5. 自定义函数是程序员为了完成某项任务而编写的函数,目的是为了实现某项的功能或让主程序更简洁。程序员在使用自定义函数之前,必须先声明和定义。

自定义函数的声明

  1. 自定义函数声明就是告诉编译器函数名称及如何调用函数,包括函数返回值的数据类型、函数名称、参数列表。
  2. 有些程序员也将函数声明说成是函数原型,只是用词不同,意思是一样的。
  3. C语言中的声明函数的语法如下:
  4. ![20190803194828365.png][]
  5. **返回值的数据类型return\_type:**函数执行完任务后,可以返回一个值,return\_type是函数返回的值的数据类型,可以是intchardouble或其它自定义的数据类型。有些函数只执行任务而不返回值,在这种情况下,return\_type用是关键字 void表示。
  6. 无返回值的函数的声明语法如下:
  7. ![20190803194845208.png][]
  8. **函数名称function\_name:**函数名称是标识符,命名规则与变量名称的命名规则相同。
  9. **函数的参数列表parameter list:**当函数被调用时,调用者需要向函数的参数传递值。参数列表包括参数的类型、顺序。参数列表是可选的,也就是说,函数可以没有参数。
  10. 无参数的函数的声明语法如下:
  11. ![20190803194857690.png][]
  12. **函数声明示例:**
  13. ![20190803194911269.png][]
  14. 声明了一个函数,返回值是int类型,函数名是checksc,函数只有一个参数int height,注意,函数的声明语句最后的分号不能少。
  15. 如果把自定义函数比喻成工具,函数的声明就是这个工具的设计图纸。

自定义函数的定义

  1. 自定义函数是工具,如果想让这个工具能被使用,光有设计图纸还不行,要把工具制造出来,函数的定义就是这个工具的实体,提供了函数的实际主体,为了实现函数的功能,程序员为需要函数编写代码。
  2. C语言中的函数定义的语法如下:
  3. ![20190803194927708.png][]
  4. 函数定义的return\_typefunction\_nameparameter list必须与函数声明一致。
  5. 函数主体包含为了完成任务需要执行语句的集合,放在花括号内。
  6. **示例:**
  7. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70][]
  8. 注意,不要在函数定义后面加分号,以下是错误的,初学者容易犯这种错误。
  9. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 1][]

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

  1. 如果自定义函数只在调用者程序中使用,可以在调用者程序中声明和定义,声明一般为调用者程序的上部,定义一般在调用者程序的下部,这并不是C语言的规定,而是为了让程序更方便阅读,程序员约定的写法。
  2. **自定义函数在调用者程序中声明和定义的示例(book45.c):**
  3. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 2][]
  4. book45.c中,判断超女身材的函数checksc不是公共的功能,只是选秀程序使用,所以声明和定义在book45.c中。
  5. 如果自定义函数是一个公共的功能模块,例如比较两个数的大小,就可以在其它的头文件中声明(如\_public.h),调用者程序需要用\#include预处理指令包含该函数声明的头文件。
  6. 如果自定义函数是一个公共的功能模块,就可以在其它的程序文件中定义(如\_public.c),编译的时候,要把调用者程序和自定义函数的程序文件一起编译。
  7. 在以下的示例中,函数max\_public.h头文件中声明,在\_public.c程序文件中定义,在book46.c程序中被调用。
  8. **自定义函数的头文件(\_public.h):**
  9. ![20190803195039971.png][]
  10. **自定义函数的程序文件(\_public.c):**
  11. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 3][]
  12. **调用者程序文件(book46.c)**
  13. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 4][]
  14. **编译命令如下:**
  15. ![20190803195118392.png][]
  16. 注意:
  17. 1)在book46.c的第6行![20190803195127967.png][],这里包含头文件是用双引号,不是尖括号<>。一般来说 \#include <> 用于包含C语言提供的库函数的头文件,\#include ""用于包含程序员自定义的头文件。
  18. 2)编译调用者程序的时候,把调用者程序和自定函数的程序文件一起编译。否则编译的时候会出现以下错误。
  19. ![20190803195142461.png][]
  20. 正确的编译指令应该是gcc -o book46 book46.c \_public.c
  21. 3)自定义函数的头文件\_public.h\_public.c的命名没有规定,由程序员自己命名,就像变量的命名一样,为了增加程序的可读性,尽可能采用一些有意义的名称。

库函数

  1. C语言提供了一些已声明和定义的函数,调用这些函数可以完成一些基本的功能,我们把这些函数称为C 标准函数(C standard library),简称库函数,例如printfscanfmemsetstrcpy等。CC语言的库函数有几百个,常用的不过十分之二三,不需要记住,在以后的章节中我将详细介绍一些常用库函数的使用,用多了就熟了。
  2. C语言标准库函数的声明的头文件存放在/usr/include目录中,如下:
  3. <asset.h> <ctype.h> <errno.h> <float.h> <limits.h>
  4. <locale.h> <math.h> <setjmp.h> <signal.h> <stdarg.h>
  5. <stddef.h> <stdlib.h> <stdio.h> <string.h> <time.h>
  6. C语言库函数的定义的文件是/usr/lib/gcc/x86\_64-redhat-linux/4.4.4/libgcc.a(不同编译器的版本目录名有所不同),这是一个打包好的静态链接库文件,静态链接库的知识我们以后再介绍。
  7. 我们在用gcc编译程序的时候并没有把libgcc.a包含进来,那是因为gcc编译器缺省会包含它,但是,程序员自定义函数的头文件和程序文件就没有这种待遇,需要手工的包含进来。

需要包含哪些头文件

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

20190803195157370.png

  1. 该包含哪些头文件呢?有两种方法,一是上百度上查资料,二是使用Linux系统提供的帮助,以strcpy函数为例,在命令行下输入man strcpy回车,如下:
  2. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 5][]
  3. man显示了函数的声明的头文件(第5行),函数的参数、使用方法和返回值。
  4. 注意了,如果程序中使用的没有包含它头文件的库函数,编译的时候不一定是警告,也可能是报错,函数无法识别等,这个要看编译器,不同C语言的编译器不一样。

调用函数的方法

  1. 库函数是系统声明和定义的,是现成的工具。自定义函数是程序员自己声明和定义的,是程序员补充的工具,不管是现成工具的还是补充的工具,都是工具,对使用者来说都一样,没有区别。
  2. C语言中,函数的调用非常灵活,可以独占一行语句,也可以当成常量赋值给变量,也可以当成函数的参数。
  3. 如果函数的返回值是void,表示该函数的的任务以完成某项功能为主,一般用单行书写,独占一条语句。
  4. 如果函数的返回值不是void,如果单行书写,表示不关心它的返回值,也可以当成常量用于任何表达式中。
  5. 例如:
  6. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 6][]

函数调用的过程

  1. 当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行函数体的代码,当函数的返回语句被执行时,或到达函数的结束括号时,就把程序控制权交还给调用者程序。
  2. **示例(book47.c)**
  3. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 7][]
  4. **运行结果**
  5. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 8][]

函数参数的传递

  1. 关于函数的参数,在很多教程中有很多说法,如“形参”、“实参”、“值传递”、“地址传递”、“引用”等,这些说法把简单的概念复杂化了,大家不必理会。
  2. 函数的参数可以理解为函数的局部变量,参数传递就是调用者程序把变量(或常量)的值复制一份给函数的参数,简单说来就是复制的过程。一旦完成数据的复制,调用者程序的变量和函数的参数就再也没有瓜葛了,所以,在函数调用的过程中,函数的参数的值发生改变并不会影响调用者程序的变量的值。
  3. 我们在调用函数的时候,不关心函数参数的名称,函数参数的名称是函数自己的事情,只在函数内部使用,与调用者无关。
  4. **示例(book48.c)**
  5. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 9][]
  6. **运行结果**
  7. ![20190803195329588.png][]

const约束

  1. const constant 的缩写,意思是“恒定不变的”!它是定义只读变量的关键字,或者说 const 是定义常变量的关键字。用 const 定义常变量的方法很简单,就在通常定义变量时前面加 const 即可,如:
  2. const int a = 10;
  3. 那么用 const 修饰后和未修饰前有什么区别呢?它们不都等于 10 吗?
  4. const 定义的变量的值是不允许改变的,即不允许给它重新赋值,即使是赋相同的值也不可以。所以说它定义的是只读变量。这也就意味着必须在定义的时候就给它赋初值。
  5. 在变量前加const约束,主要用于定义函数的参数,表示该参数在函数中是只读取,不允许改变,如果函数中试图改变它的值,编译的时候就会报错。
  6. 例如:
  7. ![20190803195356960.png][]
  8. 函数max在声明的时候,参数ab都加了const约束,在函数中,a=10;和b=20;这两代码试图改变ab的值。编译的时候如下:
  9. ![20190803195350116.png][]
  10. 编译无法通过。

应用经验

  1. 如果寻找函数

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

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

  1. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1Y3oxMjIxNDA3Mjk_size_16_color_FFFFFF_t_70 10][]
  2. 然后,打开多几个网页看看,基本上就差不多了。
  3. 注意一个问题,网上的内容太多太杂乱,重点关注百度百科的文章。
  4. 1)测试函数的功能
  5. 要使用函数,只需要关注它需要包含的头文件、函数名、返回值、参数的数据类型和参数的顺序,不必关心参数的名称。
  6. strcpy函数为例,函数的声明如下。
  7. char \*strcpy(char \*dest, const char \*src);
  8. 函数名:strcpy
  9. 返回值:返回dest,一般没用,不理它。
  10. 第一个参数是目标字符串;第二个参数是源字符串,有const约束。
  11. 写代码测试一下:
  12. char strname\[50\];
  13. strcpy(strname,"西施");
  14. printf("=%s=\\n",strname);
  15. 然后,看看输出的结果是不是“=西施=”,用=号夹住输出的内容是为了看清楚有没有其它的字符。

版权声明

C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。

来源:C语言技术网(www.freecplus.net)

作者:码农有道

如果这篇文章对您有帮助,请点赞支持,或在您的博客中转发我的文章,谢谢!!!

如果文章有错别字,或者内容有误,或其他的建议或意见,请您留言指正,非常感谢!!!

发表评论

表情:
评论列表 (有 0 条评论,492人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C语言 函数

    函数 一、函数的调用    1.传值调用: 函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。在函数被调用时,实参传给形参其实形参就是实参的一份临时拷贝

    相关 C语言函数

    文章目录 一、函数的概念 1、函数的概念 2、函数的分类 二、自定义函数的声明 三、自定义函数的定义 四、自定义函数代码

    相关 C语言 函数

    \ 函数基本概念 \\1.函数的概述 \- C源程序是由\\函数组成\\的。虽然在前面各章的程序中大都只有一个主函数main(),但实用程序往往由多个函数组成。函数是C源程

    相关 C语言函数

    1、C语言里可以采用分组的方式管理语句每个语句分组叫做一个函数 2、多函数程序执行的时候时间分配情况必须遵守以下规则 1.整个程序的执行时间被划分成几段,每段时间都被分配

    相关 C语言函数

    1、C语言里可以采用分组的方式管理语句每个语句分组叫做一个函数 2、多函数程序执行的时候时间分配情况必须遵守以下规则 1.整个程序的执行时间被划分成几段,每段时间都

    相关 CC语言内存函数

    C语言内存函数向编程人员提供复制、比较与设置内存块的有效方式,这些函数属于字符串函数,放在库文头文件string.h中声明,C89增补1增加了5个操纵宽字符数组的新函数。 s

    相关 C语言函数

      函数的概念        每个C程序都至少有一个函数,即主函数 main() ,如果程序的任务比较简单,全部的代码都写在main()函数中,但是,在实际开发中,程序