函数
(一)概述
1.为什么需要函数?
我们为什么需要函数?在main函数中写代码不是挺好的吗?
①如果程序功能比较多,代码规模比较大,那么main函数就会变得很庞杂,使用和维护起来都比较困难。
②程序中可能涉及到需要多次实现某一功能,就需要重复实现该功能代码,使得程序显得特别冗余。简言之就是在进行一些相同的操作,我们可以将其写成一个函数,减少代码冗余。
2.函数的功能是什么?
函数实质上就是实现一定的功能, 函数名就是给该功能起一个名字。在开发一个较大程序时,往往需要进行任务分解,即将程序分成不同的模块,每个模块的功能通过函数实现。
一个C语言程序可以由一个main函数和多个其他函数组成,由main函数调用其他函数或者其他函数相互之间调用。同一个函数可以被调用一次或者多次。
3.函数的分类
从函数定义的角度看,函数可以分为两种:
①系统函数:这是由编译系统提供的,用户不必自已定义这些函数,可以直接使用它们,如我们常用的打印函数printf()。
②用户自定义函数:用来专门解决用户的需要。
函数使用的C语言示例一
#include<stdio.h>
int max(int a,int b){
if(a>b){
return a;
}
else
return b;
}
int main(){
/*
函数使用的示例一:降低代码的重复性
*/
int a1=10,b1=20,c1=0;
c1 = max(a1,b1); //调用max()
int a2=30,b2=40,c2=0;
c2 = max(a2,b2); //调用max()
return 0;
}
函数使用的C语言示例二
这些函数在使用的时候要先定义。
#include<stdio.h>
int main(){
/*
函数使用的示例二:使程序更加模块化,有利于阅读
*/
run();
skill1();
jump();
skill2();
return 0;
}
(二)函数的定义和调用
1.函数的定义格式
函数定义的一般形式为
返回类型 函数名(形式参数列表)
{
数据定义部分;
执行语句部分;
}
示例:
int max(int a.int b)
{
if(a>b]{max = a;}
else{max = b;}
return max;
}
2.函数定义的注意事项
-
函数定义就是将之前写在main函数的代码换个地方组装起来。
-
函数定义好了以后,需要该函数被调用,才会起作用。
-
main函数是由系统自动调用的,无须我们人为调用。
3.函数调用的格式
函数调用的一般格式是:
函数名(实参列表)
注意:如果是调用无参函数,则实参列表可以省略,如果有多个实参,需要用逗号隔开。
4.无参无返回值函数的定义及调用
#include<stdio.h>
/*
无参无返回值函数的使用。
1.没有返回值,所以返回类型用void修饰。
2.没有参数,所以直接缺省,即空表示。
3.同一个程序中不能出现同名函数。
*/
void show() {
printf("无参无返回值函数的调用...\n") ;
}
int main() {
show() ;
return 0;
}
5.有参无返回值函数的定义及调用
#include<stdio.h>
/*
有参无返回值函数的使用。
1.定义函数的参数叫形参,形参的格式是类型变量名,不可以赋值。
2.函数没有被调用,则形参不会分配内存空间,而且函数执行完毕,
形参变量自动释放。
3.函数调用时的参数叫实参,只能将实参的值传递给形参。
4.实参可以是常量,变量,表达式。
5.如果参数有多个,则使用,分隔。
*/
void show2(int a){
printf("%d\n",a);
}
int main() {
//int i = 11;
//show2(i);
show2 (3>4);
show2(10);
return 0;
}
6.无参有返回值函数的定义及调用
#include<stdio.h>
/*
无参有返回值函数的使用。
1. 第一个int指的是返回值类型,通过return获取到。
2. return的作用是终止当前的函数。。
3.返回值可以是常量,变量以及表达式。
4.函数的返回值只能是1个。
5. return类型和函数值返回类型不一致,以函数返回类型为准。
*/
int show(){
return 1;
}
int main(){
//1.如果有返回值,可以用,也可以不用
//2.如果要使用,尽量使用匹配的数据类型
int a = show();
show();
printf("%d\n",a);
return 0;
}
7.return和exit的区别
在main函数中调用exit和return结果是一样的, 但在子函数中调用returm只是代表子函数终止了,在子函数中调用exit,那么程序终止。
8.函教的定义与声明
如果使用用户自己定义的函数,而该函数与调用它的函数(即主调函数)不在同一文件中,或者函数定义的位置在主调函数之后,则必须在调用此函数之前对被调用的函数作声明。
所谓函数声明,就是在函数尚在未定义的情况下,事先将该函数的有关信息通知编译系统,相当于告诉编译器,函数在后面定义。以便使编译能正常进行。
注意:一个函数只能被定义一次,但可以声明多次。
9.函数的定义与声明的区别
定义是指对函数功能的确立,包括指定函数名、函数类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。
声明的作用则是把函数的名字、函数类型以及形参的个数、类型和顺序(注意,不包括函数体)通知编译系统,以便在对包含函数调用的语句进行编译时,据此对其进行对照检查(例如函数名是否正确,实参与形参的类型和个数是否一致)
(三)作用域
1. 变量的作用域
问题引入
在一个函数中定义的变量,在其他函数中是否可以使用?在不同位置定义的变量,在
什么范围内有效?
C语言中的作用域可以分为以下三种:
①代码作用域(即{}里面的)
②函数作用域
③文件作用域
2. 局部变量
-
局部变量也叫auto自动变量(auto可写可不写),一般情况下代码块{}内部定义的变量都是自动变量。
-
局部变量有以下特点:
①在一个函数内定义,只在函数范围内有效。
②在复合语句中定义,只在复合语句中有效。
③随着函数调用的结束或复合语句的结東局部变量的声明声明周期也结束。
④如果没有赋初值,值为随机值。
C语言程序示例
#include<stdio.h>
void test(){
//auto写不写是一样的
//auto只能出现在{}内部
auto int b = 10;
}
int main(){
/*
1.在{}定义的就是局部变量
2.只有在执行到变量定义的语句,才会进行初始化
3.离开{}时,这个非static局部变量自动释放
4.加不加auto都一样
5.就近原则
*/
//b = 100; //err, 在main作用域中没有b
if (1)
{
//在复合语句中定义, 只在复合语句中有效
int a = 10;
printf("a = %d\n",a);
}
//a = 10; //err离开if()的复合语句,a已经不存在
return 0;
}
3. 静态局部变量
static局部变量的作用域也是在定义的函数内有效
static局部变量的生命周期和程序运行周期一样,同时staitc局部变量的值只初始化一
次,但可以赋值多次
static局部变量若未赋以初值,则由系统自动赋值:数值型变量自动赋初值0,字符型
变量赋空字符
4. 全局变量
在函数外定义,可被本文件及其它文件中的函数所共用,若其它文件中的函数调用此变量,须用extern 声明全局变量的生命周期和程序运行周期一样不同文件的全局变量不可重名。
5. 静态全局变量
在函数外定义,作用范围被限制在所定义的文件中
不同文件静态全局变量可以重名,但作用域不冲突
static全局变量的生命周期和程序运行周期一样,同时staitc全局变量的值只初始化一
次
6. extern全局变声明
extern int a;声明一个变量,这个变量在别的文件中已经定义了,这里只是声明,而不
是定义。
7.内部函数和外部函数
在C语言中函数默认都是全局的,使用关键字static可以将函数声明为静态,函数定义为static就意味着这个函数只能在定义这个函数的文件中使用,在其他文件中不能调用,即使在其他文件中声明这个函数都没用。
对于不同文件中的staitc函数名字可以相同。
总结
类型 | 怍用城 | 生命周期. |
---|---|---|
auto变量 | 一对{}内 | 当前函数 |
static局部变量 | 一对{}内 | 整个程序运行期 |
extern变量 | 整个程序 | 整个程序运行期 |
static全局变量 | 当前文件 | 整个程序运行期 |
extern函数 | 整个程序 | 整个程序运行期 |
static函数 | 当前文件 | 整个程序运行期 |
register变量 | 一对{}内 | 当前函数 |
自学自用,难免存在错误,如有错误,请给予指正。在这里将自己的心得和学习过程分享给大家,为大家提供一些思路,希望大家在学习的道路上少走一些弯路。
部分资源来源于网络,如有侵权,请联系本人予以删除!