多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### 函数 定义:函数是一组一起执行一个任务的语句,每个C程序至少有一个函数,即主函数main(),所有简单的程序都可以定义其他额外的函数。 C 语言中的函数定义的一般形式如下 ~~~ return_type function_name( parameter list ) { body of the function } ~~~ 在 C 语言中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分: * **返回类型:**一个函数可以返回一个值。**return\_type**是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return\_type 是关键字**void**。 * **函数名称**:这是函数的实际名称。函数名和参数列表一起构成了函数签名。 * **参数**:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。 * **函数主体**:函数主体包含一组定义函数执行任务的语句 ### 调用函数 创建 C 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。 当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。 调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。例如: ``` #include <stdio.h> /* 函数声明 */ int max(int num1, int num2); int main () { /* 局部变量定义 */ int a = 100; int b = 200; int ret; /* 调用函数来获取最大值 */ ret = max(a, b); printf( "Max value is : %d\n", ret ); return 0; } /* 函数返回两个数中较大的那个数 */ int max(int num1, int num2) { /* 局部变量声明 */ int result; if (num1 > num2) result = num1; else result = num2; return result; } ``` 把 max() 函数和 main() 函数放一块,编译源代码。当运行最后的可执行文件时,会产生下列结果: ~~~ Max value is : 200 ~~~ * [ ] **知识点:函数调用时需注意先后函数存在的先后顺序** 比如A函数调用B函数,则B函数的声明一定要在A函数的前面,否则会出现报错:B函数找不到标识符。 如正常代码如下: ``` #include "stdafx.h" #include <iostream> int func(void) { printf("函数"); return -1; } int func(void* pathName, int a) { printf("函数"); return -1; } int main() { func(); } ``` 如果我们将func函数移到main函数后面,即 ``` #include "stdafx.h" #include <iostream> int main() { func(); } int func(void) { printf("函数"); return -1; } int func(void* pathName, int a) { printf("函数"); return -1; } ``` 运行就会报错如下: ![](https://img.kancloud.cn/87/15/871595418c3ed2be2bec5c8934a2ff1f_1500x38.png) 原因如下:在C语言里面,程序加载过程是由上至下来进行加载,到加载到main函数时没有找到func函数(此时func函数还没有被加载到内存,会认为func函数没有,不存在),而Java中为啥可以呢?因为Java是面向对象的,它对于整个class文件,会整个加载到内存,它不会分为上下。 * [ ] **为什么C语言这样设计?** 因为C语言是以函数为基础,它不像Java一样以类为基础,类作为一个对象,所有的方法都可以写在类中。C程序是以每一个函数组成的,当设计一个应用程序之后,它会产生很高的耦合,所以C语言中的众多的头文件就相当于每一个接口,这些头文件不会参与编译,真正参与编译的是这些头文件实现的C文件,头文件的存在就是为了解决程序的耦合问题。 * [ ] **解决方案**: * 第一种方案就是,将func定义在main函数前面,就是刚开始正确的代码 * 第二种方案就是,编写头文件,将func函数声明在该头文件中,切记只有函数的声明,没有函数的实现,类似于Java中的接口,具体步骤:右面解决方案资源管理器中找到源文件,右键,添加,新建项,如图所示 ![](https://img.kancloud.cn/40/2c/402c09b0c43e3bfd289ed6f7d620e857_794x266.png) ![](https://img.kancloud.cn/1d/62/1d6246228f7a6bfdc5b7449c5344d92b_941x653.png) func.h如下 ``` int func(void); int func(void* pathName, int a); ``` 引用头文件如下: ![](https://img.kancloud.cn/59/c6/59c61554d582818cd4398e22c89a47d5_689x201.png) **注意:如果是自定义的头文件,是双引号,系统的自带的头文件则是尖括号** * [ ] **#include 指令** `#include`指令主要有两种书写格式. 第一种格式用于属于C语言自身库的头文件: ``` [#include指令(格式1)] #include <文件名> ``` 第二种格式用于所有其他头文件,也包含任何自己编写的文件: ``` [#include指令(格式2)] #include "文件名" ``` 这两种格式间的细微差异在于编译器定位头文件的方式。下面是大多数编译器遵循的规则。 * `#include <文件名>`:搜寻系统头文件所在的目录(或多个目录)。(例如,在UNIX系统中,通常把系统头文件保存在目录/usr/include中。) * `#include "文件名"`:先搜寻当前目录,然后搜寻系统头文件所在的目录(或多个目录),通常可以改变搜寻头文件的位置,这种改变经常利用诸如-I路径这样的命令选项来实现。 这样如下代码 ``` #include "stdafx.h" #include <iostream> #include "func.h" int main() { func(); } int func(void) { printf("函数"); return -1; } int func(void* pathName, int a) { printf("函数"); return -1; } ``` 再次运行就不会报错