• 网络学院
  • IT资讯
  • 操作系统
  • 网络技术
  • 软件应用
  • 办公软件
  • 编程技术
  • 网站架设
  • 数据库类
  • 平面设计
  • 多媒体类
  • 游戏资讯
  • 教学论文
  • 认证考试
C语言教程连载--第五章
  站点:
  • 首 页
  • 最新软件
  • 文章教程
  • 国内软件
  • 国外软件
  • 绿色软件
  • 源码下载
  • 字体下载
C语言教程连载--第五章 函数
软件发布 C语言教程连载--第五章 函数
网络软件 系统工具 应用软件 联络聊天 图形图像 多媒体类 行业软件 游戏娱乐 编程开发 安全相关 教育教学 数码软件 绿软下载
热门软件: QQ 瑞星 pplive e话通 木马克星 千千静听 office2000 五笔字根 Photoshop 视频分割
返回文章教程首页 >> 认证考试 >> 计算机等级考试 >> 计算机等级考试动态 >> C语言教程连载--第五章 函数

C语言教程连载--第五章 函数

添加时间: 2007-5-25 6:58:27  作者: 计算机等级考试认证参考  阅读次数:60   来源: http://www.d9soft.com

       

 
第五章   函数 

    C程序是由一组或是变量或是函数的外部对象组成的。 函数是一个自我包含的完成一定相关功能的执行代码段。我们可以把函数看成一个"黑盒子", 你只要将数据送进去就能得到结果, 而函数内部究竟是如何工作的的, 外部程序是不知道的。外部程序所知道的仅限于输入给函数什么以及函数输出什么。函数提供了编制程序的手段, 使之容易读、写、理解、排除错误、修改和维护。 
    C程序中函数的数目实际上是不限的, 如果说有什么限制的话, 那就是, 一个C程序中必须至少有一个函数, 而且其中必须有一个并且仅有一个以main为名, 这个函数称为主函数, 整个程序从这个主函数开始执行。 
    C 语言程序鼓励和提倡人们把一个大问题划分成一个个子问题, 对应于解决一个子问题编制一个函数, 因此, C 语言程序一般是由量的小函数而不是由少量大 函数构成的, 即所谓"小函数构成大程序"。这样的好处是让各部分相互充分独立, 并且任务单一。因而这些充分独立的小模块也可以作为一种固定规格的小"构件", 用来构成新的大程序。 
    C语言的一个主要特点是可以建立库函数。Turbo C2.0提供的运行程序库有400多个函数, 每个函数都完成一定的功能, 可由用户随意调用。这些函数总的分为输入输出函数、数学函数、字符串和内存函数、与BIOS和DOS有关的函数、 字符屏幕和图形功能函数、过程控制函数、目录函数等。对这些库函数应熟悉其功能, 只有这样才可省去很多不必要的工作。 
    本教程后半部分专门介绍Turbo C2.0的库函数, 并对每个函数都给出例程, 读者可以将自已需要的部分以块的方式定义, 然后将此块写入文件, 这样就可以在进入Turbo C2.0集成开发环境后, 直接调用此程序, 连接, 运行, 观察结果, 以加深对该函数的理解。用户名Turbo C语言源程序, 就是利用Turbo C的库函数。可以把所有使用的库函数放在一个庞大的主函数里, 也可以按不同功能设计成一个个用户函数而被其它函数调用。Turbo C2.0建议用户使用后者, 当用户编制了一些较常用的函数时,只要将其存在函数库里, 在以后的编程中可被方便的调用而不需要再去编译它们。 
连接时将会自动从相应的库中装配成所需程序。 

    1. 函数的说明与定义 
    Turbo C2.0中所有函数与变量一样在使用之前必须说明。所谓说明是指说明函数是什么类型的函数, 一般库函数的说明都包含在相应的头文件<*.h>中,  例如标 
