关于c:C入门8函数

1次阅读

共计 5109 个字符,预计需要花费 13 分钟才能阅读完成。

Summary

1)C 语言中的函数次要有 2 种类型:

  • Function:数据处理(数据 –> 数据),通过某种规定由输出的数据失去输入数据
  • Procedure:过程定义(数据 –> 性能),(依据数据)执行一系列动作,进而实现某种性能

2)应用程序必须依附操作系统能力运行,应用程序承受操作系统的治理。当 操作系统运行程序时,首先调用的就是 main()函数 。)(main() 函数个别是第一个被调用的函数,也有其余办法能够让其余函数先于 main 执行)

3)应用程序执行的过程:(后续补上时序图)

  1. 用户双击.exe,或者在命令行中间接运行.exe
  2. OS 把应用程序加载到内存中:Load()
  3. OS 找到应用程序的 main()函数
  4. 执行 main()函数
  5. 敞开应用程序时,main()函数执行完结 返回一个值给操作系统 (在 windows 中,能够在命令行,应用echo %errorlevel% 命令查看刚刚命令执行的 exe 的返回值)

4)函数的调用过程:

  1. 暂停主调函数
  2. 跳转到被调函数,执行被调“函数体”
  3. 被调函数返回,复原执行主调函数

5)工具包就是一个函数集,蕴含了一系列定义好的函数。#inlude 语句用于申明,要应用工具包中的函数

6)void 是 C 语言中的一个根本类型,但void 不是根底数据类型,不能够用来定义具体变量

7)C 语言中如果想定义一个无参函数,必须应用 void 申明!如果函数参数列表什么都不写,示意承受任意多的参数。即:void f(void) --> 不承受参数void f() --> 几个参数都能够

8)对于 void f()无返回值函数,能够间接应用 return; 语句使函数间接返回

9)形参 :函数定义时的参数列表; 实参 :函数调用时指定的具体值;实参用来 初始化 形参(将实参的值 赋值 给形参),所以 形参相当于一个函数外部的变量 (函数参数的 实质是变量

10)C 语言中,当数组作为参数时,数组参数会进化为指针 ,数组大小无奈传递;此时 批改数组形参,会同时扭转数组实参的值

11)排序的要害操作:比拟 替换

12)全局变量不同同名,会产生命名抵触,报重定义的谬误;就近准则,存在多个同名变量时,优先应用最近定义的变量。

13)变量的 作用域指的是变量定义后的可拜访范畴 ;在重叠作用域中, 优先应用最近定义的 变量。

14)代码块 指的是从 { 开始到 } 完结的一段代码;局部变量的作用域 从定义开始,到以后代码块完结;

15)对于全局变量,存在两个作用域 全局作用域 文件作用域。全局作用域指的是在程序的各个角落都能够拜访到;文件作用域则只能在以后代码文件中拜访并应用;

16)计算机中,物理内存被分为不同区域,不同区域有不同的用处。全局数据区 用于寄存全局变量和动态变量; 区用于寄存局部变量和函数参数; 空间用于动态创建变量;

17)生命期 :变量从创立到销毁的工夫(非法可用的工夫)。 全局数据区的变量 :生命期从程序开始到程序完结; 栈区的变量:生命期从进入作用域开始,到作用域完结;

18)作用域和生命期没有实质分割:作用域是语法层面上 对变量是否可拜访的规定(空间上 ); 生命期是二进制层面上 变量存在于内存中的工夫(工夫上

19)static 润饰的变量位于 全局数据区static 润饰的全局变量只有文件作用域static 局部变量只会初始化一次,作用域依然是所在代码块。

20)变量的 生命期由存储地位决定 。如果变量 未初始化 存储地位决定了变量的初始值 是多少:全局数据区的变量如果未初始,值为 0(.bss 段); 栈区的变量如果未初始化,值为随机值;寄存器里的值未初始化为随机值。

static auto(默认) register
局部变量 全局数据区 栈空间 寄存器(可能)
全局变量 全局数据区 —————- ——————

21)C 语言中,如果函数不写返回值类型,则默认返回类型是 int;对于一个有返回值的函数,如果不写返回值,会返回一个随机值。

22)当参数只是一个字符串,且没提供长度的时候。能够应用while 循环来遍历字符串,判断根据是字符串的最初一个字符是 0 元素 '\0'

23)在写递归函数的时候,首先要 先把函数的递归模型画进去 ,而后去编写递归函数。编写时候要留神:n-1边界 。在了解递归函数的时候, 不要想着去执行递归的细节 ,而是从递归模型来了解。
递归模型的个别表示法:

