函数及其作用域——(C语言笔记)

函数

一、函数的定义

一个函数由函数头函数体组成:

1. 函数头:

[<数据类型>]  <函数名>  ([形式参数列表])

[<数据类型>]规定函数返回值的类型。如int min(int x, int y),表示函数min将返回一个int类型的值;无返回值的类型是void类型。

<函数名>:

(1)不允许一个程序中出现同名的自定义函数名,不允许自定义函数名与同一程序中的全局变量名相同;
(2)允许自定义函数名与系统库函数名相同、与局部变量名、与函数的形式参数名相同。

([形式参数列表]):
形式参数即形参,之所以成为形参,是因为在定义函数时系统并不为这些参数分配存储空间,只有被调用,向它传递了实际参数时才为形参分配存储空间。

2. 函数体

如果表达式的类型与函数的返回值类型不相同,则将表达式的类型自动转换为函数的类型,这种转换是强制性的
C语言规定在一个函数定义内不允许出现另一个函数定义,即不允许做嵌套定义。

[return]:
(1)有返回值的return语句,可以用于返回一个表达式的值,实现函数之间的信息传递;
(2)无返回值的函数返回值类型部分需要使用关键字viod,该函数中可以有return语句,也可以无return语句;
(3)一个函数体中可以有多个return语句,但每次只能有一个return语句执行返回操作。

二、函数的调用

1. 函数调用的条件:

  1. 被调函数必须已定义且允许调用;
  2. 给出函数运行时要求的参数;
  3. 如果调用函数在定义函数之前,必须对被调函数进行原型声明;

2. 函数的调用形式:

<函数名>(实参列表)
【实参列表】

  1. 是由0、1或多个实参构成,参数之间用逗号分隔;
  2. 实参是用来在调用函数时给函数形参初始化的,一般要求,在函数调用时,实参与形参的个数相等,类型相同,第一个实参的值赋给第一个形参,第二个实参的值赋给第二个形参;
  3. C语言中的函数调用是传值调用,故实参可以是常量,变量,表达式,传值调用中,形参与实参分别占用不同的储存单元,形参改变不影响实参,即单项值传递

三、 函数的参数

有时编译器对实参的求值顺序会造成二义性,如 z=fun(–x,x+y);

如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。
形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

四、 函数原型声明

如果一个函数的定义在后,调用在前,此时在调用前,必须声明函数类型;
直接复制函数头加个;就行

五、 函数的嵌套调用

函数在C语言中,各个函数的定义都是相对独立的存在,在函数的内部可以调用其他的函数(这里面不包括main()函数)。这种调用过程叫做函数的嵌套(函数的定义部分不能嵌套)。

六、 函数的递归调用

在调用一个函数的过程中直接或者间接的调用函数的本身的过程,称为函数的递归调用。
1.调用自己本身(main函数除外)
2.有一个趋近于终止的条件。

作用域和存储类别

一、作用域

1) 块作用域:

C语言中把用花括号括起来的一部分程序称为块

局部变量:
在一个函数内部定义的变量或在一个块中定义的变量称为局部变量;
形参是局部变量;
主函数main()中定义的局部变量a,b只在主函数中有效,其余函数中定义的a,b只能在swap()函数中有效,尽管其名字相同但代表不同的对象,在内存中占据不同的存储单元,互不干扰。

局部定义优先:
具有块作用域的标识符在其作用域内,将屏蔽在本块内有效的同名标识符。

2) 文件作用域

文件是C语言的编译单位。
文件作用域是在所有函数外声明的,其作用域从声明点开始,一直延伸到本文件结束。

3) 函数原型作用域

在函数原型的参数列表中声明的参数名,其作用域只在该函数原型内,称为函数原型作用域;
函数原型声明中的标识符可以与函数定义声明中的标识符不同;
可以在函数原型声明中只做参数的类型的声明,而省略参数名;

4) 函数作用域

作为goto语句转移目标的标志,标号具有函数作用域,但不能用goto语句把流程转到其他函数体内;
语句标号是唯一具有函数作用域的标识符;

二、存储类别

·变量作用域角度:全局变量、局部变量
·变量存在时间角度:静态存储变量、动态存储变量
·一个程序在内存中占用的存储空间可以分为三个部分:程序区、静态存储区、动态存储区,程序区用来存放可执行程序的代码,变量一般存储在静态存储区和动态存储区中。

1. 局部变量的存储类别

·自动变量:
在执行程序时,当执行到变量作用域开始处时,系统动态地为变量分配空间,
而当执行到作用域结束处,系统收回这种变量所占用的存储空间;无存储类别声明的,默认为自动变量;对于自动变量,未赋初值时,初值不确定。

·静态变量:

static int a=3

局部静态变量的值在函数调用结束后,系统并不释放变量的空间,任为上次调用结束时的值;
几点说明如下:
i. 局部静态变量属于静态存储类别,在静态存储区内分配存储单元
ii. 局部静态变量的初始化仅在程序开始执行时处理一次,在程序运行时它的值始终存在;
而自动变量赋初值是在函数调用时进行的,每调用一次函数会重新分配空间并赋一次初值;
iii. 局部静态变量默认初值为0(对数值型变量)或空字符‘\0’(对字符变量);
iv. 虽然局部静态变量在函数调用结束后任然存在,但其他函数不能引用它

·寄存器变量:
用关键字register申明;将变量存储在CPU的寄存器里,提高效率;
auto声明的变量仅存储位置不同。

2. 全局变量的存储类别

全局变量(外部变量)是在函数外部定义的;
全局变量均为静态存储;
定义全局变量时没有赋初值,那么系统在给它分配空间时,将它初始化为0;

三、全局变量的作用域的拓展和限制

·extern用于拓展全局变量的作用域,static用于限制全局变量的作用域

1、 全局变量作用域的拓展

extern有以下两种使用方式:
(一) 将全局变量的作用域拓展到其定义之前
如果全局变量不在文件的开头定义,其作用范围只限于从定义处到文件末尾;

(二) 将源文件中全局变量的作用域拓展到其他源文件中
Eg:在一个文件中定义变量num,而在另一个文件中用extern对num进行全局变量声明,即
extern int num
·假如程序有四个源程序文件,在一个文件中定义外部整型变量x,其他桑文件都可以引用x,但必须在其他三个文件中都加上一个”extern int x;“声明。

2、 全局变量作用域的限制

在程序设计中希望某些全局变量只限于被本文本引用,而不能被其他文本引用时,可以在定义全局变量时加一个static声明;
不论是否加static声明,全局变量都是静态存储方式,只是作用范围不同,都是在编译时分配存储空间的;

程序的多文件组织

一、 内部函数与外部函数

1、 内部函数

如果一个函数只能被本文件中的其他函数调用,称它为内部函数,在定义时,在函数类型前加static;

2、 外部函数

C语言中,默认所有函数都是外部函数,为强调调用的是其他源文件中定义的,可以在其前加extern修饰;

二、 多文件组织的编译和连接

  1. 用包含文件的方式
  2. 使用工程文件的方式:
    用“生成解决方案”命令对程序进行编译;
  • 28
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值