zoukankan      html  css  js  c++  java
  • 115.C语言_函数

    第六章 函数

    • 6.2 函数定义的一般形式
      • 函数的定义
        • C语言中函数定义的一般形式如下:
          • 函数返回值的类型名  函数名(类型名  形式参数1,类型名  形式参数2, … )
          • {
          • 说明部分;
          • 语句部分;
          • }
      • 说明:
        • 函数名和各个形式参数都是由用户命名的合法标识符,与普通变量名的定义规则相同。在同一程序中,函数名必须唯一,不能出现重名的情况。形式参数名只要在同一函数中唯一即可,由于形式参数的作用域不相同,因此形式参数名可以与其他函数中的变量名同名。C语言规定,不能在一个函数内部再定义函数,也就是说函数不能嵌套定义。
        • 若在函数的首部省略了函数返回值的类型名,可以把函数首部写成:
          • 函数名(类型名形式参数1 ,类型名 形式参数2 ,…,类型名 形式参数n)
        • 紧跟在函数名之后的圆括号中的内容是形式参数和类型说明表,在每个形参之前都要有类型名,以标识形式参数的类型。各形参的定义之间用逗号分隔。
          • 例如,求两整数和的函数:
            • int  add(int a ,int b)
            • {
            • intt;       /* 函数体中声明部分 */
            • t=a+b;
            • return t;
            • }
        • 若所定义的函数没有形参,函数名后的一对圆括号依然不能省略。本例中函数体中的语句是用来完成求和的功能。在某些情况下,函数体可以是空的,例如:
          • fun()
          • {  }
          • 该函数中没有任何语句,什么工作也不做,没有任何实际作用。之所以要在主调函数上这样写,是为了表明此处要调用一个函数,而现在这个函数的具体功能可能还没有设计好,没有起作用,等以后扩充函数功能时补充上即可。
        • 在函数体中,除形参外,用到的其他变量必须在说明部分进行定义,这些变量(包括形参)只在函数被调用时才被临时分配内存单元,当退出函数时,这些临时开辟的存储单元全部被释放掉,即在该函数体内部定义的变量都将不存在。因此,这些变量只在函数体内部起作用,与其他函数体内的变量并不相关。
    • 6.3 函数参数和函数返回值
      • 6.3.1 形式参数和实际参数
        • 定义
          • 在程序中调用函数时,绝大多数情况下,主调函数和被调函数之间会发生数据传递关系,这就要用到前面提到的有参函数。在定义函数时,函数名后面括号中的变量称为“形式参数“(简称“形参“);在主调函数中,函数名后面括号中的参数(可以是一个表达式)称为“实际参数“(简称“实参“)。
        • 说明:
          • (1)实参可以是常量、变量或表达式。
          • (2)在被定义的函数中必须指定形参类型。
          • (3)实参与形参的类型应相同或赋值相兼容。
          • (4)C语言规定,实参变量对形参变量的数据传递是“值传递“,即单向传递。只能由实参传给形参,而不能由形参返回来给实参。在内存中,实参单元与形参单元是不同的单元。
          • (5)在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参。调用结束后,形参单元被释放,实参单元仍保留并维持原值。
          • (6)一定要注意参数之间的传递,实参和形参之间 传数值,和传地址的差别。传数值的话,形参的变化不会改变实参的变化。传地址的话,形参的变化就会有可能改变实参的变化。
      • 6.3.2 函数的返回值
        • 函数的返回值就是通过函数调用使主调函数能得到一个确定的值。函数的值通过return语句返回,return语句的形式如下:
          • return 表达式;
          • 或return(表达式);
          • 或return;
        • return 语句中的表达式的值就是所求的函数值。此表达式值的类型必须与函数首部所说明的类型一致。若类型不一致,则以函数值的类型为准,由系统自动进行转换。
          • 例如 通过函数调用的方法求1到自然数n(n>1)自然数的和,有程序段如下
            • #include<stdio.h>
            • ints(int n)
            • {
            • int i,sum=0;
            • for(i=1;i<=n;i++)
            • sum+=i;
            • return sum;
            • }
            • main()
            • {
            • int n;
            • printf("input number ");
            • scanf("%d",&n);
            • n=s(n);
            • printf("1到n的和为:%d ",n);
            • }
    • 6.4 函数的调用
      • 6.4.1 函数调用的一般形式
        • 函数名(实参表列);
        • 函数的调用可以分为调用无参函数和调用有参函数两种,如果是调用无参函数,则不用“实参表列“,但括号不能省略。在调用有参函数时,若实参列表中有多个实参,各参数间用逗号隔开。实参与形参要求类型一致。
      • 6.4.2 函数调用的方式
        • (1)函数语句。把函数调用做为一个语句,这时该函数只需要完成一定的操作而不必有返回值。
        • (2)函数表达式。当一个函数出现在一个表达式中,该表达式就被称为函数表达式。因为要参与表达式中的计算,所以要求该函数有一个确定的返回值提供给表达式。
        • (3)函数参数。函数调用做为一个函数的实参。
      • 6.4.3 C语言中,调用函数和被调用函数之间的数据可通过3种方式进行传递。
        • (1)实参与形参之间进行数据传递。
        • (2)通过return语句把函数值返回到主调用函数中。
        • (3)通过全局变量。
      • 6.4.3  函数的递归调用
      • 函数的递归调用一定要记得有结束的条件
      • 在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。允许函数的递归调用是C语言的特点之一。
      • 当一个问题在采用递归法解决时,必须符合以下3个条件:
      • (1)可以把要解决的问题转化为一个新的问题。而这个新的问题的解决方法仍与原来的解决方法相同,只是所处理的对象有规律地递增或递减。
      • (2)可以应用这个转化过程使问题得到解决。
      • (3)必须要有一个明确的结束递归的条件。
      • 当函数自己调用自己时,系统将自动把函数中当前的变量和形参暂时保留起来,在新一轮的调用过程中,系统将为本次调用的函数所用到的变量和形参,开辟新的存储单元。因此,递归调用的层次越多,同名变量所占的存储单元也就越多。当本次调用的函数运行结束时,系统将释放本次调用所占的存储单元。当程序执行的流程返回到上一层的调用点时,同时取用进入该层函数中的变量和形参所占用的存储单元中的数据。
    • 6.5 函数的说明
      • 6.5.1  形式
        • 概念
          • C语言中,除了主函数外,对于用户定义的函数要遵循先定义后使用的规则。把函数的定义放在调用之后,应该在调用之前对函数进行说明(或函数原型说明)。
        • 函数说明的一般形式如下:
          • 类型名 函数名(参数类型1 ,参数类型2 ,…,参数类型n);
              • intadd(int  ,int  );
          • 类型名 函数名(参数类型1 参数名1,参数类型2 参数名2 ,…,参数类型n  参数名n);
            • 此处的参数名完全是虚设的,它们可以是任意的用户标识符,既不必与函数首部中的形参名一致,又可以与程序中的任意用户标识符同名,实际上参数名常常省略。函数说明语句中的类型名必须与函数返回值的类型一致。
        • 函数说明可以是一条独立的语句。对函数进行说明,能使C语言的编译程序在编译时进行有效的类型检查。当调用函数时,若实参的类型与形参的类型不能赋值兼容而进行非法转换,C编译程序将会发现错误并报错;当实参的个数与形参的个数不同时,编译程序也将报错。
      • 6.5.2函数说明的位置
        • 一个函数在所有函数的外部,如在被调用之前说明,则在说明后的所有位置上都可以对该函数进行调用。如在main()函数内部进行说明,则只能在main()函数内部才能识别。
        • 例如 调用求和函数输出1到n的和值,程序段如下:
          • #include<stdio.h>
          • main()
          • {
          • int n;
          • int s(int n);
          • printf("input number ");
          • scanf("%d",&n);
          • s(n);
          • printf("n=%d ",n);
          • }
          • ints(int n)
          • {
          • int i,sum=0;
          • for(i=1;i<=n;i++)
          • sum+=i;
          • printf("1到n的和值为:%d ",n);
          • }
      • 一定要有:函数名,函数的返回类型,函数的参数类型。不一定要有:形参的名称。
    • 6.6 常用函数
      • 6.6.1  字符串 <string.h>
        • 6.6.1.1  strlen 计算长度
        • 6.6.1.2  strcmp 比较
        • 6.6.1.3  strcpy 复制 (不安全,越界)
        • 6.6.1.4  strcat 追加 (不安全,越界)
      • 6.6.2  数学函数<math.h>
        • 6.6.2.1   向上,向下取整
          • 函数名: ceil
            • 功能:向上取整
            • 用法: double ceil(double x);
          • 函数名: floor
            • 功能:向下取整
            • 用法: double floor(double x);
        • 6.6.2.2  取绝对值
          • 函数名:abs
            • 功能:返回整型数的绝对值.
            • 用法:abs(number)
            • number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回Null;如果是未初始化变量,则返回 0.
          • 函数名:fabs
            • 功能:求浮点数x的绝对值.
            • 用法:fabs  (double x);
        • 6.6.2.3  平方根
          • 函数名:sqrt
            • 功能:返回指定数字的平方根.
            • 用法:sqrt  (double x);
        • 6.6.2.4  求幂
          • 函数名:exp
            • 功能:返回 e 的 n 次幂.
            • 用法:exp  (double x);
          • 函数名:pow
            • 功能:返回指定数字的指定次幂.
            • 用法:pow   (double x, double y);(将返回x的y次幂)
        • 6.6.2.5  取余
          • 函数名: fmod
            • 功  能: 计算x对y的模, 即x/y的余数
            • 用  法:double fmod(double x, double y);
        • 6.6.2.6  对数
          • 函数名:log
            • 功能: 自然对数函数ln(x)
            • 用法: double log(double x);
          • 函数名:log10
            • 功能:返回以 10 为底的对数.
            • 用法:log10(double x);
        • 6.6.2.7  三角函数:(所有参数必须为弧度)
          • sin
            • 函数声明:sin  (double x);
            • 用途:用来返回给定的 X 的正弦值。
          • cos
            • 函数声明:cos  (double x);
            • 用途:用来返回给定的 X 的余弦值。
          • tan
            • 函数声明:tan   (double x);
            • 用途:用来返回给定的 X 的正切值。
        • 6.6.2.8  反三角函数
          • acos
            • 函数申明:acos  (double x);
            • 用途:用来返回给定的 X 的反余弦函数。
          • asin
            • 函数申明:asin  (double x);
            • 用途:用来返回给定的 X 的反正弦函数。
          • atan
            • 函数申明:atan  (double x);
            • 用途:用来返回给定的 X 的反正切函数。
          • atan2
            • 函数声明:atan2 (double y, double x);
            • 用途:返回给定的 X 及 Y 坐标值的反正切值
        • 6.6.2.9  双曲函数
          • 函数名:cosh
            • 功能:返回指定角度的双曲余弦值.
            • 用法:Double Cosh(double x(以弧度计量的角度)) ;
          • 函数名:sinh
            • 功能:返回指定角度的双曲正弦值。
            • 用法:sinh (double x);(其中参数x必须为弧度制)
          • 函数名:tanh
            • 功能:回指定角度的双曲正切值.
            • 用法:tanh  (double x);
        • 6.6.2.10  实型数分整数和小数
          • 函数名:modf
            • 功  能: 把数分为整数部分和小数部分
            • 用  法: double modf(doublevalue, double *iptr);
            • eg
              • 1.  #include<math.h>
              • 2.
              • 3.  #include<stdio.h>
              • 4.
              • 5.  int main(void)
              • 6.
              • 7.  {
              • 8.
              • 9.  double fraction,integer;
              • 10.
              • 11. double number =100000.567;
              • 12.
              • 13. fraction =modf(number, &integer);
              • 14.
              • 15. printf("Thewhole and fractional parts of %lf are %lf and %lf ",
              • 16.
              • 17. number, integer,fraction);
              • 18.
              • 19. return 0;
              • 20.
              • 21. }
              • The whole andfractional parts of 100000.567000 are 100000.000000 and 0.567000
        • 6.6.2.11  随机数
          • 在编程的时候需要电脑来获取一些随机的反应,这个时候我们可以使用随机数,比较常见的是 rand() 函数,它可以随机的产生 0 ~rand_max 的随机数。rand_max 是一个很大的数字,具体关系到IDE和数据类型,我们一般的需要不可能超出它的范围
          • C语言中还有一个 random() 函数可以获取随机数,但是 random() 函数不是ANSI C标准,不能在VC等编译器通过,所以比较少用。
          • eg
            • int a=rand()%10; //产生0~9的随机数,注意10会被整除
            • int a=rand()%51+13; //产生13~63的随机数
            • 产生 13~63 范围内随机数的完整代码:
              • 1.      #include <stdio.h>
              • 2.      #include <stdlib.h>
              • 3.      #include <time.h>
              • 4.      int main(){
              • 5.      int a;
              • 6.      srand((unsigned)time(NULL));
              • 7.      a=rand()%51+13;
              • 8.      printf("%d ",a);
              • 9.      return 0;
              • 10.  }
            • 下面是一个实例:
              • 1.      #include <stdio.h>
              • 2.      #include <stdlib.h>
              • 3.      int main(){
              • 4.      int a=rand();
              • 5.      printf("%d ",a);
              • 6.      return 0;
              • 7.      }
              • 编译后再运行几次,你会发现产生的随机数是相同的。实际上,rand() 函数产生的随机数是伪随机数,是根据一个数按照某个公式推算出来的,这个数我们称之为“种子”,但是这个种子在系统启动之后就是一个定值,我们需要用 srand() 来进行播种,即在int a前加一句:
                • 1.      srand((unsigned)time(NULL)); //这里利用时间进行播种,需要time.h
        • sqrt( ) fabs( )  pow( )  sin( )
      • 6.6.3 malloc
        • malloc的返回类型是 void *
          • int  *p;
          • p = (int *)malloc(2);
          • p = (int *)malloc(sizeof(int));以上两个等价

  • 相关阅读:
    剑指offer 31.时间效率 整数中1出现的次数(从1到n整数中1出现的次数)
    剑指offer 30.时间效率 连续子数组的最大和
    ElasticSearch 数据路由原理+增删改查内部原理+写一致性原理以及quorum机制
    剑指offer 29.时间效率 最小的K个数
    剑指offer 28.时间效率 数组中出现次数超过一半的数字
    剑指offer 27.分解让复杂问题简单 字符串的排列
    ElasticSearch 并发冲突+悲观锁与乐观锁+基于_version和external version进行乐观锁并发控制
    剑指offer 26.分解让复杂问题简单 二叉搜索树与双向链表
    Spfa+DP【p2149】[SDOI2009]Elaxia的路线
    Dfs【bzoj3252】攻略
  • 原文地址:https://www.cnblogs.com/ZanderZhao/p/10013891.html
Copyright © 2011-2022 走看看