C语言.(1)函数的基本概念

1.函数的概念

函数是一个可以反复使用的程序段,从其他的程序段中,均可以通过条约定的语句来执行这段代码,完成既定的工作。
在C语言中我们一般会见到两类函数:

  • 库函数
  • 自定义函数

2.库函数

2.1标准库和头文件

C语言标准中规定了C语言的各种语法规则,C语言并不提供库函数;C语言的国际标准ANSI C规定了一
些常用的函数的标准,被称为标准库,那不同的编译器厂商根据ANSI提供的C语言标准就给出了一系列
函数的实现。这些函数就被称为库函数
有了库函数,一些常见的功能就不需要程序员自己实现了,一定程度提升了效率;同时库函数的质量和执行效率上都更有保证。
各种编译器的标准库中提供了一系列的库函数,这些库函数根据功能的划分,都在不同的头文件中进行了声明
库函数的相关文件: link

2.2库函数的使用方法

库函数的学习和查阅,比如:
C/C++ 官方的链接: link
cplusplus.com:link
举例: sqrt

double sqrt(double x);

有用信息

  1. sqrt 是函数名。
  2. x 是函数的参数,表示调用 sqrt 函数需要传递一个 double 类型的值。
  3. double 是返回值类型的值 - 表示函数计算的结果是 double 类型的值。

2.2.1功能

Compute square root x 计算平方根
Returns the square root x. (返回平方根)

2.2.2头文件包含

库函数是在标准库中对应的头文件中声明的,所以库函数的使用,务必包含对应的头文件,不包含是可能会出现一些问题的。

2.2.3实践

#include<stdio.h>
#include<math.h>// sqrt() 的头文件

int main()
{
	double a = 16.0;//在 VS2022中,16.0认为是 double 类型
	double b = sqrt(a);
	printf("%lf", b);// double 类型用 %lf 占位符来接收
	return 0;
}

输出结果:
在这里插入图片描述

2.2.4库函数文档的一般格式

  1. 函数原型
  2. 函数功能介绍
  3. 参数和返回类型
  4. 代码举例
  5. 代码输出
  6. 相关知识链接

3.自定义函数

3.1函数的语法形式

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

ret_type fun_name(形式参数)
{

}
  1. ret_type 是函数的返回类型

它是用来表示计算结果的类型,有时候返回类型可以是 void 表示什么都不返回。

  1. fun_name 是函数名

他是为了方便使用函数,尽量要根据函数的功能起的有意义

  1. 括号放的是形式参数

函数的参数也可以是 void 明确表示函数没有参数。如果有参数,要交代清楚参数的类型和名字,以及参数个数

  1. { } 是函数体

它是为了完成计算的过程。

3.2函数的举例

例子:
写一个加法,完成 2 个整型变量的加法操作

#include<stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	//输入
	scanf("%d %d", &a, &b);
	//调用加法函数,完成 a和b 的相加
	//求和的结果放在 r 中
	//输出
	printf("%d\n", r);
	return 0;
}

根据要完成的的要求:
函数取名为 :Add ,函数 Add 需要接收 2 个整型类型的参数,计算的结果也是整型。
所以:

#include<stdio.h>

int Add(int a, int b)
{
	int z = 0;
	z = a + b;
	return z;
}

int main()
{
	int a = 0;
	int b = 0;
	//输入
	scanf("%d %d", &a, &b);
	//调用加法函数,完成 a和b 的相加
	//求和的结果放在 r 中
	int r = Add(a, b);
	//输出
	printf("%d\n", r);
	return 0;
}

Add 函数也可以简化为:

int Add(int a, int b)
{
	return a + b;
}

函数参数部分需交代清楚: 参数个数,每个参数的类型是什么,形参的名字是什么。

4.形参和实参

在函数使用的过程中,吧函数的参数分为,实参和形参
看一下前面的代码:

#include<stdio.h>

int Add(int a, int b)
{
	return a + b;
}

int main()
{
	int a = 0;
	int b = 0;
	//输入
	scanf("%d %d", &a, &b);
	//调用加法函数,完成 a和b 的相加
	//求和的结果放在 r 中
	int r = Add(a, b);
	//输出
	printf("%d\n", r);
	return 0;
}

4.1实参

在上面的代码中,第 2~6行是 Add 函数的定义,有了函数后,在16行调用 Add 函数的。
把第16行调用 Add 函数时,传递给函数的参数 a 和 b 称为实际参数,简称实参实际参数就是真实传递给函数的参数

4.2形参

在上面的代码中,第3行定义函数时,在函数名 Add 后的括号中写的 x 和 y ,被称为形式参数,简称形参

为什么叫形式参数?

  1. 实际上,如果只是定义了 Add 函数,而不去调用的话Add 函数的参数 x 和 y 只是形式上存在的,不会向内存申请空间,不会真实存在的,所以叫形式参数。
  2. 形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形参的实例化

4.3实参和形参的关系

虽然我们提到了实参是传递给形参的,他们之间是有联系的,但是形参和实参各自是独立的内存空间
这个现象可以通过调试来观察:

#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);
	//调用加法函数,完成 a和b 的相加
	//求和的结果放在 r 中
	int r = Add(a, b);
	//输出
	printf("%d\n", r);
	return 0;
}

在这里插入图片描述
我们在调试的时候可以观察到,x 和 y 确实得到了a 和 b 的值,但是 x 和 y 的地址和a和b的地址是不一样的,所以我们可以理解为形参是实参的一份临时拷贝

5.return 语句

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

6.数组做函数参数

在使用函数解决问题的时候,难免会将数组作为参数传递给函数,在函数内部对数组进行操作。
例子:
写一个函数对将一个整型数组的内容,全部置为 -1,再写一个函数打印数组的内容。

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	//设置数组内容为 1
	set_arr();
	//打印数组内容
	print();

	return 0;
}

分析:

  1. 这里的 set_arr 函数要能够对数组内容进行设置,就得把数组作为参数传递给函数,同时函数内部在设置数组每个元素的时候,也得遍历数组,需要知道数组的元素个数
  2. 所以我们需要set_arr传递 2个参数,一个是数组,另外⼀个是数组的元素个数。仔细分析 print_arr 也是⼀样的,只有拿到了数组和元素个数,才能遍历打印数组的每个元素。
#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	//求数组 arr 元素的个数
	int sz = sizeof(arr) / sizeof(arr[0]);

	//设置数组内容为 1
	set_arr();
	
	//打印数组内容
	print_arr();

	return 0;
}

数组作为参数传递给了 set_arrprint_arr 函数了,那这两个函数应该如何设计呢?
插入一个知识点:与数组传参相关

  1. 函数的形式参数要和函数的实参个数匹配
  2. 函数的实参是数组,形参也是可以写成数组形式
  3. 形参如果是一维数组,数组大小可以省略不写
  4. 形参如果是二维数组,行可以省略,但是列不能省略
  5. 数组传参,形参是不会创建新的数组的
  6. 形参操作的数组和实参的数组是同一个数组

根据上述的信息,我们就可以实现这两个函数:

#include<stdio.h>

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

void print_arr(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	//求数组 arr 元素的个数
	int sz = sizeof(arr) / sizeof(arr[0]);

	//设置数组内容为 1
	set_arr(arr,sz);
	
	//打印数组内容
	print_arr(arr,sz);

	return 0;
}

结果:
在这里插入图片描述

  • 27
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值