C语言——函数(超详细分析)

🏡润下个人主页
🔥个人专栏 : 《C语言基础》

⛰️万仞高山,只登一步!

文章目录

函数是C语言基础重要的组成部分,在整个C语言学习过程中 经常会使用到函数,因此学会函数是学精C语言的关键一步!接下来,我将以我个人的视角,带领大家理解和感受函数是如何创建和使用!

一.函数的概念

函数对于我们来说并不陌生,自中学起我们就学习函数。在C语言中函数 可以叫子程序 ,具体解释:函数是一个完成某项特定的任务的一小段代码。这段代码有特殊的写法和调用方法!

其实C语言程序是由无数个小的函数组合而成,每个函数都能完成某项特定的任务,也可以重复的使用!

C语言中常见的函数分为两类
库函数自定义函数

二.库函数

2.1标准库和头文件

C语言规定了C语言的各种语法,但是C语言不提供库函数。

但是人们在使用的过程中会经常用到例如:

求字符串长度

输入信息

输出信息

开平方

...

经常会使用这些功能,但是每个人都写一份,很浪费时间且不利于代码的可移植性,于是C语言国际标准ANSI规定了一系列常用函数的使用标准,就被称为标准库

不同的编译器厂商根据ANSI提供的C语言标准给出了一系列函数的实现,这些函数就被称为库函数。库函数也是函数只不过是现成的直接可以拿来使用,有了库函数代码在执行效率和函数质量都有了保证

🚀库函数相关头文件

2.2 库函数的使用方法

库函数查询工具

✈️C/C++官方连接

🛸cplusplus.com

举例

strlen

size_t strlen ( const char * str );

strlen 是函数名

str 是函数的参数,表示调用函数strlen需要传递一个 char* 类型的值

size_t 表示函数返回值的类型

在search中直接输入想要查询的函数

2.2.1功能

计算字符串的长度

返回字符串的长度大小

2.2.2 头文件包含

库函数是在标准库对应的头文件声明的,使用函数是必须包含头对应的文件,不然会出问题

该函数对应的头文件

2.2.3 实践

c 复制代码
#include<stdio.h>
#include<string.h>
int main()
{
	char s[] = "abcdef";
	size_t str = strlen(s);
	printf("%d\n", str);
	return 0;
}

2.2.4 库函数文档的一般格式

1.函数原型

2.函数功能介绍

3.参数和返回类型说明

4.代码举例

5.代码输出

6.相关知识链接

三.自定义函数

库函数固然能让程序使用更加便利,但是自定义函数更为重要更具有创造性

3.1 函数的语法形式

ret_type fun_name(形式参数)

{

//内容

}

ret_type是函数的 返回类型

fun_name 是 函数名

{}是 函数体

我们可以把函数当成小型的加工厂,输入原料产生商品

函数也一样,我们输入参数进过函数的"加工" 得出结果
ret_type 表示返回的参数类型,可以是void表示什么都不返回

fun_name 表示 函数名 可以随意起,尽量做到见名知意

函数的参数

1.可以是void,表示函数没有参数

2.有参数要交代清楚参数个数,类型,名字

{}是 函数体表示计算过程

3.2函数的举例

例子:写一个加法函数,完成加法操作

c 复制代码
int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int n = 0;
	int m = 0;
	scanf("%d%d", &n, &m);
	int r = Add(n, m);
	printf("%d\n", r);
	return 0;
}

注:函数的参数部分一定要交代清楚函数的参数个数和类型,参数名是什么,可以灵活多变但是参数尽量不要超过四个

四.形参和实参

函数的参数可以分为实参和形参

用刚才上面写的代码举例

c 复制代码
int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int n = 0;
	int m = 0;
	scanf("%d%d", &n, &m);
	int r = Add(n, m);
	printf("%d\n", r);
	return 0;
}

4.1 实参

在函数调用Add时传递给函数的n,m 称为实际参数 简称实参

实际参数就是真实传递给函数的参数

4.2 形参

函数名Add中括号中的x,y 就是形式参数 ,简称形参

实际上Add虽然在形式上创造了x,y但是没有向内存申请空间,不是真实存在的,只有在函数被调用的过程中为了存放实际参数穿过来的值才会向内存申请空间,这个过程就是形参的实例化

4.3形参和实参的关系

