
此笔记仅是我个人学习的笔记,接下来会持续更新,希望对初学者有所帮助,如果发现错误,望在评论区指正。
在前文中我们了解过库函数的概念,库函数是函数的一个分类,一般情况下,我们在C语言中遇到的两个函数为:库函数和自定义函数。 概念:同数学中函数的概念一样,C语言中的函数同样是输入值以后输出一些值。为什么要引入函数呢?是因为在编写代码的过程中如果存在错误,查找和改正这些错误时一堆杂乱无章的代码是很难找到错误的。这个时候引入函数的概念就能将一个大的代码部分分为无数小的代码部分,这样就可以很方便的修正这些错误。
C语言的国际标准ANSI规定了一些常用函数的标准,称为标准库。不同的编译器厂商根据这些给出了一系列函数的实现,这些函数被称为库函数。 各种编译器的标准库中提供了⼀系列的库函数,这些库函数根据功能的划分,都在不同的头⽂件中进⾏了声明。 库函数相关头⽂件:https://zh.cppreference.com/w/c/header 库函数查阅: 库函数查询https://zh.cppreference.com/w/c/header.html 库函数查询https://legacy.cplusplus.com/reference/clibrary/
有时候需要一些复杂的版块而库函数无法实现,自定义函数就是自己编写一个函数,方便程序编写。
其实自定义函数和库函数是一样的,形式如下:
ret_type fun_name(形式参数)
{
}int ADD(int x, int y)
{
return x + y;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
scanf("%d", &b);
int c = ADD(a, b);
printf("%d", c);
return 0;
}以上面函数的举例ADD为例子,来说一下形参和实参 形式参数,简称形参,是仅仅在函数里面出现的参数,就是上面的x和y,只在形式上存在,不会像内存申请空间。形式参数只有被调用时接收了实际参数的值才会向内存申请空间,这个过程称为形参的实例化。
实际参数就是真实传递给函数的参数,就是上面的a和b。
通过代码调试,我们可以看到这段代码运行的过程:
1.开始的时候

2.a和b被定义

3.进入函数内部观察

4.形参的实质化过程

5.计算并返回值

6.计算并打印

以上就是这段代码完整的运行过程了,如果是初学者可以自己试一下 实际上,我们在调试的时候发现,x和y确实是从a和b得到的值,但是xy和ab的内存地址是不一样的,所以我们可以理解为形参是实参的一份临时拷贝

形参和实参是可以为同一名称的,但是他们本质上还是不同的变量,仅仅作用域和内存空间不同
在函数中经常要出现return语句,这里重点说明一下return语句的注意事项
在详细述说数组作为函数参数怎么传参以前,我们先来看一个代码:
//set_arr函数作用:将代码中的元素全部换为 6 ,并且打印出来
void set_arr(int arr[], int sz);
int main()
{
int arr[5] = { 0 };
int sz = 0;
sz = sizeof(arr) / sizeof(arr[0]);
set_arr(arr,sz);
return 0;
}
void set_arr(int arr[], int sz)
{
int i = 0;
for (i = 0;i < sz;i++)
{
arr[i] = 6;
}
for (i = 0;i < sz;i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return;
}接下来依次开始解释
void set_arr(int arr[], int sz);是函数声明,在本文稍后的位置会解释
arr[][3]以这个代码为例
//计算某年某⽉有多少天?
int is_leap_year(int year);
int IF(int year, int month);
int main()
{
int year = 0;
int month = 0;
scanf("%d", &year);
scanf("%d", &month);
printf("%d\n", IF(year,month));
return 0;
}
int is_leap_year(int year)
{
if ((year % 400 == 0) || (year % 4 == 0) && (year % 100 != 0))
{
return 1;
}
else
return 0;
}
int IF(int year,int month)
{
int day[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
if (is_leap_year(year))
day[2]++;
return day[month];
}is_leap_year这个函数,以后代码中经常要用到函数的嵌套调用,但是函数是不能嵌套定义的,即函数的调用只能在其他函数外部。//链式访问
int main()
{
char ch[] = "abcde";
printf("%d", strlen(ch));
return 0;
}下面我们来看一个代码:
int main()
{
printf("%d", printf("%d", printf("%d", 43)));
return 0;
}代码输出的内容

为什么是4321不是43,这是因为printf返回的是打印在屏幕上字符的个数。第一次返回的是43,第二次返回的是2,第三次返回的是1,如果我们在每个printf里面加\n,最终打印出来的结果如下。

以下面代码为例
//计算某年某⽉有多少天?
int is_leap_year(int year);
int IF(int year, int month);
int main()
{
int year = 0;
int month = 0;
scanf("%d", &year);
scanf("%d", &month);
printf("%d\n", IF(year,month));
return 0;
}
int is_leap_year(int year)
{
if ((year % 400 == 0) || (year % 4 == 0) && (year % 100 != 0))
{
return 1;
}
else
return 0;
}
int IF(int year,int month)
{
int day[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
if (is_leap_year(year))
day[2]++;
return day[month];
}int is_leap_year(int year);
int IF(int year, int month);这部分是函数的声明
printf("%d\n", IF(year,month));这部分是函数的调用
int is_leap_year(int year)
{
if ((year % 400 == 0) || (year % 4 == 0) && (year % 100 != 0))
{
return 1;
}
else
return 0;
}这部分是函数的定义
有时候代码比较多的时候,需要把不同的代码放在多个文件里面。 一般情况下,函数的声明,类型的声明放在头文件(.h)中,函数的实现放在源文件(.c)中
如下:

这里将声明放到了ADD.h里,将定义放到了ADD.c里,调用在源文件中,并且前面添加了#include "ADD.h".