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语言中的函数(1) -> 正文阅读

[C++知识库]C语言中的函数(1)

什么是函数

在数学中,我们学过函数的概念,都知道y=f(x),但是在C语言中,所谓的函数跟数学中的函数还是有很大的区别的,我们看看维基百科中对于函数的定义:

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

简单的理解就是在C语言中函数就是用来专门完成某项任务的部分代码,和其他函数相对独立,各司其职。通常需要输入和输出,需要使用某个函数时,申明引用即可。

函数的分类——库函数和自定义函数

库函数

什么是库函数?举个非常常见的例子,我们在输入输出时都会使用printf、scanf,而这些函数都在<stdio.h>这个库函数中,类似的还有很多,为什么会需要库函数呢?我们在编程时,会运用到一些常用的操作,比如输入输出,字符对比,内存设置等等,如果没有库函数,每个程序员都需要自己编写函数,不仅麻烦,而且可移植性差,因此我们就需要库函数的存在,将我们常用的函数进行封装,当我们需要引用时直接使用就可以了。
简单总结一下我们可以将库函数分为一下几种

  • IO函数 (printf 、scanf)
  • 字符串操作函数(strlen、strcmp)
  • 字符操作函数 (tolower 、toupper)
  • 内存操作函数 (memset、memcpy、memmove)
  • 时间/日期函数 (time)
  • 数学函数 (sin 、sqrt、abs、pow)
  • 其他库函数
    特别需要注意的是,在使用库函数的时候必须要使用#include来引用头文件。

自定义函数

在现实生活中,即使我们将库函数学习的特别牛,也是没用太大用处的,因为我们会遇到各种各样的问题,而这些问题库函数不可能全部概括到,因此我们就需要自定义函数。顾名思义,自定义函数就是自己设置的函数用来解决各式各样的问题。
那么函数的基本形式是什么样子的呢?

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);
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	int max = get_max(a, b);
	printf("max=%d", max);
	return 0;
}

这个代码是求两个数的较大值,不用函数的方法我们都会写,用函数是不是也会呢?在这段代码中我们自定义了一个get_max的函数,我们可以看到他包含了函数名,函数参数,返回类型。在主函数中用到时需要声明一下,如此才能够引用。a和b我们叫做实际参数(实参),x和y叫做形式参数(形参)。
我们再看一个例子:编写代码,交换两个变量里的内容。
我们不用函数来写:

 #include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int c = 0;
	printf("交换前:a=%d,b=%d\n", a, b);
	c = a;
	a = b;
	b = c;
	printf("交换后:a=%d,b=%d\n", a, b);
	return 0;
}

这种代码我们都会写,那么如何用函数编写这种问题的代码呢?
我们先看这样一组代码

#include <stdio.h>
void Swap(int x, int y)
{
	int z = 0;
	z = x;
	x = y;
	y = z;
}
int main()
{
	int a = 10;
	int b = 20;
	printf("交换前:a=%d,b=%d\n", a, b);
	Swap(a, b);
	printf("交换后:a=%d,b=%d\n", a, b);
	return 0;
}

我们看看打印的结果是什么?
在这里插入图片描述
我们发现结果前后没有发生变化,为什么呢?这是大家都会经常犯的一个错误,在这个代码中,a和b将各自的值传给了对应的x和y,也就是说函数Swap()仅仅是将x和y的值进行了交换对a和b的值没有进行任何的操作,这就导致交换前后没有变化,我们可以这样理解,当实参传给形参值的时候,他们空间上是没有联系的,因此对形参的操作对实参没有影响,形参就像是实参的copy一样。那么我们如何解决呢?既然没有联系,我们就可以建立联系,我们采用指针,不就可以将实参和形参建立联系了嘛?我们来看这样一组代码。

#include <stdio.h>
void Swap(int* px, int* py)
{
	int z = 0;
	z = *px;
	*px = *py;
	*py = z;
}
int main()
{
	int a = 20;
	int b = 10;
	printf("交换前:a=%d,b=%d\n", a, b);
	Swap(&a, &b);
	printf("交换后:a=%d,b=%d\n", a, b);
	return 0;
}

在这里插入图片描述
我们可以看到,通过指针传参可以实现效果,很好理解,在使用指针传参时我们发现,我们将a和b的地址传给px和py,因此px和py指向a和b的内容,所以在Swap()函数中我们就能够完成a和b的交换。

函数参数

经过上面两个例子我们直到了形参和实参,那么具体怎么理解呢?

  • 实际参数(实参)

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

  • 形式参数(形参)

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

函数调用

函数调用分为两种:传值调用和传址调用。
根据我们前面例子的介绍我们知道传值调用就是传数值,传址调用就是传地址。具体解释如下:

  • 传值调用

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

  • 传址调用

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

根据解释我们知道了两者的区别,那么具体我们如何使用呢?当我们只需要进行传值给形参,而不需要对实参进行修改时,我们应该采用传值操作;当我们需要对实参进行数值的修改时,我们采用传址调用。

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

嵌套调用

举个例子:

#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;
}

我们可以看到,在函数three_line()中调用了new_line函数,在函数main()中调用three_line()函数,这就是嵌套调用,但是函数不能嵌套定义,什么意思呢?举个例子:

//错误示范
#include <stdio.h>
int main()
{
	viod menu()
	{
		printf("hehe\n");
	}
	return 0;
}

这样是错误的。

链式访问

把一个函数的返回值作为另外一个函数的参数。举个例子:

#include <stdio.h>
int main()
{
	int len = strlen("abc");
	printf("%d\n", len);
	printf("%d\n", strlen("abc"));//链式访问
	return 0;
}

我们可以看到strlen()函数将返回值作为了printf函数的参数,所以叫做链式访问。
好了,这次的分享就到这里,如有错误,希望大家能指正,谢谢各位!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-23 10:32:07  更:2021-07-23 10:32:31 
 
开发: 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年4日历 -2024/4/28 1:45:35-

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