虽然实参是传递给实参的,但是其中"暗藏玄机",实参和形参的各自有独立的空间。

接下来用一段代码调试和演示

c 复制代码
int Add(int x, int y)
{
	int r = 0;
	r = x + y;
	return r;
}
int main()
{
	int n = 0;
	int m = 0;
	scanf("%d%d", &n, &m);
	int r = Add(n, m);
	printf("%d\n", r);
	return 0;
}

通过监视可以看到

x,y确实得到了n,m的值,但是它们的地址是不一样的
总结
1.形参和实参有自己各自的空间
2.形参的改变不会影响实参
3.形参是实参的一份临时拷贝
4.形参和实参名字可以相同,但是空间依旧不同

五.return 语句

在函数的设计中经常会使用return语句,return语句注意事项

5.1 return语句后面可以是一个数也可以是表达式,如果是表达式先执行表达式,再返回表达式的结果

c 复制代码
int Sub2(int x, int y)
{
	
	return x-y;
}

int Sub1(int x, int y)
{
	int z = 0;
	z = x - y;
	return z;
}
int main()
{
	int m = 0;
	int n = 0;
	scanf("%d%d", &m, &n);
	int s = Sub1(m, n);
	printf("%d\n", s);
	printf("%d\n", Sub2(m, n));
	return 0;
}

5.2 return也可以不写,表示什么都不返回一般用于返回值是void的情况

c 复制代码
void test(int n)
{
	if (n > 0)
	{
		printf("hehe\n");
	}
	else
	{
		printf("haha\n");
	}
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	test(n);
	return 0;
}

5.3 return语句执行后函数就彻底返回,后面的代码不再执行

c 复制代码
int test(int n)
{
	if (n > 0)
	{
		return 1;
		printf("hahaha\n");
	}
	else
	{
		printf("hehe\n");
		return 2;
	}
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	test(n);
	return 0;
}


5.4 return 返回值和函数返回类型不一样,系统会自动将返回值转换为函数的返回类型

c 复制代码
int test()
{
	return 3.14;
}

int main()
{
	int r = test();
	printf("%d\n", r);
	return 0;
}


5.5 如果函数存在if分支语句,要保证每种情况下都有返回值否则会出现编译错误

c 复制代码
int test()
{
	int n = 0;
	scanf("%d", &n);
	if (n > 0)
		return 1;
}
int main()
{
	
	printf("%d\n", test());
	return 0;
}

没有说明n<=0的情况,出现逻辑错误


5.6函数返回值类型不写,编译器会默认返回类型为int

c 复制代码
test()
{
	return 3.14;
}

int main()
{
	
	printf("%d\n", test());
	return 0;
}

5.7 函数写了返回类型,但是函数没有return语句返回值不确定

c 复制代码
 int test()
{
	 int r = 0;
}
int main()
{
	
	printf("%d\n", test());
	return 0;
}

六.数组做函数参数

函数在解决问题的时候难免会把数组做为参数传的给函数,在函数内部对数组进行操作

把数字全部都置为-1,再写一个函数打印数组

c 复制代码
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]);
	}
}
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;
}

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

二维数组传参
例:

c 复制代码
 void Print_arr(int arr[][5], int r, int c)
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for ( j = 0; j < c; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { {1,2,3},{4,5,6, 7,} ,{ 8, 9, 10 } };
	Print_arr(arr,3,5);
	return 0;
}

总结

相关推荐
夜猫逐梦3 小时前
【C++】Visual Studio+CMake 开发 C++ 入门指南:从环境搭建到项目实战
开发语言·c++·visual studio
超级大只老咪3 小时前
数组(Java基础语法)
java·开发语言
tumu_C3 小时前
无用知识研究:用sfinae实现函数模板的overload [一]
开发语言·c++·算法
-森屿安年-3 小时前
数据结构——排序
数据结构·算法·排序算法
西望云天3 小时前
Trie树实战:三道典型例题
数据结构·算法·icpc
dragoooon343 小时前
[优选算法专题三.二分查找——NO.20搜索插入位置 ]
算法·leetcode·动态规划
hn小菜鸡4 小时前
LeetCode 1089.复写零
算法·leetcode·职场和发展
与己斗其乐无穷4 小时前
算法(一)双指针法
数据结构·算法·排序算法
能不能别报错4 小时前
K8s学习笔记(四) etcd组件
笔记·学习·kubernetes