对于函数知识的全面学习

目录

1.函数概论

2.库函数

3.函数定义

了解局部变量和全局变量

 5.函数调用

5.递归函数

6.数组做函数的参数

1.一维数组

2.二维数组

3.数组作函数参数


1.函数概论

  1. 函数本质上是一段可以被重复调用,功能相对独立的程序段。
  2. 函数引用的目的:便于结构化、模块化编程(对代码进行整理总结,使之条理化),解决代码的重复使用问题,防止代码冗余(减少同一类代码的使用)。
  3. 函数是C程序的基本组成单元,所有的C语言程序都由一个或多个函数构成。最开始我们只是单独使用main函数去解决问题,但随着程序的复杂化,我们就需要用到多个函数。

2.库函数

在了解自定义函数前,我们需要先了解一下库函数(我们用的stdio.h\math.h都是库函数)

我们知道scanf函数、printf函数等都是stdio.h库函数内的函数,math.h内包含了许多数学方面的函数,但是除此之外还有其他库函数 我们怎么办呢?

在网上有很多文档可以帮助我们解决这个问题,比如这篇:http://t.csdn.cn/6s7mo

当然你也可以在以下网页中去查找你需要的函数:

1.MSDN

2.www.cplusplus.com

3.函数定义

C语言中的库函数都是编译系统事先定义好的,使用时无需再定义,但是我们的自定义函数是我们自己创造的,编译器是不认识的,所以我们一定要“先定义后使用”。

而定义有两种情况:

 

 先定义后调用:

 fun函数是在main函数上边,我先定义了fun函数,然后在main函数中调用了它。

先声明再调用再定义

 二者结果是完全相同的,怎么选择也看你个人。

注意:函数定义是互相平行的,不可以在一个函数里定义另一个函数

了解局部变量和全局变量

变量定义的位置不同,其作用域也不同,从变量的作用域来说,分为局部变量和全局变量

局部变量:在函数内部定义的变量,其作用域仅限于该函数内

注意:

1.不同函数内可以使用相同的变量名,但他们内存中占不同的空间,不是同一个变量

2.X函数内不能使用使用Y函数内定义的变量,局部变量只能在定义自己的函数中使用

3.形参也属于局部变量,在函数调用时为其分配空间,退出函数时释放空间

全局变量:在函数之外也可以定义变量,这样的变量称为全局变量

有效范围从全局变量开始到该源文件结束(整个.c文件)

注意:

1.全局变量的定义:同一作用域范围内只能定义一次,位置在所有函数之外

2.如果全局变量与局部变量同名,在局部变量作用范围内,全局变量不起作用

3.全局变量越少越好(可以被多个函数直接引用,在不同函数中都可能改变全局变量的值)

 5.函数调用

一张图让你明白函数嵌套调用

先赋予n的值,进入two函数中计算6+n,然后进入jieg函数求出最终结果2*(6+n),先返回two函数,最后回到main函数。

那么我们接下来看一下函数内参数的传递来真正理解函数调用:

 可以看到swap函数中的a,b值在我们的要求下交换了数值,而main函数中的a,b值没有发生改变。这是因为我们采用的是按值传递,顾名思义就只是传递给它一个数值。另外还有按地址传递。

我有一个好朋友,他家有一片苹果林,按值传递与按地址传递的区别就是:我从他那里得到了两个苹果,他因为家里苹果还没熟透,在街上买了两个苹果给我,这是按值传递(的确给了我苹果,但没有改变他家果园的苹果数量)而按地址传递是我跑到他家里,不管苹果熟没熟,自己上树上去摘了两个苹果(我也是得到了两个苹果,但是影响到了他家里果园的苹果数量,少了两个)

简单来说就是这样

通常我们采用的都是按值传递,不会影响main函数中参数原来的数值,但当我们遇到函数的形参是数组或者接下来的指针函数时,我们就要用到按地址传递,由于传递的是地址,形参与实参共享相同的存储单元,这样通过改变形参可以直接改变实参的值。

