函数(C语言)

函数分类

1.标准库函数
2.用户自定义函数(必须先定义才能调用)

函数组成

1.函数说明部分(函数类型、函数名、形式参数名)
2.函数体(类型说明部分、可执行语句部分)

函数定义

1.有参函数的一般形式
函数类型 函数名(参数表)
{
	函数体
}
2.无参函数的一般形式
函数类型 函数名(void)
{
	函数体
}
3.空函数(无参数)
函数类型 函数名(void)
{
}

函数调用

1.形式

函数名(实参表);

对于无参函数,调用时没有参数表,但不可忽略函数名后的括号。
2.分类

(1)将函数当作一个功能语句。
(2)要求函数有返回值,并参与表达式(函数表达式)的运算。
(3)将函数的返回值作为另一个函数的参数。

3.形式参数与实际参数

形参定义函数时使用的参数(变量),标识了该函数使用时传递数据的个数和类型,没有具体值。

实参:函数调用时使用的参数,将具体的数据传递给相应的形参,供函数使用。

注意:

(1)形参和实参的类型、个数和次序的一致。
(2)形参出现在函数定义中,只能在该函数体内使用。函数未调用时,形参不占内存中的存储单元,只在函数被调用时才分配内存单元。函数调用结束后,形参所占用的内存单元被释放。
(3)实参可以为常量、变量、表达式或函数值,函数调用时必须有确定的值,以便把这些值传递给形参。因此,应预先用赋值、输入等方法使实参得到确定的值。
(4)实参对形参的数据传送是“值传送”,即是单向的,只能由实参传送给形参,即形参的变化不影响实参。
(5)在内存中,实参和形参占用不同的单元,即使是同名也互不影响。

函数返回值

函数返回值也称函数值,一般通过return(返回语句)得到,一个函数体中可以包含多个return语句,程序执行到哪一个就返回哪一个的结果。

1.形式
return;
return 表达式;
return(表达式);
2.类型

(1)定义函数时,一般指明函数的返回值类型,没有说明时,默认为整形(int)。
(2)函数返回值的数据类型一般和函数体中return语句的表达式类型一致,不一致的话,系统会自动进行类型转换,使return语句返回值的类型与函数类型统一。
(3)void类型
若函数不需要返回值,可将函数类型定义为void,即“空类型”或“无类型”。

函数类型声明

用户自定义的函数若在程序中被其他函数调用(主调函数),且其函数定义在主调函数之后,则需在主调函数中对该函数进行“函数类型声明”。

1.格式

函数返回类型 函数名(参数类型1,参数类型2…);

注意:

(1)函数类型声明不包括形参变量名和函数体。
(2)函数类型声明和函数定义必须在返回类型、函数名、参数类型上完全一致。

2.说明

(1)被调用函数的定义出现在主调函数前,可省去对被调函数的声明。
(2)若在所有函数定义前,在函数外部对各函数进行了声明,在主调函数可省去对被调函数的声明。
(3)对库函数调用不用声明,但须用文件包含命令将其头文件包含。

数组或字符串作为函数参数

1.数组作为函数的参数

数组元素 (下标变量)只能作为函数的实参,是值传递

数组名 作为函数参数是地址传递,传递整个数组

(1)一维数组名作为函数实参

用数组名作函数参数,此时实参与形参都应用数组名。
在执行函数时形参数组与实参数组从首地址起共享存储单元,所以对形参数组的说明要简单,必须说明数组的类型、名称(可以与实参数组相同)和维数,维大小可以不必说明。

(2)多维数组名作为函数实参

可以指定每一维的大小,也可省去第一维的大小说明,但从第二维开始,每一维的大小必须说明。
例如:
int array [] [10];int array [5] [10];都是合法的
int array [5] [];int array [] [];都是非法的

2.字符串作为函数参数

在C语言中,字符串是以一维数组的形式存放的,用字符数组名作为函数的参数,在被调函数中可以改变字符串的内容,在主调函数中可以得到改变了的字符串。

函数的嵌套调用和递归调用

1.函数的嵌套调用

函数定义时不允许嵌套,但可以嵌套调用。

嵌套调用过程示意图:

在这里插入图片描述

2.函数的递归调用
(1)形式

a.直接递归

int fn1(int x)
{
	if (x>5)
	return fn1(x-1);   /*在函数中调用自身*/
	else
	return 5;
}

b.间接递归

int fn1(int x)
{
	int a=fn2(x+1);   /*在fn1函数定义中调用fn2函数*/
}
int fn2(int y)
{
	int b=fn1(y-1);   /*在fn2函数定义中调用fn1函数*/
}
(2)消去递归

大多数递归函数都可以用非递归函数来代替。
大部分函数的递归形式比非递归形式运行速度慢(附加的函数调用增加了时间开销)。
递归函数可以简化程序设计,有些问题不用递归算法无法解决(例如:汉诺塔问题)

变量存储类型

1.局部变量与全局变量
(1)局部变量

在函数内部定义的变量,也称内部变量。
a.主函数main()中定义的变量也是局部变量,只在main()函数体内有效。main()函数也不能使用其他函数定义的局部变量。
b.在不同的函数中可以使用相同的局部变量名,互不干扰。
c.函数的形参也是局部变量。
d.在复合语句中也可以定义局部变量,其有效范围只在该复合语句当中。
e.局部变量在函数运行时分配存储空间,函数执行完毕,程将自动释放所分配的存储空间。

(2)全局变量

在函数外部定义的变量,也称外部变量。外部变量不属于任何一个函数。
a.外部变量的定义必须在所以函数之外,且只能定义一次。
b.外部变量的声明是在使用该外部变量的函数之内,且可多次出现。
c.外部变量在定义时分配存储单元,且可初始化;声明时不能再赋值。

2.自动变量

自动变量的定义形式是在变量类型前加关键字auto。

例如:
void func(void)
{
	auto int a,b,c;    /*定义三个自动变量a,b,c*/
	...
}

关键字auto可以省略。

3.寄存器变量

变量的值一般存放在内存中,如果在程序中需要对某个变量频繁使用,为提高执行速度,可以将局部变量定义为寄存器型。寄存器变量的值存放在CPU的寄存器中,使用时直接从寄存器取出进行计算,而不必访问内存。
寄存器变量定义的形式是在变量的前面加关键字register。

例如:
void func(void)
{
	register int x,y,z;  /*定义三个寄存器变量x,y,z*/
	...
}
4.外部变量

外部变量的值存放在静态存储区,整个程序执行期间均占据存储空间。

(1)允许其他源文件中的函数访问

默认情况下,一个全局变量允许被其它源文件访问,但需要在访问它的文件中,用关键字extern说明。

(2)不允许被其他源文件访问

在定义外部变量时前面加关键字static,这样定义的外部变量(全局变量)称为“静态外部变量”。
在多人合作的程序开发中,将全局变量声明为静态外部变量可以避免模块间的冲突和误操作。

5.静态变量
(1)内部静态变量
(2)外部静态变量

内部函数与外部函数

1.内部函数(“静态函数”)
只能在源文件内使用
定义形式:
static 函数类型 函数名(参数表)
{
	函数体
}
static:静态存储类型标识符
2.外部函数
在定义它的文件之外的函数中使用
定义形式:
extern 函数类型 函数名(参数表)
{
	函数体
}
extern:外部存储类型标识符
在函数定义时如果省略extern,则系统默认其为外部函数。
其他文件需要使用外部函数时要对函数进行声明,并在函数类型名前加上extern,表明是在调用一个外部函数。

(文章内容部分借鉴教材,仅用于个人记录。)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值