1、函数的概念

  • 函数是具备特定 性能 的程序组件(能够看做黑盒:不须要晓得外面怎么实现的,只晓得怎么用)
  • 函数有明确的应用形式(固定输出对应固定输入)
  • 函数在程序中能够重复使用(程序中的工具)

1.1 函数的类型

C 语言中的函数次要有 2 种类型:

  • Function:数据处理(数据 –> 数据),通过某种规定由输出的数据失去输入数据
  • Procedure:过程定义(数据 –> 性能),(依据数据)执行一系列动作,进而实现某种性能

1.2 函数的组成部分

  • 函数名:函数的惟一标识
  • 函数参数:数据输出(数据 –> 数据,数据 –> 动作)
  • 函数返回类型:

    • 数据输入(数据 –> 数据)
    • 无返回值(数据 –> 动作)

形如:

返回类型 函数名(参数 1,参数 2){
    程序语句 1;
    ...
    程序语句 1;
}

2、函数的调用

  • 通过 函数名 调用曾经定义好的函数
  • 函数调用时须要顺次指定函数参数的具体值
  • 函数调用的后果(返回值)可保留在同类型的变量中

    int r1 = func_name(5);
    int r2 = func_name(10);

2.1 深刻了解 main()

个别状况下,C 语言程序都是从 main()开始执行的,那么 main()是什么呢?

  • main()是应用程序与操作系统的一个“约定”,程序的 入口函数
  • 当操作系统运行应用程序时,首先调用的就是 main()函数
  • 应用程序必须运行于操作系统,承受操作系统的治理(如 windows 工作资源管理器,能够随便完结某个利用过程)

在 windows 上运行程序,都是双击 App 运行的,为什么说应用程序是被操作系统运行的呢?
应用程序执行的过程:(后续补上时序图)

  1. 用户双击.exe,或者在命令行中间接运行.exe
  2. OS 把应用程序加载到内存中:Load()
  3. OS 找到应用程序的 main()函数
  4. 执行 main()函数
  5. 敞开应用程序时,main()函数执行完结,返回一个值给操作系统 (在 windows 中,能够在命令行,应用echo %errorlevel% 命令查看刚刚命令执行的 exe 的返回值)

2.2 函数的调用过程

C 程序的实质是由一系列不同性能的函数形成;函数之间通过互相调用组合“小性能”形成“大性能”;整个 C 程序的性能由函数的组合调用实现。

函数的调用过程:

  1. 暂停主调函数
  2. 跳转到被调函数,执行被调“函数体”
  3. 被调函数返回,复原执行主调函数

之前的文章中始终在说 “工具包” 这个概念,实际上,工具包就是一个函数集,蕴含了一系列定义好的函数。#inlude 语句用于申明,要应用工具包中的函数

3、函数的定义

3.1 函数中的 void

函数定义与函数调用:

  • 函数在被调用前必须残缺定义(实现函数体)
  • 函数能够先被申明,而后再被定义

    • 申明时,必须给出 函数三要素(函数名,参数列表,返回类型)
    • 定义时,必须残缺给出函数体定义

在函数调用之前如果函数没有申明,那么会报 not delared 谬误;如果申明了,然而没定义,就会报 undefined reference 谬误;(申明 就是通知编译器,我这个符号是有的,只管用,去其余中央找定义就好了)

void 的深刻了解:

  • C 语言中存在 空类型(void),这种类型示意“空”
  • void 不能用于定义具体变量(没有数据属于空类型)
  • void 罕用于函数定义,示意 没有返回值或无参数