准输入输出函数包含在stdio.h中, 非标准输入输出函数包含在io.h中,  以后在使用库函数时必须先知道该函数包含在什么样的头文件中, 在程序的开头用#include<*.h>或#include"*.h"说明。只有这样程序在编译, 连接时Turbo C 才知道它是提供的库函数, 否则, 将认为是用户自己编写的函数而不能装配。 

    1.1 函数说明 

    1. 经典方式 
         其形式为:  函数类型   函数名(); 
    2. ANSI 规定方式 
         其形式为:  函数类型  函数名(数据类型  形式参数,  数据类型  形式   参数, ......);

    其中: 函数类型是该函数返回值的数据类型, 可以是以前介绍的整型(int),长整型(long), 字符型(char), 单浮点型(float), 双浮点型(double)以及无值型(void), 也可以是指针, 包括结构指针。无值型表示函数没有返回值。 
    函数名为Turbo C2.0的标识符, 小括号中的内容为该函数的形式参数说明。可以只有数据类型而没有形式参数, 也可以两者都有。对于经典的函数说明没有参数信息。如: 
      
    int putlll(int x,int y,int z,int color,char *p)/*说明一个整型函数*/ 
     char *name(void);               /*说明一个字符串指什函数*/ 
     void student(int n, char *str); /*说明一个不返回值的函数*/ 
     float calculate();              /*说明一个浮点型函数*/ 
    注意: 如果一个函数没有说明就被调用, 编译程序并不认为出错, 而将此函数默认为整型(int)函数。因此当一个函数返回其它类型, 又没有事先说明,  编译时将会出错。 

    1.2 函数定义 

    函数定义就是确定该函数完成什么功能以及怎么运行, 相当于其它语言的一个子程序。Turbo C2.0对函数的定义采用ANSI规定的方式。即: 
       函数类型  函数名(数据类型形式参数; 数据类型 形式参数...) 
      { 
          函数体; 
       } 
    其中函数类型和形式参数的数据类型为Turbo C2.0的基本数据类型。函数体为Turbo C2.0提供的库函数和语句以及其它用户自定义函数调用语句的组合, 并包括在一对花括号"{"和"}"中。 
    需要指出的是一个程序必须有一个主函数, 其它用户定义的子函数可以是任意多个, 这些函数的位置也没有什么限制, 可以在main()函数前,  也可以在其后。Turbo C2.0将所有函数都被认为是全局性的。而且是外部的, 即可以被另一个文件中的任何一个函数调用。 

    2 函数的调用 

    2.1  函数的简单调用 
    Turbo C2.0调用函数时直接使用函数名和实参的方法, 也就是将要赋给被调用函数的参量, 按该函数说明的参数形式传递过去, 然后进入子函数运行, 运行结束后再按子函数规定的数据类型返回一个值给调用函数。使用Turbo C2.0的库函数就是函数简单调用的方法。举例说明如下: 
    例1: 
     #include 
     int maxmum(int x, int y, int z);   /*说明一个用户自定义函数*/ 
     int main() 
&nbsp;    { 
          int i, j, k; 
          printf("i, j, k=? "); 
          scanf("%4d%4d%4d", &i, &j, &k);

          maxmum(i, j, k); 
          getch(); 
          return 0; 
     } 

     maxmum(int x, int y, int z) 
     { 
          int max; 
          max=x>y?x:y; 
          max=max>z?max:z; 
          printf("The maxmum value of the 3 data is %d ", max); 
     } 

    2.2 函数参数传递 

    一、调用函数向被调用函数以形式参数传递 
    用户编写的函数一般在对其说明和定义时就规定了形式参数类型, 因此调用这些函数时参量必须与子函数中形式参数的数据类型、顺序和数量完全相同, 否则在调用中将会出错, 得到意想不到的结果。 
    注意: 
    当数组作为形式参数向被调用函数传递时, 只传递数组的地址, 而不是将整个数组元素都复制到函数中去, 即用数组名作为实参调用子函数, 调用时指向该数组第一个元素的指针就被传递给子函数。因为在Turbo C2.0中, 没有下标的数组名就是一个指向该数组第一个元素的指针。当然数组变量的类型在两个函数中必须相同。 
    用下述方法传递数组形参。 
    例2: 
     #include 
     void disp(int *n); 
     int main() 
     { 
          int m[10], i; 
          for(i=0; i<10; i++) 
            m[i]=i; 
          disp(m);       /*按指针方式传递数组*/ 
      &nbsp;   getch(); 
          return 0; 
     } 
     void disp(int *n) 
     { 
          int j; 
          for(j=0; j<10; j++) 
            printf("%3d", *(n++)); 
          printf(" "); 
     } 
    另外, 当传递数组的某个元素时, 数组元素作为实参, 此时按使用其它简单变量的方法使用数组元素。例2按传递数组元素的方法传递时变为: 
     #include 
     void disp(int n); 
     int main() 
     { 
          int m[10], i;

          for(i=0; i<10; i++){ 
            m[i]=i; 
            disp(m[i]);  /*逐个传递数组元素*/ 
          } 
          getch(); 
          return 0; 
     } 
     void disp(int n) 
     { 
          printf("%3d "); 
     } 
