Summary
1)C 语言中的函数次要有 2 种类型:
Function
:数据处理(数据 –> 数据),通过某种规定由输出的数据失去输入数据Procedure
:过程定义(数据 –> 性能),(依据数据)执行一系列动作,进而实现某种性能
2)应用程序必须依附操作系统能力运行,应用程序承受操作系统的治理。当 操作系统运行程序时,首先调用的就是 main()函数
。)(main() 函数个别是第一个被调用的函数,也有其余办法能够让其余函数先于 main 执行)
3)应用程序执行的过程:(后续补上时序图)
- 用户双击.exe,或者在命令行中间接运行.exe
- OS 把应用程序加载到内存中:Load()
- OS 找到应用程序的 main()函数
- 执行 main()函数
- 敞开应用程序时,
main()函数执行完结
,返回一个值给操作系统
(在 windows 中,能够在命令行,应用echo %errorlevel%
命令查看刚刚命令执行的 exe 的返回值)
4)函数的调用过程:
- 暂停主调函数
- 跳转到被调函数,执行被调“函数体”
- 被调函数返回,复原执行主调函数
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 运行的,为什么说应用程序是被操作系统运行的呢?
应用程序执行的过程:(后续补上时序图)
- 用户双击.exe,或者在命令行中间接运行.exe
- OS 把应用程序加载到内存中:Load()
- OS 找到应用程序的 main()函数
- 执行 main()函数
- 敞开应用程序时,main()函数执行完结,
返回一个值给操作系统
(在 windows 中,能够在命令行,应用echo %errorlevel%
命令查看刚刚命令执行的 exe 的返回值)
2.2 函数的调用过程
C 程序的实质是由一系列不同性能的函数形成;函数之间通过互相调用组合“小性能”形成“大性能”;整个 C 程序的性能由函数的组合调用实现。
函数的调用过程:
- 暂停主调函数
- 跳转到被调函数,执行被调“函数体”
- 被调函数返回,复原执行主调函数
之前的文章中始终在说 “工具包”
这个概念,实际上,工具包就是一个函数集
,蕴含了一系列定义好的函数。#inlude 语句用于申明,要应用工具包中的函数
。
3、函数的定义
3.1 函数中的 void
函数定义与函数调用:
- 函数在被调用前必须残缺定义(实现函数体)
-
函数能够先被申明,而后再被定义
- 申明时,必须给出
函数三要素
(函数名,参数列表,返回类型) - 定义时,必须残缺给出函数体定义
- 申明时,必须给出
在函数调用之前如果函数没有申明,那么会报 not delared 谬误;如果申明了,然而没定义,就会报 undefined reference 谬误;(申明
就是通知编译器,我这个符号是有的,只管用,去其余中央找定义就好了)
void 的深刻了解:
- C 语言中存在
空类型(void)
,这种类型示意“空” - void 不能用于定义具体变量(没有数据属于空类型)
- void 罕用于函数定义,示意
没有返回值或无参数
3.2 函数的返回值
- return 语句完结以后函数执行,返回主调函数,后续代码不再执行
-
对于
无返回值
函数(procedure
)- return 能够间接返回,无需跟上返回值;即
return;
- 当函数体里没有 return 时,最初一条语句执行后主动返回
- return 能够间接返回,无需跟上返回值;即
-
对于
有返回值
的函数(function
)- return 必须跟上一个非法返回值,
所有的分支都得显示返回值
- 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,且 S1
= a1
。将问题向下往n-1
去合成,且有边界
,如 n = 1 时。
递归模型的个别表示法:
本文总结自“狄泰软件学院”唐佐林老师《C 语言入门课程》。
如有错漏之处,恳请斧正。