一.函数的概念

用来封装功能

函数是 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;
}
最后修改:2024 年 03 月 11 日
如果觉得我的文章对你有用,请随意赞赏