3.2 函数的返回值

  • return 语句完结以后函数执行,返回主调函数,后续代码不再执行
  • 对于 无返回值 函数(procedure

    • return 能够间接返回,无需跟上返回值;即 return;
    • 当函数体里没有 return 时,最初一条语句执行后主动返回
  • 对于 有返回值 的函数(function

    • return 必须跟上一个非法返回值,所有的分支都得显示返回值
    • return 语句必须呈现在函数体中,并且必须被执行

4、函数的参数

  • 函数参数在函数定义时并没有确定的值(形参
  • 函数参数的具体值再函数调用时指定(实参
  • 函数参数的 实质是变量

4.1 一般参数

函数调用是指定的实参用于对形参进行 初始化 ,初始化之后形参在函数外部等同于 一般变量

int add(int a, int b)
{return a+b;}

int main()
{int c = add(1, 2);
    printf("c = %d\n", c);
    return 0;
}

4.2 数组参数

  • 定义函数时能够应用 数组形参(如 int f(int a[5]);)
  • 数组形参须要应用 同类型数组 作为实参
  • C 语言中,数组作为函数参数传递时大小信息失落(数组参数进化为指针
  • 在数组外部批改数组形参,将影响实参

个别的,当应用数组作为参数时,函数的参数列表须要多一个参数来示意数组的大小。

4.3 数组排序

排序中的两个要害操作:

  • 比拟:任意两个数据元素通过比拟操作确定先后秩序
  • 替换:数据元素之间须要通过替换能力失去预期后果

解决方案:

  • 编写函数 int Min(int a[], int b, int e)抉择最小元素

    • 性能定义:在数组 a 的 [b,e] 范畴内寻找最小元素
    • 返回值:最小元素在数组中的下标
  • 循环遍历数组,将每次找到的最小元素 替换

    for(i=0; i<n; i++)
    {j = Min(a, i, n-1);
      if(i != j)
          Swap a[i] and a[j];
    }

5、变量的作用域和生命期

如果两个函数中有同同名变量,会产生命名抵触的问题么?

C 语言中变量的分类:

  • 局部变量:函数外部定义的变量(隶属于以后函数),只能在以后函数中拜访
  • 全局变量:不特定隶属于某个函数,在任意函数中都能够拜访

同名变量的问题:

  • 不同函数中的局部变量能够同名(不会发生冲突)
  • 全局变量不能同名(会产生 命名抵触
  • 当局部变量和全局变量同名时,优先应用局部变量

5.1 作用域

变量的作用域:

  • 变量的作用域指的是变量定义后的可拜访范畴
  • 不同变量的作用域能够有重叠

    • 不同变量在重叠作用域内可别离拜访
    • 在重叠作用域内,只可拜访最近定义的同名变量

局部变量的作用域:

  • 代码块:从 { 开始到 } 完结的一段代码
  • 经典 C 语言中,变量只能定义在代码块的开始处,即:{之后,执行语句之前
  • 变量的作用域从定义开始到以后代码块完结
  • 当变量的作用域完结后,变量不可用(无奈间接拜访)

全局变量的作用域:

  • 全局作用域:可在程序的各个角落拜访并应用
  • 文件作用域:只能在以后代码文件中拜访并应用
  • 全局变量的作用域可能被局部变量笼罩(同名局部变量)
  • 工程开发中,全局变量通常以 g_作为前缀名

5.2 生命期

问题:为什么来到作用域之后变量无奈应用?能够创立变量,那么是否也能够销毁变量?

不同变量的物理存储区域:

  • 在古代计算机系统中,物理内存被分为不同区域
  • 区域不同,用处不同,不同品种的变量位于不同区域

    • 全局数据区:寄存全局变量,动态变量
    • 栈空间:寄存函数参数,局部变量
    • 堆空间:用于动态创建变量

生命期 变量从创立到销毁的工夫 ,即 非法可用的工夫

  • 不同变量的生命期

    • 全局数据区中的变量:程序开始运行时创立,程序完结时销毁,整个程序运行期间非法可用
    • 栈空间中的变量:进入作用域时创立,来到作用域时销毁(主动销毁),局部变量在函数调用返回后销毁

5.3 作用域和生命期?

问题:感觉上,变量的作用域间接决定了生命期;那么作用域和生命期之间有关系么?

作用域和生命期无实质分割:

  • 作用域规定是 语法层面 对变量是否可拜访的规定(空间上
  • 生命期是 二进制层面 上变量存在于内存中的工夫(工夫上

    • 可能的状况

      • 作用域外无法访问的变量,可能在其生命期中(动态局部变量)
      • 作用域内可拜访的变量,可能曾经被销毁(堆变量)
      • 生命期中的变量,可能无法访问(文件作用域全局变量)

动态变量:

  • static 是 C 语言中的关键字
  • static 润饰的局部变量创立于 全局数据区(领有程序生命期)
  • static 润饰的全局变量只有 文件作用域(文件之外无法访问)
  • static 局部变量只会初始化一次,作用域与一般变量无异

变量的 生命期由变量存储地位决定

  • static 变量存储于全局数据区,默认初始化为0
  • auto 将变量存储于栈空间,默认初始化为 随机值
  • register 将变量存储于寄存器,默认初始化为 随机值

6、递归函数简介

问题:函数能不能自己调用本人?

函数 本人调用本人 ,就是递归。
递归是一种数学上 分而自治 的思维

  • 将原问题合成为规模较小的问题进行解决
  • 问题的合成是无限的(递归不能有限进行)
    例如:数列求和,
    令:Sn为 a 1 + a2 + … +an
    则:Sn = Sn-1 + an,且 S 1 = a1。将问题向下往 n-1 去合成,且有 边界,如 n = 1 时。

递归模型的个别表示法:

本文总结自“狄泰软件学院”唐佐林老师《C 语言入门课程》。
如有错漏之处,恳请斧正。

正文完
 0