您当前的位置:首页 >> 科技
C 语言程序设计---函数
发布时间:2019-11-29
 


上次写了 C 语言入门级别的指针,这篇写函数,指针和函数在一起使用,更有意思,这也才能最大程度的发挥指针的作用。


基本概念


C 语言是一个函数语言,函数相当于”工厂“,具有”来料加工“的能力。

1sqrt(2.0);
2//sqrt()函数,接收 2.0 这个来料,并把它加工成 1.414...这样的结果。


1、

函数的分类

A、按 main() 和其它函数:主函数、其它函数

B、按作者分:系统函数(库函数)、用户自定义函数(我们自己写的);无论是库函数,还是用户自定义函数,其产生过程和调用,都应遵循相同的编程原则;

C、按函数调用关系分:主调函数、被调函数;

D、函数按参数个数划分:定参函数、不定参函数。


定参函数,参数个数固定;不定参函数,参数个数不确定;定参函数又分为有参函数和无参函数。

1printf("%d%d%d", a, b, c);  //4 个参数
2printf("Hello\n");  //1 个参数
3//所以 printf() 是一个不定参函数
4//若函数无参,则可以用 void 加以明确声明
5void main(void){}  //名称为 main 的函数,无返回值,无参数

2、

函数的产生和使用过程(步骤)


A、函数声明

B、函数定义

C、函数调用


函数声明:

(1)、确定的函数名称,函数名称是用以区分其它函数的标志,是这个函数的”入口“地址常量。


(2)、说明函数的返回值类型,sqrt(2.0) 的计算结果为 1.414,这个 1.414 就是所谓的返回值;


函数可以没有返回值,此时该函数返回值类型必须明确的写成:void;


返回值是由被调函数返回给主调函数的数值;函数若有返回值,最多只能有一个返回值;


(3)、说明函数的参数,参数个数以及每个参数的数据类型;函数在声明时,可以只说明参数类型,而缺省相关变量。

1int fun(int n);
2int fun(int);
//以上函数声明都是正确的


函数定义:

就是函数的编程,实现函数的功能,主要包含函数首部和函数体。

函数首部包括:函数返回值类型、函数名称、以及形参;

函数体是由 {} 括起来的语句组成。

1int fun(int m){}


注意:

(1)、若函数明确声明不是 void,则该函数必须以 {return 表达式;} 语句结束,并且,表达式类型必须与函数的返回值类型完全一致!

若函数返回值为 void,则可以写 return; 语句结束,也可以缺省这条语句。


特别强调:return (表达式); 这样的写法,在概念上是一种坏习惯,在 C 语言中,xxx() 出现,代表的是对 xxx() 函数的调用,上面的写法好像就是在说 return 是函数名称,而实际上,return 是关键字!


(2)、关于 return

A、它是函数运行结束的语句,在这条语句后出现的任何其它语句,是绝对不会运行到的。

1if (条件) {
2    return ;
3}
4语句1;
5//明显,只有条件不成立,才能执行语句1
6}


B、所谓的函数运行结束的 return(返回),是“返回”到调用它的函数的下一条语句继续执行。


C、所谓的 return 表达式; 意思是,返回到主调函数,并用“表达式”的值,替代主调函数中,关于这个函数的调用部分内容。


函数调用:

 1#include <stdio.h>
2
3int add (int a, int b);   //函数声明
4int add (int a, int b) {  //函数定义
5    return a + b;
6}
7int main (void) {
8    int a;
9    int b;
10    int sum;
11
12    scanf("%d%d", &a, &b);
13    sum = add(a, b);  //函数调用
14
15    return 0;
16}


形参与实参


1、

形参与实参的定义

A、形参出现在函数定义的“函数首部”的括号中;

B、实参出现在函数调用的括号中;

C、实参有三种形式:常量、变量、表达式;

D、形参只有一种形式:变量。

 1int fun (int num);
2int fun (int num) {  //这个 num 就是形参   这块是函数定义
3   ...
4}
5
6int main (void) {
7    int a;
8
9    a = fun(5);  //这个 5 就是实参   这块是函数调用
10}


形参只有变量这一种形式,不可能出现常量,甚至不可能出现数组!


2、

(1)、形参与实参之间的关系

A、个数一致;

B、按位置关系必须对应;

C、数据类型必须一致;

D、

值传递


将实参表达式的值,复制一份,赋值给形参变量!


(2)、私有变量

在一个函数的函数体中定义的变量,以及该函数的所有形参变量,都是这个函数的私有变量。


一个函数只能使用、调用这个函数的私有变量和“公有变量”,绝对不能直接使用其它函数的私有变量(包括数组)。


私有变量是在定义这个变量的函数被调用时,才申请存储空间;私有变量(尤其是形参变量)的空间,与其它函数的私有变量的空间,是没有任何关系的,即,其空间是独立申请的。


私有变量将随着定义它的函数的运行结束,而释放其空间。


(3)、形参不能修改实参的值

被调函数对形参变量所进行的任何修改,绝对不会更改与其对应的实参的值,这就是“值传递”的必然结果!!!


对形参变量所进行的任何修改,绝对不会更改实参表达式的值 !


C 语言中,“指针”存在的理由:

最核心的原因:C 语言是一个函数语言,没有过程这个概念,就需要指针传变量的地址,才能对变量进行修改!


函数特点


1、

C 语言函数的重要特点

A、高度的独立性:任何函数只能引用属于自己的私有变量和全局变量,绝对不能直接引用其它函数的私有变量;这意味着,不能在被调函数中,直接修改主调函数的私有变量的值;


B、函数返回值最多只有一个,若需要通过被调函数同时得到多个结果,那是行不通的;


C、函数的参数(实参与形参)的关系,在 C 语言函数中,只有一种:值传递(传递的是值,只不过这个值可能是普通的值,也可能是地址值),且这种传递方式所产生的必然结果是:对被调函数的形参变量所进行的任何更改,绝对不会影响主调函数的实参的值!


上述三个特点,将对 C 语言函数的功能产生巨大的束缚:在上述情况存在的前提下,C 函数是无法实现:“同时更改主调函数中多个私有变量的值”的功能!


2、

指针的概念,就是为了解决上述 C 语言“致命”问题而提出来的!


指针解决上述问题的具体方法:

A、将需要更改的变量(空间)的首地址作为实参;

B、被调函数对应的形参变量必须是上述变量的指针类型进行接收,这将使被调函数的形参变量“指向”主调函数中,需要更改的那个变量;

C、在被调函数中,通过 * (指向)运算,间接地修改主调函数相关变量的值。

 1void fun (int *);
2void fun (int *num) {
3    *num = 5;  //通过指针修改 a 空间的值,进行了指向运算 
4}
5
6int main (void) {
7    int a = 6;
8
9    fun(&a);  //传的是 a 空间的地址
相关阅读