黑马编程员--函数的基本知识总结

来源:互联网 发布:mac可以玩什么国内网游 编辑:程序博客网 时间:2024/04/29 14:13

                               ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 

                                                            函数的使用

   

1. 模块化

    C语言是国内外广泛使用的一种计算机语言,是计算机应用人员应掌握的一种程序设计工具。C语言是一种高级语言,采用结构化的程序设计方法:自顶向下、逐步细化、模块化设计、结构化编码。程序中的模块化在C语言中通常用函数来实现,在程序设计中常采用模块设计的方法,尤其是当程序比较复杂时,更有必要。在遇到一个大任务时,一般把它分为若干个小的子任务,每一个子任务就相对简单了。这些子任务就可以看作模块,每个模块完成特定的功能,按照一定的顺序执行这些模块,这个大任务就能顺利完成。在C语言中,可用函数来实现模块的功能。一个C程序可由一个主函数和若干个函数构成,由主函数调用其他函数,其他函数之间也可互相调用,同一个函数也可被一个或多个函数调用任意次。

       要想掌握函数,必须掌握函数的三大操作:定义、声明和调用

2. 函数的定义

       函数定义的一般形式:

       类型标识符 函数名(形式参数表列)

       {

              声明部分

              语句

函数的类型标识符是函数要返回的数据的类型,函数的形式参数是函数要进行数据处理时,需要从主调函数里获取的值。例:用函数实现计算两个整数的和。

因为函数的功能是计算两个整数的和,首先要涉及到两个整数,而这两个整数不是固定的,要把这两个整数作为函数的形式参数;而最后得到的结果是这两个整数的和,要返回到主调函数,所以函数的类型标识符也应该是整型;而函数的功能则是把这两个整数相加,利用return语句返回两个整数的和。

函数的定义如下:

int add(int x,int y)

{

  int z;

  z=x+y;

  return z;

}

       (1)函数的名字是add,函数起名时也要遵循C语言标识符的规定;

       (2)函数的形式参数(简称“形参”)是x和y两个整数;

       (3)函数的功能是计算x+y的值,并把它的值赋给z,然后将z值返回;

       (4)因为z值是整数,所以函数的类型设置为int。

3. 函数的分类

   
(1)C语言的函数兼有其它语言中的函数和过程两种功能,从这个角度看,又可把函数分为有返回值函数和无返回值函数两种。 

有返回值函数 此类函数被调用执行完后将向调用者返回一个执行结果, 称为函数返回值。如数学函数即属于此类函数。 由用户定义的这种要返回函数值的函数,必须在函数定义和函数说明中明确返回值的类型。 无返回值函数 此类函数用于完成某项特定的处理任务, 执行完成后不向调用者返回函数值。这类函数类似于其它语言的过程。 由于函数无须返回值,用户在定义此类函数时可指定它的返回为“空类型”, 空类型的说明符为“void”。
(2)从主调函数和被调函数之间数据传送的角度看又可分为无参函数和有参函数两种。 
无参函数 函数定义、函数说明及函数调用中均不带参数。 主调函数和被调函数之间不进行参数传送。 此类函数通常用来完成一组指定的功能,可以返回或不返回函数值。 有参函数 也称为带参函数。在函数定义及函数说明时都有参数, 称为形式参数(简称为形参)。在函数调用时也必须给出参数, 称为实际参数(简称为实参)。 进行函数调用时,主调函数将把实参的值传送给形参,供被调函数使用。


4. 函数的声明

       在主调函数中一般要写上被调用函数的声明,除非被调用函数在主调函数前被定义。函数的声明是把函数的名字、函数的类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时系统按照此进行对照检查。上面函数例子的声明就是:int add(int x,int y); 有时在函数声明中可以不写形参名,只写形参的类型,称为函数的原型:int add(int,int);

a.函数的定义和声明的区别

声明:一般在头文件里,对编译器说:这里我有一个函数叫function() 让编译器知道这个函数的存在。声明是告诉编译器有这么个变量,但并不实现。

定义:就是实现这个变量,真正在内存(堆或栈中)为此变量分配空间。定义一般在源文件里,具体就是函数的实现过程,写明函数体。

对函数的“定义”和“声明”不是一回事。“定义”是指对函数功能的确立,包括指定函数名,函数值类型、形参类型、函数体等,它是一个完整的、独立的函数单位。而“声明” 的作用则是把函数的名字、函数类型以及形参类型、个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查(例如函数名是否正确,实参与形参的类型和个数是否一致)。

从程序中可以看到对函数的声明与函数定义中的函数首部基本上是相同的。因此可以简单地照写已定义的函数的首部,再加一个分号,就成为了对函数的“声明”。在函数声明中也可以不写形参名,而只写形参的类型。

在C语言中,函数声明称为函数原型(function prototype)。使用函数原型是ANSI C的一个重要特点。它的作用主要是利用它在程序的编译阶段对调用函数的合法性进行全面检查。

注意:

(1) 实际上,如果在函数调用前,没有对函数作声明,则编译系统会把第一次遇到的该函数形式(函数定义或函数调用)作为函数的声明,并将函数类型默认为int 型。如一个max函数,调用之前没有进行函数声明,编译时首先遇到的函数形式是函数调用"max(a, b)",由于对原型的处理是不考虑参数名的,因此系统将max()加上int作为函数声明,即int max(); 因此,如果函数类型为整型,可以在函数调用前不必作函数声明。但是使用这种方法时,系统无法对参数的类型做检查。或调用函数时参数使用不当,在编译时也不会报错。因此,为了程序清晰和安全,建议都加以声明为好。

(2) 如果被调用函数的定义出现在主调函数之前,可以不必加以声明。因为编译系统已经先知道了已定义的函数类型,会根据函数首部提供的信息对函数的调用作正确性检查。

(3) 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调用函数中不必对所调用的函数再作声明。

b.C语言中头文件和源文件写法的区别

相同点: 头文件与源代码都是源文件,都用纯文本文件存储,都需要遵照C/C++语言规范来写,都可以使用类型定义和常、变量定义,都可以包含函数的声明和实现,都能包含宏定义,都使用相同的调用规范。

不同点: C/C++的编译器规定源代码文件必须包含函数入口,即main函数,或者winmain函数。而头文件不得包含函数入口,也就是说,头文件不可以单独编译成一个程序,仅仅包含程序片断或者仅仅定义常、变量。

关联: 头文件是专为源代码调用而写的静态包含文件,可被源代码文件中的#include编译预处理指令解释,而将头文件完整拷贝到源代码的指令处,从而在编译时相当于在源代码中插入了函数声明或者实现。

某些头文件包含了静态库中的函数调用声明,包含了LIB文件的调用信息,编译时静态链接进程序;而某些头文件是专为方便API调用而写的,里面包含了动态链接库的调用信息和规范,只有在运行时将DLL载入内存提取函数执行。

也就是说,其实你将头文件里的信息完全写到源代码里,是可以实现完全相同的功能的。如果你想要学写头文件,可以参照标准C/C++库的h文件


5. 函数的调用

       对函数的调用也是函数功能的实现。函数调用的一般形式为:函数名(实参表列); 函数的实参是真正进行计算的数据,一般都有具体的数据。实参可以没有,但括弧不能省略。各实参之间用逗号间隔,实参与形参按顺序对应,一一传递数据。

       例:对上述函数的调用

       void main()

       {

              int a,b,c;

              scanf(“%d,%d”,&a,&b);

              c=add(a,b);

              printf(“%d”,c);

}

在此程序中:

(1)a和b为实参,从键盘上输入,有固定的值;

(2)调用add(a,b)函数时,把实参的值按照顺序对应一一传递给形参,即有x=a,y=b;

(3)函数add通过形参得到实参的值后,进行运算z=x+y; 得到两个整数的和;

(4)再通过return语句将z的值返回到主调函数;

(5)主调函数通过调用add(a,b)得到z的值,并将它赋值给c,得到了两个整数a,b的和。

6. 如何编写函数

       编写函数时最主要的是函数的定义,因为函数的定义决定了函数声明和函数调用的格式,而函数的定义主要掌握函数的输入、输出和处理。

       (1)函数的输入,一般指函数的形参,即希望函数对哪些数据进行处理,这些数据大都要作为函数的形参而参与计算;

       (2)函数的输出,一般指函数的返回值,即希望函数调用后得到的数值;

       (3)函数的处理,一般函数内部所实现的功能,即通过何种算法利用形参的值得到返回值。

       在编写函数时,一般要确定好函数的输入、输出和处理。

比如:利用函数计算n!的运算。

       分析这个问题,可以得到:

       (1)函数的输入是n,是一个整数;

       (2)函数的输出是n!,也是一个整数;

       (3)函数的处理,是进行1*2*3*……*n的运算得到n!的值,可用for循环进行计算。

       根据上述分析,编写函数时,首先给函数起一个名字,要做到“见名知义”。可以给函数起一个名字:jiancheng;函数的形参是一个整数,可命名为n;函数的返回值是一个整数,但这个整数的值可能会很大,它的数据类型可以设置为长整型,以满足计算的要求。如此,函数的定义如下:

      

long jiancheng(int n)

{

       long nn;   //因此返回值为长整型数,首先定义一个长整型变量nn,来存储n!的值

//然后在程序的最后一条语句中写上return nn语句,再写中间的语句

       int i;

       nn=1;

       for(i=2;i<=n;i++) //利用for循环计算n!

              nn=nn*i;

return nn;              //返回n!

}

       函数定义好以后,就可以在其他函数中任意次地进行调用。

void main()

{

       int j;

       for(j=1;j<=10;j++)

       { printf(“%ld\n”,jiancheng(j)); }

}

       这个函数实现的功能是在屏幕上输出1!,2!,……,10!, jiancheng函数被调用了10次,每一次调用函数的实参都不相同。

                 ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

0 0
原创粉丝点击