【C语言基础】:函数

目录

一.函数的概念

   二.函数的分类

1.库函数

1.1.标准库和头文件

1.2.库函数的使用方法

2.自定义函数

2.1.函数的语法格式

2.2.函数的举例

三 .形参和实参

1.概念

2.形参与实参的关系

四.return语句

五.数组做函数参数

1.实例

2.注意

 六.嵌套调用和链式访问

1.嵌套调用

2.链式访问


一.函数的概念

C语言中的函数就是一个完成某项特定任务的一小段代码。

特点:                                                                         

  • 一小段代码。
  •   完成某项特定任务。

好处:

  • 可拆分任务。
  • 可重复利用,提高开发效率。

   二.函数的分类

两类函数:

  •  库函数(现成的、可直接使用的函数)
  •  自定义函数(根据需要,自己设计和创造的函数)

1.库函数

1.1.标准库和头文件

C语言提供了语法规则和一些库函数的信息(如,printf-名字-参数-返回类型···),但不提供库函数。C语言编译器厂商根据规定来实现这些函数。 

bce1230b391e43ed8f44af601524cf6b.png

各种编译器的标准库中提供了一系列的库函数,这些库函数根据功能划分,都在不同的头文件中进行了声明。

库函数相关头文件:https://zh.cppreference.com/w/c/header

1.2.库函数的使用方法

库函数的学习和查看工具很多,按需自取哈:

C/C++官方的链接:https://zh.cppreference.com/w/c/header

cplusplus.com:https://legacy.cplusplus.com/reference/clibrary/

例如:sqrt

double sqrt (double x);
// sqrt 是函数名
// x 是函数的参数,表示调用sqrt函数需要传递一个double类型的值
// double 是返回值类型

1.2.1.功能

计算算术平方根 

b74b39c36cc9489984a5b7af91bc1dd7.png

1.2.2.头文件

<math.h>e47de86bfeed44e498d28483b72e08f9.png

1.2.3.实践

#include<stdio.h>
#include<math.h>

int main()
{
	double a = 16.0;
	double b = sqrt(a);
	printf("%lf\n", b);
	return 0;
}

运行结果:bba86514524c496e8dc2c73e83eef491.png

2.自定义函数

自定义函数一般比库函数更加重要,给了程序员写代码更多的创造性。

2.1.函数的语法格式

其实自定义导函数和库函数是一样的,形式如下:

ret_type fun_name(形式参数) //如,double sqrt(doouble x) 
{
  函数体
}
// ret_type 是函数返回类型
// fun_name 是函数名
//()里的是形式参数
// {} 里的是函数体(描述的是函数完成任务的过程)

我们可以把函数想象成一个工厂,参数为原材料,输入原材料(即参数)后,经过工厂(即函数)的加工,输出产品(即计算结果)。

c0cd9b760fb84ebaacd39ecf8190ede8.png

注意:

  • ret_type 是用来表示函数计算结果的类型,有时候返回类型可以是 void,表示什么都不返回
  • 函数的参数也可以是void,明确表示函数没有参数。如果有参数,要交代清楚参数的类型名字以及参数的个数
  • fun_name是为了方便参数使用,但尽量要根据函数的功能取一些有意义的名字。

2.2.函数的举例

例,写一个加法函数,完成2个整型变量的加法操作。

//不创建函数时
#include<stdio.h>

int main()
{
	int a = 0, b = 0;
	scanf("%d %d", &a, &b);
	printf("%d\n", a + b);
	return 0;
}

//
//
//创建一个名为Add的加法函数
#include<stdio.h>
int Add(int x, int y) //x,y为两个参数;Add为函数名;返回整形类型
{
	int z = 0;
	z = x + y;
	return z;
}

int main()
{
	int a = 0, b = 0;
	scanf("%d %d", &a, &b);
	int sum = Add(a, b);  //a,b是Add函数接收的2个整形类型的参数
	printf("%d", sum);
	return 0;
}

Add函数也可简化为:

int Add(int x, int y)
{
	return x + y;
}

注意:参数的参数部分需要交代清楚参数个数每个参数的类型参数的名字

三 .形参和实参

1.概念