这时一次只传递了数组的一个元素。 

    二、被调用函数向调用函数返回值 

    一般使用return语句由被调用函数向调用函数返回值, 该语句有下列用途: 
    1. 它能立即从所在的函数中退出, 返回到调用它的程序中去。 
    2. 返回一个值给调用它的函数。 
    有两种方法可以终止子函数运行并返回到调用它的函数中: 一是执行到函数的最后一条语句后返回; 一是执行到语句return时返回。前者当子函数执行完后仅返回给调用函数一个0。若要返回一个值, 就必须用return语句。只需在return 语句中指定返回的值即可。例1返回最大值时变为: 
     例3: 
     #includeO.H> 
     int maxmum(int x, int y, int z);   /*说明一个用户自定义函数*/ 
     int main() 
     { 
          int i, j, k, max; 
          printf("i, j, k=? "); 
          scanf("%4d%4d%4d", &i, &j, &k); 
          max=maxmum(i, j, k);     /*调用子函数, 并将返回值赋给max*/ 
          printf("The maxmum value is %d ", max); 
          getch(); 
          return 0; 
     } 

     maxmum(int x, int y, int z) 
     { 
          int max; 
          max=x>y?x:y;        /*求最大值*/ 
          max=max>z?max:z; 
          return(max);        /*返回最大值*/ 
     } 
    return语句可以向调用函数返回值, 但这种方法只能返回一个参数, 在许多情况下要返回多个参数, 这是用return语句就不能满足要求。Turob C2.0提供了另一种参数传递的方法, 就是调用函数向被调用函数传递的形式参数不是传递变量本身,而是传递变量的地址, 当子函数中向相应的地址写入不同的数值之后, 也就改变了调用函数中相应变量的值, 从而达到了返回多个变量的目的。 
     例4: 
     #include 
     void subfun(int *m, int *n);  /*说明子函数*/ 
     int main() 
     { 
          int i, j; 
          printf("i, j=? "); 
          scanf("%d, %d", &i, &amp;j); /*从键盘输入2个整数*/ 
          printf("In main before calling "/*输出此2数及其乘积*/ 
                 "i=%-4d j=%-4d i*j=%-4d ", i, j, i*j); 
          subfun(&i, &j);          /*以传送地址的方式调用子函数*/ 
          printf("In main after calling "/*调用子函数后输出变量值*/ 
                 "i=%-4d j=%-4d i*j=%-4d ", i, j, i*j); 
          getch(); 
          return 0; 
     } 
     void subfun(int *m, int *n) 
     { 
          *m=*m+2; 
          *j=*i-*j; 
          printf("In subfun after calling " /*子函数中输出变量值*/ 
                 "i=%-4d j=%-4d i*j=%-4d ", *i, *j, *i**j); 
      } 

    上例中, *i**j表示指针i和j所指的两个整型数*i和*j之乘积。 
    另外, return语句也可以返回一个指针, 举例如下。 
    下例中先等待输入一字符串, 再等待输入要查找的字符, 然后调用match() 函数在字符串中查找该字符。若有相同字符, 则返回一个指向该字符串中这一位置的指针, 如果没有找到, 则返回一个空(NULL)指针。 
    例5: 
     #include 
     char *match(char c, char *s); 
     int main() 
     { 
          char s[40], c, *str; 
          str=malloc(40);          /*为字符串指什分配内存空间*/

          printf("Please input character string:"); 
          gets(s);                 /*键盘输入字符串*/ 
          printf("Please input one character:"); 
          c=getche();              /*键盘输入字符*/ 
          str=match(c, s);         /*调用子函数*/ 
          putchar(’ ’); 
          puts(str);               /*输出子函数返回的指针所指的字符串*/ 
          getch(); 
          return 0; 
     } 
     char *match(char c, char *s) 
     { 
          int i=0; 
          while(c!=s[i]&&s[i]!=’ ’)/*找字符串中指定的字符*/ 
               i++; 
          return(&s[i]);           /*返回所找字符的地址*/ 
     } 


    三、用全程变量实现参数互传 
    以上两种办法可以在调用函数和被调用函数间传递参数, 但使用不太方便。如果将所要传递的参数定义为全程变量, 可使变量在整个程序中对所有函数都可见。这样相当于在调用函数和被调用函数之间实现了参数的传递和返回。这也是实际中经常使用的方法, 但定义全程变量势必长久地占用了内存。因此, 全程变量的数目受到限制, 特别对于较大的数组更是如此。当然对于绝大多数程序内存都是够用的。 
    例6: 
     #incluide 
     void disp(void); 
     int m[10];          /*定义全程变量*/ 
     int main() 
     { 
          int i; 
          printf("In main before calling "); 
          for(i=0; i<10; i++){ 
            m[i]=i; 
            printf("%3d", m[i]);   /*输出调用子函数前数组的值*/ 
          } 
          disp();                  /*调用子函数*/

          printf(" In main after calling "); 
          for(i=0; i<10; i++) 
            printf("%3d", m[i]);   /*输出调用子函数后数组的值*/ 
          getch(); 
          return 0; 
     } 
     void disp(void) 
     { 
          int j; 
          printf("In subfunc after calling ");/*子函数中输出数组的值*/ 
          for (j=0; i<10; j++){ 
               m[j]=m[j]*10; 
               printf("%3d", m[i]); 
          } 
     } 


    2.3 函数的递归调用  
   Turbo C2.0允许函数自己调用自己, 即函数的递归调用, 递归调用可以使程序  简洁、代码紧凑, 但要牺牲内存空间作处理时的堆栈。 
    如要求一个n!(n的阶乘)的值可用下面递归调用: 
    例8: 
      #include 
      unsigned ling mul(int n); 
      int main() 
     { 
          int m; 
          puts("Calculate n! n=? "); 
          scanf("%d", &m);         /*键盘输入数据*/ 
          printf("%d!=%ld ", m, mul(m));/*调用子程序计算并输出*/ 
          getch(); 
          retun 0; 
      } 
     unsigned long mul(int n) 
     { 
          unsigned long p; 
          if(n>1) 
               p=n*mul(n-1);       /*递归调用计算n!*/ 
          else 
               p=1L; 
          return(p);               /*返回结果*/ 
     }

