1.函数的概念
函数在C语言中,有些翻译成:子程序,当然子程序这种翻译更加准确一点,C语言中的函数就是一个完成某项特定的任务的一小段代码。这种代码是有特殊的写法和调用方法的。
在C语言中我们一般有2种函数:
- 库函数
- 自定义函数
库函数
1.标准库和头文件
C语⾔标准中规定了C语⾔的各种语法规则,C语⾔并不提供库函数;C语⾔的国际标准ANSIC规定了⼀些常⽤的函数的标准,被称为标准库,那不同的编译器⼚商根据ANSI提供的C语⾔标准就给出了⼀系列函数的实现。这些函数就被称为库函数。
我们前⾯内容中学到的 printf 、 scanf 都是库函数,库函数也是函数,不过这些函数已经是现成的,我们只要学会就能直接使⽤了。有了库函数,⼀些常⻅的功能就不需要程序员⾃⼰实现了,⼀定程度提升了效率;同时库函数的质量和执⾏效率上都更有保证。
各种编译器的标准库中提供了⼀系列的库函数,这些库函数根据功能的划分,都在不同的头⽂件中进⾏了声明。
- 库函数相关头⽂件查询:https://zh.cppreference.com/w/c/header
有数学相关的,有字符串相关的,有⽇期相关的等,每⼀个头⽂件中都包含了,相关的函数和类型等信息,库函数的学习不⽤着急⼀次性全部学会,慢慢学习,各个击破就⾏。
- 小编给大家整理了库函数的使用方法的查询:
C/C++官⽅的链接:https://zh.cppreference.com/w/c/header
中⽂版:https://cppreference.cn/w/
cplusplus.com:https://legacy.cplusplus.com/reference/clibrary/
例如:
double sqrt (double x);
//sqrt 是函数名
//x 是函数的参数,表⽰调⽤sqrt函数需要传递⼀个double类型的值
//double 是返回值类型 – 表⽰函数计算的结果是double类型的值
自定义函数
1.函数的语法形式:
其实自定义函数和库函数是一样的,形式如下:
代码块
ret_type fun_name(形式参数)//函数头
{
//ret_type叫做返回类型
//fun_name叫做形式参数
//“{}”中的东西叫做函数体
}
- 函数的参数就相当于,工厂中送进去的原材料,函数的参数也可以是void,明确表示函数没有参数,如果有参数,要交代清楚参数的类型和名字,以及参数个数。
- { }括起来的部分被称为函数体,函数体就是完成计算的过程。
比如以下2段代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
int c = 0;
scanf("%d %d", &a, &b);
c = a + b;
printf("%d", c);
return 0;
}
下面的代码为自定义函数计算a和b的和(此代码在续计算中只需要调用即可,不用每次在重新写加的代码,大大提高了使用效率)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Add(int x, int y)//形式参数,简称行参
{
return x + y;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int c = 0;
//函数调用
c = Add(a, b);//实际参数,简称实参,当把a,b往过传时,称为形参的实例化
printf("%d\\n", c);
return 0;
}
形式参数是实际参数的临时拷贝
那么就会有小伙伴问小编,代码中,return 是什么意思 下来小编给大家讲return 语句
2.return 语句
- return 后边可以是一个数值,也可以是一个表达式,如果是表达式则先执行表达式,再返回表达式的结果
- return 后边也可以什么都没有,直接写return;这种写法适合函数返回类型是void的情况。
- return 语句执行后,函数就彻底返回,后边的代码不再执行。
- return 返回的值和函数返回类型不一致,系统就会自动将返回的值隐试转换为函数的返回类型
- 如果函数中存在if 等分支语句,则要保证每种情况下都有return返回,否则会报错
- 函数的返回类型不写,编译器会默认函数的返回类型是int
- 函数写了返回类型,但是函数中没有使用 return 返回值,那么函数的返回值是未知的。
例如我们下面这段代码:

