目录
六、函数
6.1 概述
6.2 函数的定义
6.2.1 定义函数的一般形式:
6.3 函数的调用
6.3.1 传值方式调用函数⭐
6.3.2 引用的方式调用函数
6.3.3 无参函数的调用
6.4 函数的声明
6.5 多文件编程
C语言是由函数组成的,每一个C程序都至少有一个函数,即main() 函数,
函数都是从主函数main()开始执行,
一个C程序中,有且仅有一个main() 函数,其他函数的名字也是唯一的
函数的使用可以省去重复代码的编写,降低重复率,可以让程序更加模块化,有助于程序的阅读、修改、完善
返回值类型 函数名称( 参数 )
{
函数主体
}
1、返回值
返回值类型: 一个函数只能有一个返回值类型,可以是 int , float, char, double ,也可以是一个数组,等等,并且函数体类需要有对应的返回语句,即return语句(返回的东西也可以是表达式)
也可以定义没有返回值的函数,这个时候,返回值类型填 void,
在函数调用的时候,遇到返回值就结束这个被调用的函数
2、参数
参数:参数就是在函数调用的时候,需要给这个函数传递一些什么信息,可以没有参数,也可以有多个参数
在函数调用过程中传递的参数成为实参(实际参数,有具体的值)
函数定义中的参数称为 形参(形式参数,并不是实际存在的数据),在未出现函数调用的时候,他们并不占用内存的存储单元,
实参与形参的个数应该相等,类型相匹配,按照顺序一一对应
3、函数主题
函数主体:就是函数里需要执行的代码,只有main函数调用的时候,才会执行里边的语句
4、举个栗子
int sum( int a, int b ){
int result = a+b; //局部变量
return result;
}
函数的调用一般在其他函数里,例如主函数中,主函数执行到 调用这个函数的 语句的时候,这个函数才会被执行
在调用函数的时候,把参数的实际值赋给函数的形参,此时函数内对形参的操作,不会影响实际参数,在main函数种调用sum函数的方法 如下(sum函数在6.2.1的第4部分):
int main()
{
int num1 = 1, num2 = 2;
int c;
/*函数的调用
调用上边的函数sum,传递两个int型的参数,,参数的名字可以不跟定义的时候一样,只是把对应的数据传递给对应的形参,,但对应类型和数量必须一致
sum函数 的 返回值是 int类型, 可以直接赋值给c
*/
c = sum(num1, num2 );
printf("%d\n",c);
return 0;
}
函数调用结束后,函数会在内容中销毁,里边的局部变量,包括参数什么的也都不复存在,只留一个返回值,返回给主函数继续处理。对形参的操作不会影响实参。
这种方式下,形参是指向实参地址的指针,对形参进行的操作,也同样是对实参的操作,
好处:传递指针可以让多个函数访问 指针所引用的对象,不需要把这个对象声明为全局的,就可以被访问
int main()
{
int num1 = 1, num2 = 2;
int c;
/*函数的调用
通过传递指针来传递参数
*/
c = sum(&num1, &num2 );
printf("%d\n",c);
return 0;
}
⭐注意:数组是传址形式的,就是说数组作为实参传给形参的时候,传入的是地址,函数形参接收数组后,对数组的改变会影响实参。
无参函数的调用就很简单,直接调用就可以,但是要记得函数后仍需要加括号,不加括号就变成了函数指针
//定义一个没有参数的函数
void print(){
printf("hello world");
}
int main(){
//函数调用,没有参数的时候,括号也要加上
print();
//函数指针,不加括号,这就是一个函数指针
print;
return 0;
}
如果一个函数定义在 main函数之前,则不需要声明就可以直接调用,如果定义在main之后,或者其他程序中,就需要先在main函数之前进行声明后再调用
函数的声明格式就是在main函数之前,先写一下函数的“返回值类型、函数名字、参数类型”的信息,例如,add函数定义在main之后,就需要在main之前先声明一下add函数的相关信息,声明的规则如下面代码中的展示:
//函数的声明
extern int add(int a , int b ); //extern 关键字只做声明,不能做任何定义
//在一个程序中,一个函数可以被声明多次,也可以调用多次,但是只能定义一次
int add(int a, int b ); // extern可以省略
int add(int j, int k); //形参名字也可以改变;
int add(int , int); // 函数的形参名字也可以省略
int main(){
int a = 1, b= 2;
//函数的调用
int sum = add(a,b);
return EXIT_SUCCESS;
}
//函数的定义
int add(int a , int b ){
return a+b;
}
注意:在一个程序中,一个函数可以被声明多次,也可以被调用多次,但是只能定义一次。
例如说,一个文件,只负责功能的编写,命名为 02fun.c, 另一个文件,负责函数执行命名为 01main.c, 在01main.c中想要调用02fun.c 中的函数的时候,就需要定义头文件,(名字可以自己起,如果需要定义多个头文件的时候,一般一个源程序对应一个头文件),这里起名为 head.h,在头文件中来声明需要调用的其他文件中的函数等信息,以及全局变量等。
head.h的代码如下:
#pragma once //用来防止不同的文件嵌套的包含,你包含我,我包含你,这样程序会报错,报错原因就是 包含文件太多:深度=1024,写上这个就可以避免这个问题
//全局变量的定义
//函数的声明
int add (int a, int b );
在01main.c 文件中,需要用include 引入这个头文件head.h,注意引入自己编写的头文件用“” 括起来,引入系统的头文件,用<> 括起来,01main.c代码如下
#include
#include "head.h"
int main(){
int a= 1, b=2;
printf("%d\n", add(a,b )); //这个时候,其他代码中的add 函数就可以直接调用了
return 0;
}
避免同一个文件被include多次的办法有两种:
1、#pragma once,就如上述head.h中写的那样,但是这种方式只能用于windows中
2、#ifndef 方式,更常用,结构如下:
#ifndef __SOME_H_// 意思就是:if(如果) n (not没有) def(定义)__SOME_H_(某个头文件)
#define __SOME_H_ //然后那就 定义__SOME_H_
…… //定义的内容,也就是各种声明的语句
#endif //最后结束
原理就是,不走 define 和 endif之间的过程,也就避免了头文件重复包含
#ifndef __02_FUN_H_ // 命名只要不重复就好,一般会与源文件名字对应,最前边是两个下划线,然后是名字,中间不一个单词的话用一个下划线隔开
#define __02_FUN_H_ //然后那就 定义__SOME_H_
#include "head.h"
//全局变量的定义
//函数的声明
int add (int a, int b );
#endif //最后结束
⌨️ 跟的课程是黑马程序员的C语言课,并结合菜鸟教程来学习的,我是有一点java和python基础的,然后来学一下C和C++,顺带记的笔记~
️课程链接:01课程介绍_哔哩哔哩_bilibili
菜鸟教程:C 函数 | 菜鸟教程
❤️跟了很久这个课,觉得挺好的,老师讲的很清楚,也挺深入的,就是总时长真的好长,感觉我还可以继续跟好久。如果只是想快速过一遍的话,菜鸟教程就可以。
个人感觉比较适合有一点点基础的,或者已经学过一遍C语言,来巩固复习提高,或者学过其他语言,来深入了解一遍C语言。