六、函数的声明与定义
00 分钟
2023-8-13
2023-8-17
type
status
date
slug
summary
tags
category
icon
password
函数是一种可重用的代码块,用于执行特定任务。函数可以接受输入参数,并可以返回一个值。

1、函数的声明

函数的声明是指在使用函数之前提供函数的原型或者函数的头部信息,包括函数的名称、返回类型、参数列表等。函数声明的目的是为了告诉编译器函数的存在和函数的接口,以便在使用函数之前进行编译检查。格式如下:
其中返回类型是函数执行完毕时返回的数据,可以时基本数据类型(如 intfloatvoid等)或者自定义数据类型;函数名是一个标识,与变量名类似。参数列表时这个函数被调用时需要接受的数据,它可以是0个参数,也可以是多个参数。每个参数都是由参数类型和参数名称组成的,他们之间用逗号隔开,如:
注意:函数的声明一般声明在函数的使用之前,否则会在编译过程中报出错误信息。

2、函数的声明顺序

这里其他函数只被主函数调用。
正常的写法是这样的:
如果被调用函数在后面,我们就要在主函数之前先把函数声明出来,这样才能正常编译:
这样就完成了函数的正常声明。
如果有很多个这样的函数,我们写在同一个代码文件中,我们阅读代码的能力就会加大,所以我们需要一个方法,将这些代码分为不同的文件。

3、头文件的引用

3.1、头文件的作用

在C语言代码的编写过程中,我们经常会看到这样的代码:#include <stdio.h> ,这样的代码就是引入头文件代码。
我们在日常写代码的过程中,代码量一旦过多,就会造成自己难以阅读,所以我们可以把代码内容进行整理,写在不同的文件里面。当我们需要使用一个文件里面的代码时,就可以通过头文件代码来引入。
头文件具有以下几个作用:
  1. 函数声明和定义的分离:头文件中包含函数的声明(也可以包含定义),而函数的实现通常放在源文件中。通过头文件的引用,源文件可以知道函数的接口(参数类型、返回类型等)而无需了解其实现细节。这样可以提高代码的可读性和可维护性,同时也方便了代码的复用。
  1. 类型声明和定义的集中管理:头文件可以包含结构体、联合体、枚举等自定义类型的声明和定义。通过将这些类型的声明放在头文件中,可以方便地在多个源文件中使用这些类型,避免了重复定义的问题。
  1. 宏定义和常量的定义:头文件中可以定义宏和常量,这些定义可以在源文件中使用。宏定义可以用于进行代码替换和宏展开,常量的定义可以提高代码的可读性和维护性。
  1. 全局变量的声明:头文件中可以声明全局变量,这样可以在多个源文件中共享这些全局变量。在需要使用这些全局变量的源文件中包含相应的头文件,就可以访问和修改这些全局变量。
  1. 模块化编程:头文件可以将相关的函数、类型和常量组织在一起,形成一个代码模块。通过使用头文件,可以将程序的不同部分分割为多个模块,每个模块负责不同的功能。这样可以提高代码的可读性、可维护性和可扩展性。
  1. 符号解析:编译器在编译过程中需要对函数和变量进行符号解析,以确定其类型和地址等信息。头文件中的声明提供了这些符号的信息,使得编译器能够正确解析和处理代码。
我们经常遇见的头文件是如下几个,他们是常见的C语言标准库头文件包括:
  • stdio.h:包含输入输出函数的声明,如printf、scanf等。
  • stdlib.h:包含通用工具函数的声明,如内存分配函数malloc、free等。
  • string.h:包含字符串处理函数的声明,如strcpy、strlen等。
  • math.h:包含数学函数的声明,如sin、cos等。
  • time.h:包含时间和日期函数的声明,如time、ctime等。
除了这些头文件,C语言标准库头文件还有很多其他的头文件可以使用,当然我们也可我已自定义头文件。

3.2、自定义头文件

我们可以在项目文件下创建一个fun.h文件,其中.h扩展名表示他是一个头文件。
打开fun.h文件,如果我们使用的是集成开发环境(IDE),可能会自动生成一些标准头文件结构,没有的话要自行手动添加,如下:
这样写是因为如果一个头文件被引用两次,编译器会处理两次头文件的内容,这将产生错误。而这种写法就是一个条件语句,如果编译过就不在编译了,直接调用。
其中:
  • #ifndef FUN_H:表示判断之前是否定义过此头文件,如果定义过就不编译,如果没有定义过就到下一行代码
  • #define FUN_H:定义此头文件
  • #endif:用于结束条件编译块的指令
这种结构就是通常所说的包装器 #ifndef。当再次引用头文件时,条件为假,因为 HEADER_FILE 已定义。此时,预处理器会跳过文件的整个内容,编译器会忽略它。
现在一个头文件已经定义好了,现在我们在里面声明一个函数:
现在声明了一个函数,我们需要对这个函数进行调用,但是我们会发现,这个函数中并没有逻辑代码和返回值,所以我们需要再写一个后缀名为.c的同名文件fun.c,用来实现这个函数,有点类似于Java中的接口实现。
这样两个文件就写好了,现在我们可以开始引入头文件并调用其中的函数了:
这样代码就可以正常执行了,输出结果是2。

3.3、有条件引用

有时需要从多个不同的头文件中选择一个引用到程序中。例如,需要指定在不同的操作系统上使用的配置参数。您可以通过一系列条件来实现这点,如下:
但是如果头文件比较多的时候,这么做是很不妥当的,预处理器使用宏来定义头文件的名称。这就是所谓的有条件引用。它不是用头文件的名称作为 #include 的直接参数,您只需要使用宏名称代替即可:
SYSTEM_H 会扩展,预处理器会查找 system_1.h,就像 #include 最初编写的那样。SYSTEM_H 可通过 -D 选项被您的 Makefile 定义。
自定义头文件目的是把代码放在多个文件中,这样做可以把一个程序分为多个模块,而C语言的编译有以下特点: 1. 分别编写,分别编译(多线程编译),提高调试效率 2. 一个源文件程序是一个编译单位,而不是以函数作为编译单位 3. 程序是由main函数开始的,其他源文件中的代码执行后最终会回到main函数结束 4. 函数不能嵌套定义,但是可以嵌套调用
上一篇
七、函数的递归
下一篇
Harmony OS应用开发-工程目录介绍

评论
Loading...