5.递归函数

自己调用自己,就是递归调用。

构造递归函数的关键:1.满足递归的表达式

2.有结束的条件(循环有出口)。

 进入递归后每一次语句的执行前都会进行条件判断,知道不满足条件退出递归调用。

递归分为递推回归

 例子:输出斐波拉契数列的第n项,递推公式如下:

 

 

 很明显,用递归会比用普通方法更简单方便。

6.数组做函数的参数

数组作函数参数有两种形式:一是把数组元素作为实参使用,二是把数组名作为函数的形参和实参使用

数组元素与常量元素的区别:

(1)数组是具有相同类型的一组变量

(2)数组名是数组元素的起始地址

数组名作为函数参数调用函数的格式为:函数名(数组名)。(数组名后边不能有[])

-------------------------------------------------------------------------------------------------------------

在这之前补充一下数组的知识

数组——一组相同类型元素的集合。

1.一维数组

注意一下数组的大小一定为常数(不推荐变长数组)

 

对于数组中的数组元素,我们进行赋值时,又分为完全赋值不完全赋值。

完全赋值就是给每一个数组元素都赋予我们指定的值。

 

如图,我在arr数组中输入了10个数,那么按照顺序,就会依次把我输入的值赋给arr[0]-arr[9]。这就是完全赋值。

那么不完全赋值很明显就是没有给每个数组元素都赋值了

 

我给10个数组元素只赋了6个值,而没赋值的元素呢?它们会被默认赋值为0。 

那么我把下标运算符内的数字去掉后,arr[]={1,2,3,4,5,6}和arr[10]={1,2,3,4,5,6}是不是相同的呢?

答案是不同的。如果我们没有规定数组元素的个数但在后边赋值的话,系统会根据所赋值元素的个数指定数组元素个数。(你写了几个数,它就认为有几个元素)

 明显它只有6个数组元素。

对于不同的数组类型都是适用的。

但要注意字符型数组,数组元素大小要比元素个数多一位,它结尾需要\0来收尾,否则你就会看到“烫烫烫”了。

另外要知道一维数组在内存中连续存放,也就是说他们的地址是连续的,你只需要知道第一个元素的地址就可以访问整个数组(而数组名就是数组第一个元素的地址,这个知识点你这段时间会经常用到的,因为函数后边就是该死的指针部分)。数组中数组元素的大小由数组元素类型决定,int型就是1个元素占4个字节了。

数组还有一个重要的就是下标,下标从0开始,到n-1(n为数组元素个数)

注意:这个不能在函数中应用,要用到main函数中

函数形参接收的是数组的地址,这时sizeof(arr)计算的是一个地址的大小,在我的图里的话就是4,所以size结果会变成1。直接错了

2.二维数组

int arr[]是一维数组,后边有一个下标运算符;而二维数组就是再加上一个int arr [] [],如你所见,这就是二维的了。

一维数组在内存中是连续存放的,那么二维数组呢?

因为二维的说法,会让人觉得是X ,Y轴那样有个长和宽,但是实际上它在内存中还是连续存放

 你看,它每一行最后一个元素和下一行第一个元素地址上相差了个4,说明它和其他元素一样在内存中都是连续存放的

二维数组的初始化遵从:自上而下,先左后右 。

3.数组作函数参数

举几个例子看一下:

例1:

例2:运用冒泡排序将数组按由大到小排序

冒泡排序思想:相邻元素进行比较,满足条件互相交换

 main函数里的东西都能看懂,说一下reslt函数,i指的是我们已经放置到位置上的元素的个数(从0开始,每放置好一个元素就+1),而j很明显就是对应元素的比较个数了,第一个元素需要和除自身外即(sz-1)个元素比较,第二个需要和(sz-1-i)个元素比较,i个元素放好后,不再需要比较。

具体没有什么可写的,到了题里边,具体情况具体分析。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值