IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言函数深度解析 -> 正文阅读

[C++知识库]C语言函数深度解析

点个赞,互相关注,一起学习!!!

前言

?一、函数是什么?

二、函数的分类

2.1 库函数

2.2? 自定义函数

3、函数的参数?

3.1 实际参数(实参):

3.2?形式参数(形参):

3.3 用内存解释形参,实参

4、函数的调用?

4.1 传值调用

4.2?传值调用

5、函数的嵌套调用和链式访问?

5.1 嵌套调用

?5.2 链式访问

?6.函数的声明与定义

总结


一、函数是什么

数学中我们常见到函数的概念。但是你了解 C 语言中的函数吗?
维基百科中对函数的定义: 子程序

计算机科学中,子程序英语:Subroutine, procedure, function, routine, method, subprogram, callable unit),是一个大型程序中的某部份代码,由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。

?一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。函数在面向过程的语言中已经出现。是结构(Struct)和(Class)的前身。本身就是对具有相关性语句的归类和对某过程的抽象。

二、函数的分类

1.库函数

2.自定义函数

2.1 库函数

为什么有库函数呢:

刚开始的时候,C语言是没有库函数的,C语言的库函数并不是C语言本身的一部分,它是由 编译程序根据一般用户的需要,编制并提供用户使用的一组程序。C的库函数极大地方便了用户,同时也补充了C语言本身的不足。在编写C语言程序时,使用库函数,既可以提高程序的运行效率,又可以提高编程的质量。
简单的总结,C语言常用的库函数都有: www.cplusplus.com
🚀IO函数
🚀字符串操作函数
🚀字符操作函数
🚀内存操作函数
🚀时间/ 日期函数
🚀数学函数
🚀其他库函数

注:使用库函数,必须包含 #include 对应的头文件。

http://en.cppreference.com (英文版)
http://zh.cppreference.com (中文版)
www.cplusplus.com? ? ? ? ? ?
以上是学习库函数的网站

2.2? 自定义函数

C语言中的库函数也不是万能的,这也就衍生出了更加重要的自定义函数 。 自定义函数和库函数一样,有函数名,返回值类型和函数参数。 但是不一样的是我们自己来设计,来赋予他的“使命”,这给了程序员很大的发挥空间!

函数的组成:

ret_type fun_name(para1, * )
{
 statement;//语句项
}
ret_type 返回类型
fun_name 函数名
para1 ? ?函数参数

下面举一个实例(得到最大的哪个数):?

#include <stdio.h>
 //输入两个数,得到最大的数
int get_max(int x, int y) {
 return (x>y)?(x):(y);
 //exp1 ? exp2 : exp3(条件操作符)  
 //如果x>y,输出x,否则输出y  
}
int main()
{
 int num1 = 10;
 int num2 = 20;
 int max = get_max(num1, num2);
 printf("max = %d\n", max);
}

3、函数的参数?

3.1 实际参数(实参):

🚀在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”(简称“实参”)。

🚀实参可以是常量变量表达式, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。 因此应预先用赋值,输入等办法使实参获得确定值。

3.2?形式参数(形参):

🚀是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数.

