《C语言初阶》 第三部分 函数(上)

大家好!这篇文章我准备向大家详细介绍函数的基本知识,函数在程序中是非常重要的一块,它是独立的,能实现某种特定任务。好了,话不多说,让我们一起来看一看吧。
在这里插入图片描述

1. 函数是什么?

函数的定义:子程序
在计算机科学中,子程序是一个大型程序中的某部分代码, 由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。
一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。

2. C语言中函数的分类

1.库函数
2.自定义函数

2.1库函数

为什么会有库函数呢?
我们知道在我们学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想
把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格
式打印到屏幕上(printf)。
所以,像这样我们经常要使用的基础功能,它们不是业务性的代码。但在开发的过程中每个程序员都可能用的到,为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。
那怎么学习库函数呢?
这里,我给大家介绍一个网站:这个网站包含了C语言中所有库函数。
简单的总结,C语言常用的库函数都有:
在这里插入图片描述
简单的介绍一下:
IO函数:就是输入输出函数(printf,scanf,getchar,putchar…)
字符串操作函数:用来进行字符串处理的函数(strcmp,strlen…)
字符操作函数:用来进行字符处理的函数(toupper…)
内存操作函数:能操作计算机内存的函数(memcpy,memcmp,…)
时间/日期函数:(time…)
数学函数:pow(次方),sqrt(开平方)…
注:
但是库函数必须知道的一个秘密就是:使用库函数,必须包含 #include 对应的头文件。

如何学会使用库函数?需要全部记住吗?
不需要全部记住,当我们学习这些库函数的时候,要学会查询这些网站来帮助自己懂得如何使用就行了。

2.2 自定义函数

如果库函数能干所有的事情,那还要程序员干什么?
所有更加重要的是自定义函数
自定义函数和库函数一样,有函数名,返回值类型和函数参数
但是不一样的是这些都是我们自己来设计。这给我们一个很大的发挥空间。
像函数的返回类型,函数参数在某些情况下可以省略,我们需根据情况而定。
函数的组成:

ret_type fun_name(para1, * )
{
 statement;
}

看一下这些意思:
在这里插入图片描述
我们举一个例子:
写一个函数可以找出两个整数中的最大值。

int get_max(int x, int y) {
	if(x>y)
	return x;
	else
	return y;
}
int main()
{
	int num1 = 0;
	int num2 = 0;
	scanf("%d%d", &num1, &num2);
	int max = get_max(num1, num2);
	printf("max = %d\n", max);
		return 0;
}

之前说过函数就像一个工厂,你给它原材料,它会给你加工成一个产品。在这里,num1和num2就像是原材料,而max就是产品,get_max就是一个独立的工厂。
我们将num1和num2传给get_max,它用x,y来接收,最后返回的值赋值给max。
再举个例子:
写一个函数可以交换两个整形变量的内容。
首先我们看一下这个代码:
在这里插入图片描述
这个代码有没有什么问题呢?我们运行一下看下结果:
在这里插入图片描述
我们可以看到这个函数并没有实现交换的功能。这是什么原因呢?我们用vs2019进行调试:
在这里插入图片描述
为了更好的了解,我们可以监视num1和num2的地址。想要观察函数内部,我们需要按F11,进入函数内部观察x,y的情况。
在这里插入图片描述
从这里我们就可以看到x,y所创建的地址和num1,num2的地址是不一样的,x,y创建了自己的空间,对x,y操作不会对num1,num2产生影响。
所以我们可以简单的认为:形参实例化之后其实相当于实参的一份临时拷贝。
那我们该如何修改?
我们应该让x,y和num1,num2建立起联系,所以应该使用指针,将num1的地址和num2的地址传给函数。
代码如下:
在这里插入图片描述
这样就可以完成交换了:
在这里插入图片描述

3. 函数的参数

3.1 实际参数(实参):

真实传给函数的参数,叫实参。
实参可以是:常量、变量、表达式、函数等。
无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。

3.2 形式参数(形参):

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

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

4. 函数的调用:

4.1 传值调用

函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。
swap1就是传值调用。

4.2 传址调用

传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。
swap2就是传址调用。
当我们写函数时,该用传值还是传址需要我们根据实际情况来定。

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

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

5.1 嵌套调用

嵌套调用很简单,举个列子:

void new_line()
{
 printf("hello\n");
}
void three_line()
{
    int i = 0;
 for(i=0; i<3; i++)
   {
        new_line();
   }
}
int main()
{
 three_line();
 return 0;
  }

这个代码在main函数中调用了three_line函数,在three_line函数中调用了new_line函数,最后打印了三次hello。
注意:函数可以嵌套调用,但是不能嵌套定义。

5.2 链式访问

把一个函数的返回值作为另外一个函数的参数。
看下面代码:

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

strlen是求字符串长度函数。所以这里结果为3,但其实我们可以简化这两行代码,让它变为一行。

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

这里我们就把strlen函数的返回值作为printf函数的参数,这就叫做链式访问。
这样我们来看一道练习题:

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

这个代码的结果是什么呢?我们来运行一下:
在这里插入图片描述
结果是4321,这是为什么呢?
首先,我们要知道一个点printf函数的返回值是打印在屏幕上字符的个数
在这里插入图片描述
我们来看我们给的数是43,所以第一个printf打印的是43。然后43是两个字符,所以返回值是2,所以第二个printf打印的就是2,然后2算一个字符,所以第三个printf接收的是1,所以打印的是4321。大家理解了吗?这就是链式访问的用法。

6. 函数的声明和定义

6.1 函数声明:

  1. 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数声明决定不了。
  2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
  3. 函数的声明一般要放在头文件中。
    声明只需要写出函数名,参数,返回类型就行了,在某些情况下,如果未声明就使用会出现警告或错误。

6.2 函数定义:

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

总结:

在这里,我就已经将函数的大概内容说完了,但其实还有一部分函数的递归没有说,递归我准备放在下一篇文章中给大家详细的说明。如果大家认为我有哪些不足之处或者知识上的错误都可以告诉我,我会在之后的文章中不断改正,也请大家多多包。如果大家觉得这篇文章有用的话,也希望大家可以给我关注点赞,你们的支持就是对我最大的鼓励,我们下一篇文章再见。

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学代码的咸鱼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值