一、函数的概念
函数是 c 语言的功能单位,实现一个功能可以封装一个函数来实现。
定义函数的时候一切以功能为目的,根据功能去定函数的参数和返回值。
二、函数的分类
1、定义角度分类
1、库函数 2、自定义函数 3、系统调用
2、参数角度分类
1、有参函数
函数有形参,可以是一个,也可以是多个,类型随便
例如:
1 2 3 4 5 6
| int fun(int a.float b.double c){
} int max(int x,int y){
}
|
2、无参函数
函数没有参数,在形参列表的位置写 void 或者不写
1 2 3 4 5 6
| int fun(void){
} int fun(){
}
|
3、返回值角度分类
(1)带返回值的函数
在定义函数的时候,必须带有返回值类型,在函数题,必须有 return,没有返回值类型,默认返回值整形
例如:
1 2 3 4 5
| char fun() { char b = 'a'; return b; }
|
(2)没有返回值的函数
在定义函数的时候,函数名字前面加个 void
1 2 3 4 5 6
| void fun(形参表){ ; ; return ; ; }
|
在函数中不需要 return,如果想结束函数,返回到被调用的地方,return ;什么都不返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <stido.h> int main(int x,int y){ int z; if(x>y) z=x; else z=y; return z; } void help(void){ printf("*********************\n"); printf("********帮助信息*****\n"); printf("*********************\n"); } int main(){ int num; help(); num = max(10,10+5); printf("num=%d\n",num); return 0; }
|
三、函数的定义
1、定义方法
返回值类型 函数名字(形参列表){
//函数体,函数的功能写在函数体实现
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void myfun1(){ printf("hello world\n"); } return ;
void myfun2(){ int sum; sum = a + b; printf("%d + %d = %d\n", a , b , sum); }
int myfun3(int a,int b){ int sum; sum = a + b; return sum; }
|
四、函数的声明
1、概念
对已经定义的函数,进行声明,可以多次
2、为什么声明
编译器在编译 c 时,上到下编译
3、声明方法
(1)主调函数和被调函数在同一个.c 中
1 2 3 4 5 6 7
| void fun(void){ printf("hello world\n"); } int main(){ fun(); }
|
(2)被调函数在下,主函数在上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| int main(){ fun(); }
void fun(void){ printf("hello world\n"); }
#include <stdio.h> void myfun1(); void myfun2(int a,int b); int myfun3(int a,int b); int main(){ myfun1(); return 0; } void myfun1(){ printf("hello world\n"); return ; } void myfun2(int a,int b){ int sum; sum = a + b; printf("%d + %d = %d\n",a,b,sum); } int myfun3(int a,int b){ int sum; sum = a + b; return sum; }
#include "a.h" int main(){ fun(); } void fun(void){ printf("hellow world"); }
extern void fun(void);
|
(2)主调函数和被调函数不在同一个.c 文件
1.直接声明 2.间接声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include "myfun.h"
void myfun1(){ printf("hellow world\n"); return; }
#ifndef MYFUN_H #define MYFUN_H
void myfun1();
#endif
#include <stdio.h> #include "myfun.h"
int main(){ muyfun1(); return 0; }
|
五、函数调用
变量 = 函数名(实参列表);带返回值
函数名(实参列表);不带返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include <stdio.h>
void myfun1(); void myfun2(int a,int b); int myfun(int a,int b);
int main(){ myfun1(); printf("*******************\n");
myfun2(100,90); int x = 10, y=10;
myfun2(x,y); printf("*******************\n");
int n; n = myfun3(100,90);
printf("n = %d\n",n); printf("sum=&d\n",myfun3(90,66)); return 0; }
void myfun1(){ printf("hello world\n"); return ; }
void myfun2(int a,int b){ int sum; sum = a + b;
printf("%d + %d = %d\n",a,b,sum); } int myfun3(int a,int b){ int sum; sum = a + b; return sum; }
|
六、变量的存储类别
1、内存的分区
物理内存:存储在存储设备
虚拟内存:操作系统虚拟出来的内存
操作系统会在物理内存和虚拟内存之间叫映射
2、运行程序的时候,操作系统会将虚拟内存进行分区
(1)堆
在动态申请内存的时候,在堆里开辟内存
(2)栈
存放局部变量
(3)静态全局区
1:未初始化的静态全局区
静态变量(就是在前面添加 statiic),或者全局变量,没有初始化,存储在这里
2:初始化的静态全局区
全局变量,静态变量,赋值初始值的,存储在这里
4、代码区
存储在程序代码
5、文字常量区
存放常量的
3、普通全局变量
在函数外部定义的变量
1 2 3 4 5
| int num =100; int main(){ return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <stdio.h>
int num;
void myfun(){ num= 888; } int main() { printf("num=%d\n",num);
myfun();
printf("num=%d\n",num); return 0; }
|
4、静态全局变量
定义全局变量的时候,用 static
作用范围:限定了静态全局变量的作业范围
生命周期:在程序整个运行中,都一直存在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <stdio.h>
static int num;
void myfun() { num++; }
int main(int argc, char *argv[]) { printf("num = %d\n", num);
myfun();
printf("num = %d\n", num);
return 0; }
|
5、局部变量
在函数内部定义,或者复合语句定义的变量
1 2 3 4 5 6
| int main(){ int num; { int a; } }
|
作用范围:
在函数中定义的变量,在函数中有效
在复合语句中定义的,在复合语句中有效。
生命周期:
在函数调用之前,局部变量不占用空间,调用函数的时候,
才为局部变量开辟空间,函数结束了,局部变量就释放了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <stdio.h>
void myfun() { int num = 100; num++;
printf("num = %d\n", num);
return ; }
int main(int argc, char *argv[]) { 放
myfun(); myfun(); myfun();
return 0; }
|
6、静态的局部变量
定义局部变量的时候,前面加 static 修饰
作用范围:
在它定义的函数或复合语句中有效。
生命周期:
第一次调用函数的时候,开辟空间赋值,函数结束后,不释放, 以后再调用函数的时候,就不再为其开辟空间,也不赋初值, 用的是以前的那个变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include <stdio.h>
void myfun() {
int a; static int num;
printf("a = %d\n", a); printf("num = %d\n", num); }
void myfun1() { static int num1 = 100; num1++;
printf("num1 = %d\n", num1); }
int main(int argc, char *argv[]) { myfun();
myfun1(); myfun1(); myfun1();
return 0; }
|
1:定义普通局部变量,如果不赋初值,它的值是随机的。
定义静态局部变量,如果不赋初值,它的值是 0
2:普通全局变量,和静态全局变量如果不赋初值,它的值为 0
7、外部函数
咱们定义的普通函数,都是外部函数。 即函数可以在程序的任何一个文件中调用。
在分文件编程中,只需要将函数的实现过程写在指定的.c 文件中,然后将其声明写在指定
的.h 文件中,其他文件只要包含了头文件,就可以使用外部函数
8、内部函数
内部函数也称之为静态函数,就是用 static 修饰的函数
在定义函数的时候,返回值类型前面加 static 修饰。这样的函数被称为内部函数。
static 限定了函数的作用范围,在定义的.c 中有效。
外部函数,在所有地方都可以调用,
内部函数,只能在所定义的.c 中的函数调用
扩展:
在同一作用范围内,不允许变量重名。
作用范围不同的可以重名。
局部范围内,重名的全局变量不起作用。(就近原则)
1 2 3 4 5 6 7 8
| int num = 100; int main() { int num = 999;
return 0; }
|