我们也可以将上述代码 int 类型改为 Bool 类型 - Bool 类型的话需要添加头文件 #include <stdbool.h>
- 将 int 类型改为 bool 类型
- 1改为 true
- 0改为 false
- r==1 改为 r
这也是一种思路
3.数组作为函数参数
在使用函数解决问题的时候,难免会将数组作为参数传递给函数,在函数内部对数组进行操作。
**比如:**写一个函数将一个整型数组的内容,全部置为-1,再写一个函数打印数组的内容。
代码块
#include<stdio.h>
int main ()
{
int arr[] ={1,2,3,4,5,6,7,8,9,10};
set_arr();//设置数组内容为-1
printf_arr();//设置打印数组内容
return 0;
}
数组在传参时几个重要知识点:
- 函数的形式参数和函数的实际参数个数匹配
- 函数的实参是数组,形参也可以写成数组形式的
- 形参如果是一对数组,数组的大小可以忽略不计
- 形参如果是二维数组,行可以省略,列不能省略
- 数组传参,形参是不会建设新的数组的
- 形参操作的数组和实参的数组是同一个数组
例如:如下图二维数组的传参(将一个二维数组的值全部变成-1)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void set_arr(int arr2[3][4], int r, int c)
{
int i = 0;
int j = 0;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
arr2[i][j] = –1;
}
}
}
void printf_arr(int arr2[3][4], int r, int c)
{
int i = 0;
int j = 0;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
printf("%d ", arr2[i][j]);
}
printf("\\n");
}
printf("\\n");
}
int main()
{
int r, c, i, j;
int arr[3][4] = { 0,1,2,3, 4,5,6,7, 8,9,10,11 };
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%d ", arr[i][j]);
}
printf("\\n");
}
printf("\\n");
set_arr(arr, 3, 4);//数组传参数直接写数组名
printf_arr(arr, 3, 4);
return 0;
}
4. 嵌套调用
嵌套调用就是函数之间的相互调用,每个函数就像一个乐高零件,正因为多个乐高零件互相无缝的配合才能搭配出乐高玩具,也正因为函数之间的相互调用,最后写出来了相对大型的程序,
假设我们计算某年某月有多少天?如下代码(提示:闰年2月有29天)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdbool.h>
bool is_leap_year(int year)//判断是否闰年
{
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
return true;
else
return false;
}
int get_days_of_month(int year, int month)//该函数下面又出现了一个函数(is_leap_year(year) )称为函数的嵌套
{
int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
int d = arr[month];
if (is_leap_year(year) && month == 2)//是闰年了,且month为2
{
d += 1;
}
return d;
}
int main()
{
int year, month;
scanf("%d %d", &year, &month);//输入年月
int d = get_days_of_month(year, month);
printf("%d\\n", d);
return 0;
}
5.链式访问
所谓链式访问就是将一个函数的返回值作为另外一个函数的参数,向链条一样将函数串起来就是函数的练市访问,
比如:
#include<stdio.h>
int main ()
{
int len =strlen("abcdef");//求一个字符串的长度
printf("%d\\n",len);//打印长度
return 0;
}
那么这串代码可以改下成以下代码:
#include<stdio.h>
int main ()
{
printf("%d\\n",strlen("abcdef"));//打印长度
return 0;
}
此过程就称之为链式访问。
6.函数的声明,函数的定义,函数的调用(单个文件)

那么当函数的定义位于main 函数下方时,此时就会出现未定义

那么此时只需将调用的函数放至main 函数之前就可以啦,这称之为函数的声明如下图

函数的声明,函数的定义,函数的调用(多个文件)

如上图:多个文件时。我们将函数的声明放至头文件中,将函数的定义放至另一个新建的文件中,我们只需在主函数文件头部添加#include"头文件起的文件名"如上图的add.h。
本期关于函数小编就讲这麽多,大家喜欢可以点赞关注,小编会继续跟新,有问题的小伙伴可在评论区留言!!

