### 调用函数
创建 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;
}
```
再次运行就不会报错