运行结果: 
          calculate n!  n=? 
输入5时结果为: 
          5!=120 

    3. 函数作用范围 

    Turbo C2.0中每个函数都是独立的代码块, 函数代码归该函数所有, 除了对函数的调用以外, 其它任何函数中的任何语句都不能访问它。例如使用跳转语句goto就不能从一个函数跳进其它函数内部。除非使用全程变量, 否则一个函数内部定义的程序代码和数据, 不会与另一个函数内的程序代码和数据相互影响。 
    Turbo C2.0中所有函数的作用域都处于同一嵌套程度, 即不能在一个函数内再说明或定义另一个函数。 
    Turbo C2.0中一个函数对其它子函数的调用是全程的, 即是函数在不同的文件中, 也不必附加任何说明语句而被另一函数调用, 也就是说一个函数对于整个程序都是可见的。 

    4. 函数的变量作用域 
    在Turbo C2.0中, 变是可以在各个层次的子程序中加以说明, 也就是说, 在任何函数中, 变量说明有只允许在一个函数体的开头处说明, 而且允许变量的说明(包括初始化)跟在一个复合语句的左花括号的后面, 直到配对的右花括号为止。它的作用域仅在这对花括号内, 当程序执行到出花括号时, 它将不复存在。当然, 内  层中的变量即使与外层中的变量名字相同, 它们之间也是没有关系的。 
    例9. 
     #include 
     int i=10; 
     int main() 
     { 
          int i=1; 
          printf("%d , i); 
          { 
               int i=2; 
               pritnf("%d ", i); 
               { 
                    extern i; 
                    i+=1; 
                    printf("%d ", i); 
               } 
               printf("%d ", ++i); 
          } 
          printf("%d ", ++i); 
          return 0; 
     } 
运行结果为 
&nbsp;    1    2    11   3    2 
从程序运行的结果不难看出程序中各变量之间的关系, 以及各个变量的作用域。

    本节主要介绍Turbo C程序设计的基本步骤及如何编译、调试和运行源程序。并给出Turbo C的常用编辑命令。最后介绍Turbo C编译、连接和运行时的常见错误。 

    一、Turbo C程序设计基本步骤 

    程序设计方法包括三个基本步骤: 
    第一步:  分析问题。 
    第二步:  画出程序的基本轮廓。 
    第三步:  实现该程序。 
      3a. 编写程序 
      3b. 测试和调试程序 
      3c. 提供数据打印结果 
    下面, 我们来说明每一步的具体细节。 

    第一步: 分析问题 
    在这一步, 你必须: 
    a. 作为解决问题的一种方法, 确定要产生的数据(输出)。作为这一子步的一部分, 你应定义表示输出的变量。 
    b. 确定需产生输出的数据(称为输入), 作为这一子步的一部分,  你应定义表示输入的变量。 
    c. 研制一种算法, 从有限步的输入中获取输出。 这种算法定义为结构化的顺序操作, 以便在有限步内解决问题。就数字问题而言, 这种算法包括获取输出的计算, 但对非数字问题来说, 这种算法包括许多文本和图象处理操作。 

    第二步: 画出程序的基本轮廓 
    在这一步, 你要用一些句子(伪代码)来画出程序的基本轮廓。每个句子对应一个简单的程序操作。对一个简单的程序来说,  通过列出程序顺序执行的动作, 便可直接产生伪代码。然而, 对复杂一些的程序来说, 则需要将大致过程有条理地进行组织。对此, 应使用自上而下的设计方法。 
    当使用自上而下的设计方法时, 你要把程序分割成几段来完成。列出每段要实现的任务, 程序的轮廓也就有了, 这称之为主模块。当一项任务列在主模块时,仅用其名加以标识, 并未指出该任务将如何完成。这方面的内容留给程序设计的下一阶段来讨论。将程序分为几项任务只是对程序的初步设计。整个程序设计归结为下图所示的流程图1.。

用free()函数释放, 会导致函数前几次调用正常, 而后面调用时发生死机现象,不能返回操作系统。其原因是因为没用空间可供分配, 而占用了操作系统在内存中的某些空间。 

    9. 使用了动态分配内存不成功的指针, 造成系统破坏。

 

 

上下文章:

 

上一篇文章: C语言教程:第二章: 数据类型、运算符、表达式(6) 下一篇文章: C语言教程:第五章:函数(6)

相关文章:

  • 谷歌百科全书网站Knol推出多种语言服务
  • PS调色教程:教你调出婚片温柔暖色调
  • PS教程:打造都市颓废风格海报
  • PS教程:真人仿卡通手绘效果
  • 火星文:最时髦的网络语言

相关软件:

  • 易语言 V4.04 简体中文正式版
  • API拦截教程 V1.0
  • 脚本语言生成器 V2.5 Build 1050
  • 辰灿汇编语言集成开发环境 V1.0
  • 汇编语言学习工具 3.6
  • AI RoboForm Pass2Go(可携带版) 中文正式版/多国语言版 6.7.3

 

快速导航

  • 网络学院
  • 精品汇聚
  • 字体下载
  • 教程下载
  • ASP源码
  • PHP源码
  • Net源码
  • JSP 源码

计算机等级考试分类导航

  • 计算机等级考试动态
  • 计算机一级考试
  • 计算机二级考试
  • 计算机三级考试
  • 计算机四级考试

本类经典文章推荐

  • 全国计算机等级考试三级网络技术(...
  • 三级网络技术复习笔记(第1-2章)
  • 三级笔试样题(PC技术)
  • 三级数据库技术样题
  • 三级网络技术复习笔记(5-7)
  • 三级网络技术复习笔记(第3-4章)
  • 笔试样题(网络技术)
  • 机考如何避免范围性错误
  • 2003年最新三级网络模拟题(2)
  • 全国计算机等级考试三级网络技术部...

计算机等级考试动态阅读排行

  • 9月17日计算机等级考试二级VF答案
  • 完整的计算机等级考试上机模拟系统
  • 计算机等级考试:VFp练习题1
  • 全国计算机等级考试三级网络技术(...
  • 历年操作系统论述题及答案(2)
  • 计算机等级考试:VFp练习题2
  • 计算机二级VB软件环境、考试时间、...
  • 2005年全国计算机等级考试全真模拟...
  • 三级网络技术复习笔记(第1-2章)
  • 全国计算机等级考试报名时间、级别...

计算机等级考试阅读总排行

  • 全国计算机等级考试一级模拟试题01
  • 全国计算机等级考试一级模拟试题10
  • 全国计算机等级考试一级模拟试题08
  • 全国计算机等级考试一级考试最新模...
  • 全国计算机等级考试一级模拟试题02
  • 全国计算机等级考试一级模拟试题07
  • 全国计算机等级考试上机考试应试技...
  • 一级(WINDOWS)试题解析-Word篇
  • 全国计算机等级考试一级模拟试题06
  • 全国计算机等级考试一级模拟试题03

广告位置

字母检索 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 回到顶部

关于我们 | 版权声明 | 免责条款 | 广告联系 | 软件发布 | 下载帮助 | 下载排行 | 网站地图 | 特别鸣谢 | 友情连接

copyright; 2005-2008 D9soft.com 第九软件网 版权所有