C语言进阶版第4课—函数

1. 函数的概念

  C语言中函数就是执行某特定任务的一小段代码,主要分为库函数自定义函数.

1.1 库函数

  库函数就是C语言规定的标准库里的函数,例如printf输出、scanf输入函数,查看库函数→库函数相关文件

1.2 自定义函数

  其实就是我们自己定义的函数,函数名尽量要有意义
在这里插入图片描述
  这里的ADD就是我们定义的加法函数,使用自定义函数时,函数一定要放在函数调用前,如果想要将函数放在函数调用之后,那么要在调用前进行函数声明.

//函数
#include <stdio.h>
int ADD(int x, int y);   //也可以写成int ADD(int , int );主要是声明有ADD这个函数,且两个参数都是int类型
int main()
{
	int a = 7;
	int b = 17;
	int sum = ADD(a, b);
	printf("%d\n", sum);
	return 0;
}
int ADD(int x, int y)
{
	return x + y;
}

在这里插入图片描述

2. 实参和形参

2.1 实参

int ADD(int x,int y)
{
  return 0;
}
//
int sum = ADD(a,b);

  实参就是真实传递给函数的参数,例如上面提到的代码int sum= ADD(a,b);中的a和b就是实参

2.2 形参

int ADD(int x,int y)
{
  return 0;
}
//
int sum = ADD(a,b);

  上面提到的代码中,int ADD(int x,int y)中的x和y就是形参形参顾名思义,就是形式上存在的参数,如果我们没有去调用ADD这个函数,那么x和y两个形参也不会再内存中占用空间,只有当ADD函数被调用时,形参才会为了接收实参传过来的值而在内存中创建空间来进行存放.

2.3 实参和形参的关系

在这里插入图片描述
  通过调试我们发现,实参a和b的值确实放进形参x和y里面了,但是实参和形参的地址却不同,说明在内存中重新为形参创建了空间来存放数值,因此也可以称形参就是实参的一份临时拷贝.
  实参和形参名也可以相同。

3. 数组传参

创建一个arr[10]的整型数组,初始化数组为{1,2,3,4,5,6,7,8,9,10}
将数组的每个元素换成‘-1’

//数组传参
#include <stdio.h>

void set_arr(int arr[10], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		arr[i] = -1;
	}
}

void print_arr(int arr[10], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%p\n", &arr[i]);
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%p\n", &arr[i]);
	}
	printf("------------------\n");
	set_arr(arr, sz);
	print_arr(arr, sz);
	return 0;
}

在这里插入图片描述
  通过上图我们可以看出,数组在传参时,实参和形参中的数组元素的地址相同,说明数组在传参时并未创建新的数组,实参和形参中的数组是同一个.因此我们可以得出:

  • 函数的实参和形参个数要匹配
  • 函数的实参是数组,形参也可以写成数组形式
  • 形参如果是一维数组,数组大小可以不写
  • 形参如果是二维数组,行可以省略,列一定不能省略不写
  • 数组传参,形参不会创建新的数组
  • 形参的数组和实参的数组是同一个

4. return语句

  • return语句后面可以跟数值或表达式,若跟表达式,则先计算表达式再返回
  • 返回类型是void时,return后面可以什么也不跟
  • 代码中if等多支语句时,要保证每种情况下都有return返回,防止报错
  • return语句执行后会立即返回,不会再执行后面的语句.

5. 函数嵌套使用和链式访问

5.1 嵌套使用

  • is_leap_year():根据年份确定是否是闰年
  • get_days_of_month():调⽤is_leap_year确定是否是闰年后,再根据⽉计算这个⽉的天数
//计算某年某月有多少天
#include <stdio.h>
int is_leap_year(int a)
{
	if ((a % 4 == 0) && (a / 100 != 0) || (a / 400 == 0))
		return 1;
	else
		return 0;
}
int get_days_of_month(int a, int b)
{
	int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//由于数组下标从0开始,第一个元素初始化为0,方便对齐输入的年月份
	int day = days[b];
	//判断是否为瑞年,是则2月份+1
	if (is_leap_year(a) && b == 2)
		day += 1;
	return day;
}
int main()
{
	int a = 0;    //年份
	int b = 0;    //月份
	scanf("%d %d", &a, &b);
	int num = get_days_of_month(a, b);
	printf("%d\n", num);
	return 0;
}

在这里插入图片描述

5.2 链式访问

  链式访问就是把一个函数的返回值当成另一个函数的参数
在这里插入图片描述
  猜一猜这段代码执行结果是什么呢?

#include <stdio.h>
int main()
{
	printf("%d", printf("%d", printf("%d", 43)));
	return 0;
}

在这里插入图片描述
  这里主要了解一下printf函数也会返回一个参数,而printf函数返回的是它读取到的字符个数,第一个printf函数正常输出43,并且返回2,将返回值放到第二个printf函数里,变成printf(“%d”,printf(“%d”,2));这时候继续打印2,然后第二个printf函数返回1,变成printf(“%d”,1),打印1.

6. 关键字static和extern

  在工程中常常会创建多个(.c)和(.h)文件中,通常函数定义放在(.c)文件,而声明函数放在(.h)文件.
在这里插入图片描述

  static可以修饰局部变量、全局变量、函数.

  • static修饰局部变量
    在这里插入图片描述
    在这里插入图片描述
  • static修饰全局变量
    在这里插入图片描述
    在这里插入图片描述
  • static修饰函数
    在这里插入图片描述
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值