C语言学习:函数

来源:互联网 发布:mac怎么下载r语言 编辑:程序博客网 时间:2024/06/06 04:01

前言

先定义,后使用。

定义函数

定义无参函数

类型名 函数名(){
函数体
}
或者
类型名 函数名(void){
函数体
}
(1)
类型名这里表示的是函数的返回值类型,也可以用void,表示不返回函数值
(2)
函数体包含声明部分和语句部分

定义有参函数

类型名 函数名(形式参数列表){
函数体
}
(1)
形式参数列表,比如:int x,int y

定义空函数

类型名 函数名(){}
比如:

void dummy(){
}

函数的调用

(1)

单独使用,方法名既可以:

max(x,y);
或者
preson();

(2)

函数表达式

c=max(x,y);
这是带有返回值的,一般来说,带有返回值的都这样用

(3)

函数参数
一个函数有返回值,可以直接当做另一个函数的参数使用

m= max(a,max(x,y));

函数调用的数据传递

(1)形式参数和实际参数

在调用有参函数时候,调用函数和被调用函数之间存在数据传递关系。
定义一个函数:

void put(int x){
//这个函数中参数x就是形式参数
}
在调用时候:
put(3);
这样的3就是实际参数,就是实参


(2)实参和形参间的数据传递

在调用函数过程中,系统会把实参的值传递给调用函数的形参。
实参:可以是常量、变量、表达式、但是要求必须有确定的值,在调用时候将值传给形参
实参和形参的类型相同或赋值兼容。

(3)函数调用过程

(1)
形参,在未出现函数调用时候,他们不占据内存中的存储单元。只有在发生函数调用时候,函数max的形参才会
被临时分配内存单元
(2)
如果带有返回值,那么通过return返回到主函数,如果是空的函数,则不需要return。
(3)
调用结束,形参单元被释放。但是,实参单元依旧保留并维持原值,没有改变。

声明

(1)

别调用的函数必须是已经定义的函数(是库函数或用户自定义的函数),如果使用的是库函数,那么在本文件开头
用#include指令调用才行。

(2)

一个用户自己定义的函数,而该函数的位置在调用它的函数(一般是主函数)的后面,在同一文件中时候,应该在主函数
中对于被调用的函数做声明。
声明的作用是将函数名、函数参数、参数类型等信息通知编译系统。

(3)

声明时候只需:
float add(float x, float y); 就可以对于add函数的声明了。
但也可以:
float add(float ,float);
因为C语言中,只关心和检查参数的个数和参数类型,不检查参数名。

(4)

数组元素可以当做函数的参数。
数组也可以用数组名当做函数参数。这种时候向形参传递的是数组首元素的地址

float add(float array[10]){}
定义上述的方法
在使用时如下:
float soore [10];
add(soore);
就可以了

局部变量和全局变量

局部变量

包含两种,一种是在函数内部定义的,这种变量旨在本函数范围内有效。还有一种是在复合语句内定义的,
这种变量只在符合语句中使用。

全局变量

在函数之外定义的变量就是外部变量,也就是全局变量。
全局变量可以被本文件中其他函数所共有,有效范围:定义变量位置到本源文件结束。

变量的存储方式和生存期

有的变量是在调用其所在函数时才临时分配存储单元,有些变量是在程序运行期间是都存在的。
可以分为:静态存储方式和动态存储方式。
静态存储方式是指程序运行期间由系统分配固定的存储空间方式
动态存储方式:在程序运行期间需要进行动态的分配存储空间的方式

存储空间的划分

可以分为程序区、静态存储区、动态存储区、
(1)
数据分别存放在静态存储区、动态存储区、
全局变量全部存放在静态存储区中,在程序开始时候就给全局变量分配存储区,程序执行完之后才释放。
动态存储区中:
函数形式参数(在调用函数时给形参分配存储空间)、
函数中定义的没有statis声明的变量、
函数调用时的现场保护和返回地址等
(2)
同一个函数,如果调用了两次,那么分配的在空间中的地址也是步相同的

数据的存储类别

每一个变量和函数 都有两个属性,数据类型和数据的存储类别。
C的存储类别包括:自动的(auto)、静态的(statis)、寄存器的(register)、外部的(extern)
根据变量的存储类别,可以知道变量的作用域和生存期。

(1)自动变量(auto 变量)

这种默认的是在调用函数时候,自动分配存储空间就是动态存储区。不写auto则隐含指定为“自动存储类别”

int b =4;
等价于
auto int b =4;

(2)静态的(statis变量)

statis 不仅仅可以定义在主函数外,还可以定义在函数内,但是,存在之后,在程序整个运行期间不会在释放。

int f(){
statis c =3 ;
并且在编译时赋值一次之后,后面都不会重新赋值。而是保留上一次调用结束的值

(3)寄存器的(register)

为了提高执行效率,允许将局部变量的值放在CPU的寄存器中,需要时直接从寄存器中取出来直接运算,不必再到内存
中去取。

(4)外部的(extern)

针对于变量:

全局变量是从定义处开始到程序的结束处,但是希望扩展外部变量的作用域。

(1)

在一个文件内扩展外部变量的作用域
可以用在引用之前用extern 对该变量作外部变量声明。

int A;
在使用的地方,在int A 定义的前面
extern int A;

(2)

将外部变量的作用域扩展到其他文件
两个文件都需要一个变量,这时候只需要在一个文件里面定义这个外部变量,在另一个中用extern Num就可以 了

文件1 : int A;
文件2 : extern A;
这样做就可以了,保证了是同一个变量

(3)

将外部变量的作用域限制在本文件中。
有些程序希望某些外部变量只限于被本文件引用。

static int S;
那么在别的文件中再用extern 就不管用了。
相当于将本文件的外部变量对外界屏蔽起来,从其他文件角度,这些静态外部变量是看不见的。

针对函数

(1)

内部函数
如果一个函数前面加上static ,那么这个函数只能在本文件中被调用。

(2)

外部函数
在定义函数的时候,在函数左端加关键字extern,变成了外部函数,可以被其他文件调用。
C语言中,如果在定义函数时忽略extern则默认是外部函数。

在文件1中:
void enter(int str[10]){}
在文件2 中
int main(){
extern void enter(int str[]);
}
写成这样,enter(int str[]) 表示为函数原型。
函数原型可以把函数的作用域扩展到定义该函数的文件之外。

原创粉丝点击