一.函数的概念
用来封装功能
函数是 c 语言的功能单位,实现一个功能可以封装一个函数来实现。
定义函数的时候一切以功能为目的,根据功能去定函数的参数和返回值。
二.函数的分类/定义
1、从定义角度分类(即函数是谁实现的)
- 库函数 (c 库实现的)
- 自定义函数 (程序员自己实现的函数)
- 系统调用 (操作系统实现的函数)
2、从参数角度分类
- 1.有参函数 函数有形参,可以是一个,或者多个,参数的类型随便完全取决于函数的功能
- 2.无参函数 函数没有参数,在形参列表的位置写个 void 或什么都不写
3、从返回值角度分类
-
带返回值的函数
必须书写
return
关键字,返回结果在定义函数时,必须带着返回值的类型(假若没带着,默认返回整数)
正确书写格式:
int fun(int a,int b){ }
不建议书写格式:(默认返回整数类型)
fun(int a,int b){ }
-
不带返回值的函数
不必书写return,但可以将其作为函数停止的关键字。
在定义函数时,在返回值类型的位置书写
void
void fun(){ }
三.函数的声明
1.概念
在所使用函数所处位置编译器无法到达时,对已经定义的函数进行声明的操作。称为函数声明
2.声明场景
(1)前件
编译是自上而下的
C语言的编译器编译程序是自上而下编译的,此时如果要使用的函数定义在调用处的下面或其它位置,编译器就会认为该函数不存在进而报错
(2)需要声明的场景
-
被调用函数在下,调用函数在上时
int main(){ fun();//编译器到达这里时找不到尚未编译的fun函数,就会直接报错。 } void fun(){ printf("HelloWorld\n"); }
-
被调函数在同一程序(工程)的不同代码文件下时
3.声明方式
(1)直接声明
① 概述
直接在调用函数的前面书写函数的声明
**函数的声明:**就是被调函数的第一行,将花括号改为;
号即可
② 例子
void fun();
int main(){
fun();//编译器到达这里时找不到尚未编译的fun函数,就会直接报错。
}
void fun(){
printf("HelloWorld\n");
}
(2)间接声明(建议)
这种方法是相对建议的,这样适合模块化开发
① 概述
其作用和上面的直接声明其实是一样的,当编译器走到头文件引用处时,就会进入头文件,按头文件的内容对函数进行初始化,以便下面直接使用(这个声明方法也可以引入其它代码文件的函数)
将函数声明的内容书写到.h
头文件中,然后在代码的开头调用该头文件即可
② 示例
头文件 test.h
- 头文件后缀是
.h
-
extern
关键字是用来调用同程序(工程)不同代码文件内容时使用的
extern void fun();
调用程序:
在程序的开头就直接引入头文件test.h
#include "test.h"
int main(){
fun();//编译器到达这里时找不到尚未编译的fun函数,就会直接报错。
}
void fun(){
printf("HelloWorld\n");
}
四.函数的调用
1.带返回值
变量 = 函数名(实参列表);
2.不带返回值
函数名(实参列表);
变量的存储
一.内存
1.分类
物理内存:实实在在存在的存储设备 虚拟内存:操作系统虚拟出来的内存。
2.内存的映射
在程序中获取到的内存地址,其实就是虚拟内存的地址
C语言程序通常是在虚拟内存中运行的
例如:指针和数组实际上是虚拟地址的引用。当程序运行时,操作系统才会将这些虚拟地址映射到实际的物理内存地址(运行在虚拟,存储在物理)
3.内存的分区
在程序运行时,系统会把虚拟内容分区成下面个区块,对应存储不同的功能
(1)堆
在动态申请内存的时候,在堆里开辟内存。
(2)栈
主要存放局部变量
(3)静态全局区
① 未初始化的静态全局区
静态变量(定义变量的时候,前面加 static 修饰),或全局变量 ,没有初始化的,存在此区
② 初始化的静态全局区
全局变量、静态变量,赋过初值的,存放在此区
(4)代码区
存放代码的区域
(5)文字常量区
概述: 存放常量的区域,通常被存储在静态存储区 特点: 程序运行期间,这些数据只会被初始化一次,之后这些数据不会被改变
二.全局变量
1.普通全局变量
可以跨源文件调用
(1)概念
定义在函数外部的变量,默认初始化值是0.
(2)作用范围
相当于Java中用Public声明的变量,同一个软件包,哪都可以调
**作用范围:**整个程序(项目)
(3)调用
① 同一个代码文件(无需声明)
同一个代码文件,不需要对全局变量进行声明,直接使用即可
② 同程序不同文件(需要声明)
同一程序(项目)不同代码文件.c
,使用其它代码文件的全局变量,需要在使用前对这个变量进行声明
Ⅰ.声明
声明的时候不要赋值
使用前,用extern 数据类型 变量名
进行声明
2.静态全局变量
不能跨源文件调用
(1)概念
有static
修饰的全局变量,初始化值默认为0.
static int num = 100;//静态全局变量
int main(){
return 0;
}
(2)作用范围
只在其所在的.c
代码文件中有效,不能在其它.c
文件中调用
3.普通局部变量
(1)概念
在函数内部的定义的变量,或者复合语句中定义的变量,默认初始化值是随机数
int main(){
int num;//局部变量
{
int a;//局部变量
}
}
(2)作用范围
只在其所处复合语句内有效
(3)生命周期⭐
不用不占用空间
- 调用之前,局部变量不占用空间
- 调用之后,才为其开辟空间,用完立即释放
4.静态局部变量
(1)概念
用static
修饰的局部变量,默认初始化值是0.
(2)作用范围
只在定义它的函数或复合语句内有效(和普通局部变量一致)
(3)生命周期⭐
不释放,每次调用都是同一个
第一次调用时开辟空间并赋值,用完后不释放,后继再调用该函数对这个变量进行复用操作
三.补充
1.main函数传参
(1)概述
在C语言中,main
函数的参数,其实就是在用命令行运行参数时传入的参数
**示例:**下面这个指令运行的时Main_Function_parameters.c
编译后的代码,其后传入的值就是将来会进入main函数的参数了
D:\>Main_Function_parameters.exe test doraemon honest abc
(2)格式
在C语言中,main
函数的参数格式通常包括两个部分:
- 命令行参数的数量:
int argc
- 包含编译后的文件名,以及后面传进去的参数
- 命令行参数的值:
char* argv[]
- 这个集合里包含编译后的文件名,以及后面传进去的参数
(3)示例
步骤:
-
先对下面示例代码进行编译,得到
.exe
文件 -
在进入其目录通过命令好运行
D:\>Main_Function_parameters.exe test doraemon honest abc
-
然后就可以通过main函数内设置的打印语句看到传入main函数的值了
argc=5 argv[0]=Main_Function_parameters.exe argv[1]=test argv[2]=doraemon argv[3]=honest argv[4]=liu
示例代码:
#include
int main(int argc, char *argv[]) {
int i;
printf("argc=%d\n", argc);
for (i = 0; i < argc; i++) {
printf("argv[%d]=%s\n", i, argv[i]);
}
return 0;
}