强化C【C语言笔记】——函数
函数概述
函数是C源程序的基本模块,通过对函数模块的调用实现特定的功能。C语言不仅提供了极为丰富的库函数(如Turbo C,MS C都提供了三百多个库函数),还允许用户建立自己定义的函数
C语言中从不同角度对函数进行分类:
-
从函数定义的角度看
-
库函数
-
用户定义函数
-
-
函数中有函数和过程两种功能
-
有返回值函数
-
无返回值函数
-
-
从被调用函数之间数据传送
-
无参数
-
有参数
-
-
C语言中提供了丰富的库函数
-
字符类型分类函数
-
转换函数
-
目录路径函数
-
诊断函数
-
图形函数
-
输入输出函数
-
接口函数
-
字符串函数
-
内存管理函数
-
数字函数
-
日期和时间函数
-
进程控制函数
-
其他函数
-
函数定义的一般形式
无参函数的定义形式
类型标识符 函数名() {声明部分 语句 }
其中类型标识符和函数名称为函数头
类型标识符指明了本函数的类型,函数的类型实际上是函数返回值的类型有参函数的定义形式
类型标识符 函数名(形式参数表列) {声明部分 语句 }
在形参表中给出的参数称为形式参数,它们可以是各种类型的变量,各参数之间用逗号间隔
函数的参数和函数的值
形式参数和实际参数
函数的参数分为形参和实参两种,形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用;实参出现在主调函数中,进入被调函数后,实参变量也不能使用
形参和实参的功能是作数据传送
函数的形参和实参具有以下特点:
-
形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元
-
实参在进行函数调用时,它都必须具有确定的值,以便把这些值传送给形参
-
实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配”的错误
-
函数调用中发生的数据传送是单向的;即只能把实参的值传送给形参
函数的返回值
函数的值是指函数被调用之后,执行函数体中的程序段所取得的并返回给主调函数的值,对函数的值有说明:
- 函数的值只能通过return语句返回主调函数
return 语句的一般形式为:return 表达式;
-
函数值的类型和函数定义中的函数类型应保持一直
-
函数值为整型,定义时可以省去类型说明
-
无返回值的函数,可以明确定义为空类型(void)
函数的调用
函数调用的一般形式
C语言中,函数调用的一般形式为:
函数名(实际参数表)
被调用函数的声明和函数原型
在主调函数中调用某函数之前应对该被调函数进行说明(声明),这与使用变量之前要先进行变量说明是一样的
其一般形式为:
类型说明符 被调函数名(类型 形参,类型 形参…);
或为:
类型说明符 被调函数名(类型,类型…);
函数的嵌套调用
C语言中不允许作嵌套的函数定义。因此各函数之间是平行的,不存在上一级函数和下一级函数的问题
但是C语言允许在一个函数的定义中出现对另一个函数的调用。这样就出现了函数的嵌套调用
函数的递归调用
一个函数在它的函数体内调用它自身称为递归调用。这种函数称为递归函数
执行递归函数将反复调用其自身,每调用一次就进入新的一层
为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满足某种条件后就不再作递归调用,然后逐层返回
数组作为函数参数
数组可以作为函数的参数使用,进行数据传送
数组用作函数参数有两种形式,一种是把数组元素(下标变量)作为实参使用;另一种是把数组名作为函数的形参和实参使用
数组元素作函数实参
数组元素就是下标变量,它与普通变量并无区别
数组名作为函数参数
用数组名作函数参数时,则要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明。当形参和实参二者不一致时,即会发生错误
在数组名作函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有一段内存空间
当形参数组a和实参数组b的长度不一致。编译能够通过,但从结果看,数组a的多余的元素显然是无意义的
局部变量和全局变量
局部变量
局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内, 离开该函数后再使用这种变量是非法的
关于局部变量的作用域还要说明以下几点:
-
主函数中定义的变量也只能在主函数中使用,不能在其它函数中使用
-
形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量
-
允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆
-
在复合语句中也可定义变量,其作用域只在复合语句范围内
全局变量
全局变量也称为外部变量,它是在函数外部定义的变量,其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明
如果同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即它不起作用
变量的存储类别
动态存储方式和静态动态存储方式
从变量值存在的作时间(即生存期)角度来分,可以分为静态存储方式和动态存储方式。
静态存储方式:是指在程序运行期间分配固定的存储空间的方式。
动态存储方式:是在程序运行期间根据需要进行动态的分配存储空间的方式。
用户存储空间可以分为三个部分:
-
程序区
-
静态存储区
-
动态存储区
全局变量全部存放在静态存储区,在程序开始执行时给全局变量分配存储区,程序行完毕就释放
动态存储区存放以下数据:
-
函数形式参数
-
自动变量
-
函数调用时的现场保护和返回地址
auto变量
在函数的局部变量,不专门声明为static存储类别,都是动态地分配存储空间的,数据存储在动态存储区中
关键字auto可以省略,auto不写则隐含定为“自动存储类别”,属于动态存储方式
用static声明局部变量
希望函数中的局部变量的值在函数调用结束后不消失而保留原值,这时就应该指定局部变量为“静态局部变量”,用关键字static进行声明
对静态局部变量的说明:
-
静态局部变量属于静态存储类别,在静态存储区内分配存储单元
-
静态局部变量在编译时赋初值,即只赋初值一次
-
如果在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符变量)。而对自动变量来说,如果不赋初值则它的值是一个不确定的值
register变量
为了提高效率,C语言允许将局部变量得值放在CPU中的寄存器中,这种变量叫“寄存器变量”,用关键字register作声明
-
只有局部自动变量和形式参数可以作为寄存器变量
-
一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量
-
局部静态变量不能定义为寄存器变量
用extern声明外部示例页面变量
外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾
在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量作“外部变量声明”
相关文章
【数据结构】——哈夫曼树
速通回忆 这里是完整的代码和运行结果,可以直接选择看下面代码的思路去快速回忆哈夫曼树,或从下面理论部分开始学习 ``` #include "stdio.h" #include "stdlib.h" /* 哈夫曼树结点的结构体 */ typedef struct { int weight; /* 权重 */ int parent; /* 父母结点下标 */ int l...
强化C【C语言笔记】——位运算
位运算符C语言提供了六种位运算符 - &:按位与 - !:按位或 - ^:异或 - ~:取反 - <<:左移 - \>>:右移 按位与运算 **其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0** 按位与运算通常用来对某些位清0 按位或运算 **其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就...
C语言中规中矩的大树
**没事干,写个树玩玩,真正的“撸树”** 在Ubuntu终端、VScode终端显示 代码 ``` #include "stdio.h" int main(){ int high = 5; //层高 int count = 5; //层数 int start; //每层开始*数 int...