192157ab02954d3d9897aeff71441f13.png

  • 实参:函数调用时传给函数的参数。
  • 形参:函数定义中的参数。(若只定义了函数,而没有调用,则函数的参数x,y只是形式上存在的,不会向内存申请空间,不会真实存在,所以叫形式参数。)
  • 形式的实例化:形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才会向内存申请空间,这个过程就叫形式的实例化。

2.形参与实参的关系

65d794016f984cf38ef83dc14d8cac87.png

我们调试的时候可以发现,x和y确实得到了a和b的值,但是x和y的地址与x和y的地址是不一样的,所以我们可以理解为形参是实参的一份临时拷贝

四.return语句

在函数的设计中,经常会出现return语句,这里说一下注意事项:

  • return后边可以是一个数值,也可以是一个表达式。如果是表达式则先执行表达式,再返回表达式的结果。
  • return后边也可以什么都没有,直接写 return;这种写法适合函数返回类型是void的情况(即无返需返回)。
  • return返回的值和函数返回类型不一致,系统会自动将返回的值隐式转换为函数的返回类型
  • return语句执行后,函数就彻底返回,后边的代码就不再执行。(break是结束循环)
  • 如果函数中存在if等分支的语句,则要保证每种情况下都有return返回,否则会出现编译错误。

五.数组做函数参数

1.实例

写一个函数对一个整数数组的内容全部重置为-1,再写一个函数打印数组的内容。

//将数组内容重置为-1的函数set_arr的创建
void set_arr(int arr[], int sz) 
//一维数组的数组大小可省略不写;二维数组只可省略行,列不可省略。
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		arr[i] = -1;
	}
}
//
//打印数组函数print_arr的创建
void print_arr(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
//
//主函数
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10}; //形参和实参的名字可以一样
	int sz = sizeof(arr) / sizeof(arr[0]);
	set_arr(arr,sz);
	print_arr(arr,sz);
//形参个数要与实参个数匹配
//数组传参,形参不会创建新的数组。形参和实参操作的数组是同一个。(特殊)
	return 0;
}

2.注意

  • 数组传参写的是数组名。(不带【】)
  • 形参写的也是数组形式,并且写的时候可以省略元素个数。(仅限一维数组)
  • 数组传参后,形参的数组和实参的数组是同一块空间,改变形参数组就是在改变实参数组。
7d6b9c09bd074677b6bf7975a9424254.png

形参数组和实参数组是同一块空间

 六.嵌套调用和链式访问

1.嵌套调用

各个函数可以像乐高零件一样,相互无缝配合,组建成更大型的程序。他们之间的互相调用就是嵌套调用

实例:

假设我们需要计算某年某月有多少天。

若要函数实现,可以设计2个函数:

  • is_leap_year():根据年份确定是否为闰年
  • get_days_of_month():根据月计算这个月的天数
#include<stdio.h>

int is_leap_year(int y)
//能被4整除并且不能被100整除,或能被400整除
{
	if (((y % 4 == 0) && (y & 100 != 0)) || (y % 400 == 0))
		return 1;
	//是闰年
	else
		return 0;
	//不是闰年
}

int get_days_of_month(int y, int m)
{
	int days[] = { 0,31,28,31,30,31,30,31,31,31,30,31,30,31 };
	//    下标 :  0 1  2  3  4  5  6  7  8  9  10 11 12 13 
	int day = days[m];
	//几月刚好对应数字几
	if (is_leap_year(y) && m == 2) //调用了is_leap_year函数
		//是闰年,且是2月
		day = day + 1;
	//则2月为28+1=29天
	return day;
}

int main()
{
	int year = 0, month = 0;
	scanf("%d %d", &year, &month);//调用了scanf函数
	int d = get_days_of_month(year, month);//调用了get_days_of_month函数
	printf("%d", d);//调用了printf函数
	return 0;
}

2.链式访问

将一个函数的返回值作为另一个函数的参数,像链条一样将函数串起来就是函数的链式访问。

例如:

#include<stdio.h>
#include<string.h>

int main()
{
	int len = strlen("abcdef");
	printf("%zd\n", len);
	return 0;
}

也可将strlen的返回值直接作为printf函数的参数,形成链式访问:
 

#include<stdio.h>
#include<string.h>

int main()
{
	printf("%zd\n", strlen("abcdef"));
	return 0;
}

本次分享已到尾声,期待下次与大家的分享~

  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高乐高有点矮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值