🚀形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例。(分配内 存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。

?下面用代码实例说明:输入两个数,交换两个数的值,并输出

#include <stdio.h>
//该代码段没有实现两数的交换
void Swap(int x, int y) {
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;
}
int main()
{
	int num1 = 1;
	int num2 = 2;
	Swap(num1, num2);//自定义函数
	printf("num1 = %d\nnum2 = %d\n", num1, num2);
	return 0;
}

代码实例输出结果?

由此我们可以得出上面代码没有实现我们所想要的功能,这是怎么一回事呢,我们下面继续探讨(形式参数当函数调用完成之后就自动销毁了)

我们对上面的代码就行改进,下面代码实例:?

#include <stdio.h>
//该代码段实现了两数的交换
void Swap(int* x, int* y) {
	int tmp = 0;
	tmp = *x;
	*x = *y;
	*y = tmp;
}
int main()
{
	int num1 = 1;
	int num2 = 2;
	Swap(&num1, &num2);//自定义函数
	printf("num1 = %d\nnum2 = %d\n", num1, num2);
	return 0;
}

??

下面我们来总结:?

🚀第一张代码图:(传过去的是值)调用函数Swap时,在Swap函数的内部,两个数的值时进行了交换,但是呢,x y是形参,形式参数当函数调用完成之后就会自动销毁,就是出了Swap函数的作用域后,x y就会被销毁,不会被保存,所以不会实现两个数交换的功能。

🚀第二章代码图:(传过去的是地址)有第一张代码图的分析后,也知道了形式参数当函数调用完成之后就会自动销毁,所以我们就传地址过去,把num1num2的内存地址传给xy,在Swap函数中,xy可以找到num1num2的内存地址,从而直接对num1num2进行修改。

3.3 用内存解释形参,实参

下面为代码实例:?

#include <stdio.h>
//不能完成要求
void Swap1(int x, int y) {
 int tmp = 0;
 tmp = x;
 x = y;
 y = tmp; 
}
//实现想要的结果
void Swap2(int *px, int *py) {
 int tmp = 0;
 tmp = *px;
 *px = *py;
 *py = tmp; 
}
int main()
{
 int num1 = 1;
 int num2 = 2;
 Swap1(num1, num2);
 printf("Swap1::num1 = %d num2 = %d\n", num1, num2);
 Swap2(&num1, &num2);
 printf("Swap2::num1 = %d num2 = %d\n", num1, num2);
 return 0; 
}

上面 Swap1 Swap2 函数中的参数 xypxpy 都是形式参数。在main函数中传给 Swap1 num1 , num2 和传 给 Swap2 函数的 &num1 &num2 实际参数

这里我们对函数的实参和形参进行分析:?

代码对应的内存分配如下:?

这里可以看到 Swap1 函数在调用的时候, x y 拥有自己的空间,同时拥有了和实参一模一样的内容。 所以我们可以简单的认为:形参实例化之后其实相当于实参的一份临时拷贝

4、函数的调用?

4.1 传值调用

函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。

4.2?传值调用

🚀传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
🚀这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。

?下面来一个练习,写一个函数,实现一个整形有序数组的二分查找。

int binary_search(int arr[], int k, int sz)
{
	int left = 0;
	int right = sz - 1;//内存中是从0开始数
	while (left <= right)
	{
		int mid = left + (right - left) / 2;
		//这样写的原因是因为如果遇见超级大的数字,那么计算机就会出错
		//你也可以这样写 int mid = (left + right) / 2;
		if (k > arr[mid])
			left = mid++;
		else if (k < arr[mid])
			right = mid--;
		else
			return mid;
	}
	return -1;
}
int main(){
	int k = 0;
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	scanf("%d", &k);
	int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = binary_search(arr, k, sz);
	if (-1==ret)
		printf("找不到");
	else
		printf("找到了,k的位置为%d", ret);
	return 0;
}

5、函数的嵌套调用和链式访问?

函数和函数之间可以根据实际的需求进行组合的,也就是互相调用的。?

5.1 嵌套调用

下面代码实例:

#include <stdio.h>
void new_line()
{
 printf("hehe\n");
}
void three_line()
{
 ? ?int i = 0;
 for(i=0; i<3; i++)
 ? {
 ? ? ? ?new_line();
 ? }
}
int main()
{
 three_line();
 return 0; 
}

函数可以嵌套调用,但是不能嵌套定义,下面代码实例(错误示范)?

int main()
{
	test()
	{
		;
	}
}

?5.2 链式访问

把一个函数的返回值作为另外一个函数的参数。

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[20] = "hello";
	int ret = strlen(strcat(arr, "bit"));//strlen:计算\0之前字符串的个数;strcat:将bit叠加到 
                                         //arr数组中
	printf("%d\n", ret);
	return 0;
}

?6.函数的声明与定义

声明:?

1. 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
声明决定不了。
2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
3. 函数的声明一般要放在头文件中的

定义:

函数的定义是指函数的具体实现,交待函数的功能实现。


总结

函数的递归与经典题目放在下一篇文章。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-14 23:31:36  更:2022-04-14 23:34:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:07:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码