C语言探索之旅 | 第二部分第一课:模块化编程

做者 谢恩铭,公众号「程序员联盟」(微信号:coderhub)。
转载请注明出处。
原文: https://www.jianshu.com/p/207...

《C语言探索之旅》全系列程序员

内容简介


  1. 前言
  2. 函数原型
  3. 头文件
  4. 分开编译
  5. 变量和函数的做用范围
  6. 总结
  7. 第二部分第二课预告

1. 前言


上一课是 C语言探索之旅 | 第一部分练习题编程

话说上一课是第一部分最后一课,如今开始第二部分的探索之旅!小程序

在这一部分中,咱们会学习 C语言的高级技术。这一部份内容将是一座高峰,会挺难的,可是咱们一块儿翻越。安全

俗语说得好:“一口是吃不成一个胖子的。”微信

可是一小口一小口,慢慢吃,仍是能吃成胖子的嘛。因此要细水长流,肥油慢积,一路上有你(“油腻”)~编辑器

一旦你跟着咱们的课程一直学到这一部分的结束,你将会掌握 C语言的核心技术,也能够理解大部分 C语言写的程序了。模块化

到目前为止咱们的程序都只是在一个 main.c 文件里捣腾,由于咱们的程序还很短小,这也足够了。函数

但若是以后你的程序有了十多个函数,甚至上百个函数,那么你就会感到所有放在一个 main.c 文件里是多么拥挤和混乱。学习

正由于如此,计算机科学家才想出了模块化编程。原则很简单:与其把全部源代码都放在一个 main.c 当中,咱们将把它们合理地分割,放到不一样的文件里面。测试

2. 函数原型


到目前为止,写自定义函数的时候,咱们都要求你们暂时把函数写在 main 函数的前面。

这是为何呢?

由于这里的顺序是一个重要的问题。若是你将本身定义的函数放置在 main 函数以前,电脑会读到它,就会“知道”这个函数。当你在 main 函数中调用这个函数时,电脑已经知道这个函数,也知道到哪里去执行它。

可是假如你把这个函数写在 main 函数后面,那你在 main 函数里调用这个函数的时候,电脑还不“认识”它呢。你能够本身写个程序测试一下。是的,很奇怪对吧?这绝对有点任性的。

那你会说:“C语言岂不是设计得很差么?”

我“彻底”赞成(可别让 C语言之父 Dennis Ritchie 听到了...)。可是请相信,这样设计应该也是有理由的。计算机先驱们早就想到了,也提出了解决之道。

下面咱们就来学一个新的知识点,借着这个技术,你能够把你的自定义函数放在程序的任意位置。

用来声明一个函数的“函数原型”


咱们会声明咱们的函数,须要用到一个专门的技术:函数原型,英语是 function prototype。function 表示“函数”,prototype 表示“原型,样本,模范”。

就比如你对电脑发出一个通知:“看,个人函数的原型在这里,你给我记住啦!”

咱们来看一下上一课举的一个函数的例子(计算矩形面积):

double rectangleArea(double length, double width)
{
    return length * width;
}

怎么来声明咱们上面这个函数的原型呢?

  1. 复制,粘贴第一行。
  2. 在最后放上一个分号(;)。
  3. 把这一整行放置在 main 函数前面。

很简单吧?如今你就能够把你的函数的定义放在 main 函数后面啦,电脑也会认识它,由于你在 main 函数前面已经声明过这个函数了。

你的程序会变成这样:

#include <stdio.h>
#include <stdlib.h>

// 下面这一行是 rectangleArea 函数的函数原型
double rectangleArea(double length, double width);

int main(int argc, char *argv[])
{
    printf("长为 10,宽为 5 的矩形面积 = %f\n", rectangleArea(10, 5));
    printf("长为 3.5,宽为 2.5 的矩形面积 = %f\n", rectangleArea(3.5, 2.5));
    printf("长为 9.7,宽为 4.2 的矩形面积 = %f\n", rectangleArea(9.7, 4.2));

    return 0;
}

// 如今咱们的 rectangleArea 函数就能够放置在程序的任意位置了
double rectangleArea(double length, double width)
{
    return length * width;
}

与原先的程序相比有什么改变呢?

其实就是在程序的开头加了函数的原型而已(记得不要忘了那个分号)。

函数的原型,实际上是给电脑的一个提示或指示。好比上面的程序中,函数原型

double rectangleArea(double length, double width);

就是对电脑说:“老兄,存在一个函数,它的输入是哪几个参数,输出是什么类型”,这样就能让电脑更好地管理。

多亏了这一行代码,如今你的 rectangleArea 函数能够置于程序的任何位置了。

记得:最好养成习惯,对于 C语言程序,老是定义了函数,再写一下函数的原型。

那么不写函数原型行不行呢?

也行。只要你把每一个函数的定义都放在 main 函数以前。可是你的程序慢慢会愈来愈大,等你有几十或者几百个函数的时候,你还顾得过来么?

因此养成好习惯,不吃亏的。

你也许注意到了,main 函数没有函数原型。由于不须要,main 函数是每一个 C程序必须的入口函数。人家 main 函数“有权任性”,跟编译器关系好,编译器对 main 函数很熟悉,是常常打交道的“哥们”,因此不须要函数原型来“介绍” main 函数。

还有一点,在写函数原型的时候,对于圆括号里的函数参数,名字是不必定要写的,能够只写类型。

由于函数原型只是给电脑作个介绍,因此电脑只须要知道输入的参数是什么类型就够了,不须要知道名字。因此咱们以上的函数原型也能够简写以下:

double rectangleArea(double, double);

看到了吗,咱们能够省略 length 和 width 这两个变量名,只保留 double(双精度浮点型)这个类型名字。

千万不要忘了函数原型末尾的分号,由于这是编译器区分函数原型和函数定义开头的重要指标。若是没有分号,编译时会出现比较难理解的错误提示。

3. 头文件


头文件在英语中是 header file。header 表示“数据头,页眉”,file 表示“文件”。

每次看到这个术语,我都想到已经结婚的“咱们的青春”:周杰伦 的《头文字D》。

到目前为止,咱们的程序只有一个 .c 文件(被称为“源文件”,在英语中是 source file。source 表示“源,源头,水源”),好比咱们以前把这个 .c 文件命名为 main.c。固然名字是无所谓的,起名为hello.c,haha.c 都行。

一个项目多个文件


在实际编写程序的时候,你的项目通常确定不会把代码都写在一个 main.c 文件中。固然,也不是不能够。

可是,试想一下,若是你把全部代码都塞到这一个 main.c 文件中,那若是代码量达到 10000 行甚至更多,你要在里面找一个东西就太难了。也正是由于这样,一般咱们每个项目都会建立多个文件。

那以上说到的项目是指什么呢?

以前咱们用 CodeBlocks 这个 IDE 建立第一个 C语言项目的时候,其实已经接触过了。

一个项目(英语是 project),简单来讲是指你的程序的全部源代码(还有一些其余的文件),项目里面的文件有多种类型。

目前咱们的项目还只有一个源文件:main.c 。

看一下你的 IDE,通常来讲项目是列在左边。

如上图,你能够看到,这个项目(在 Projects 一栏里)只有一个文件:main.c 。

如今咱们再来展现一个包含好多个文件的项目:

上图中,咱们能够看到在这个项目里有好几个文件。实际中的项目大可能是这样的。你看到那个 main.c 文件了吗?一般来讲在咱们的程序中,会把 main 函数只定义在 main.c 当中。

固然也不是非要这样,每一个人都有本身的编程风格。不过但愿跟着这个课程学习的读者,能够和咱们保持一致的风格,方便理解。

那你又要问了:“为何建立多个文件呢?我怎么知道为项目建立几个文件合适呢?”

答案是:这是你的选择。一般来讲,咱们把同一主题的函数放在一个文件里。

.h 文件和 .c 文件


在上图中,咱们能够看到有两种类型的文件:一种是以 .h 结尾的,一种是以 .c 结尾的。

  • .h 文件:header file,表示“头文件”,这些文件包含了函数的原型。
  • .c 文件:source file,表示“源文件”,包含了函数自己(定义)。

因此,一般来讲咱们不常把函数原型放在 .c 文件中,而是放在 .h 文件中,除非你的程序很小。

对每一个 .c 文件,都有同名的 .h 文件。上面的项目那个图中,你能够看到 .h 和 .c 文件一一对应。

  • files.h 和 files.c
  • editor.h 和 editor.c
  • game.h 和 game.c

但咱们的电脑怎么知道函数原型是在 .c 文件以外的另外一种文件里呢?

须要用到咱们以前介绍过的预处理指令 #include 来将其引入到 .c 文件中。

请作好准备,下面将有一波密集的知识点“来袭”。

怎么引入一个头文件呢?其实你已经知道怎么作了,以前的课程咱们已经写过了。

好比咱们来看咱们上面的 game.c 文件的开头

#include <stdlib.h>
#include <stdio.h>
#include "game.h"

void player(SDL_Surface* screen)
{
    // ...
}

看到了吗,其实你早就熟悉了,要引入头文件,只须要用 #include 这个预处理指令。

所以咱们在 game.c 源文件中一共引入了三个头文件:stdlib.h, stdio.h,game.h。

注意到一个不一样点了吗?

在标准库的头文件(stdlib.h,stdio.h)和你本身定义的头文件(game.h)的引入方式是有点区别的:

  • <> 用于引入标准库的头文件。对于 IDE,这些头文件通常位于 IDE 安装目录的 include 文件夹中;在 Linux 操做系统下,则通常位于系统的 include 文件夹里。
  • "" 用于引入自定义的头文件。这些头文件位于你本身的项目的目录中。

咱们再来看一下对应的 game.h 这个头文件的内容:

看到了吗,.h 文件中存放的是函数原型。

你已经对一个项目有大体概念了。

那你又会问了:“为何要这样安排呢?把函数原型放在 .h 头文件中,在 .c 源文件中用 #include 引入。为何不把函数原型写在 .c 文件中呢?”

答案是:方便管理,条理清晰,不容易出错,省心。

由于如前所述,你的电脑在调用一个函数前必须先“知道”这个函数,咱们须要函数原型来让使用这个函数的其余函数预先知道。

若是用了 .h 头文件的管理方法,在每个 .c 文件开头只要用 #include 这个指令来引入头文件的全部内容,那么头文件中声明的全部函数原型都被当前 .c 文件所知道了,你就不用再操心那些函数的定义顺序或者有没有被其余函数知道

例如个人 main.c 函数要使用 functions.c 文件中的函数,那我只要在 main.c 的开头写 #include "functions.h",以后我在 main.c 函数中就能够调用 function.c 中定义的函数了。

你可能又要问了:“那我怎么在项目中加入新的 .h 和 .c 文件呢?”

很简单,在 CodeBlocks 里,鼠标右键点击项目列表的主菜单处,选择 Add Files,或者在菜单栏上依次单击 File -> New -> File... ,就能够选择添加文件的类型了。

引入标准库


你脑海里确定出现一个问题:

若是咱们用 #include 来引入 stdio.h 和 stdlib.h 这样的标准库的头文件,而这些文件又不是我本身写的,那么它们确定存在于电脑里的某个地方,咱们能够找到,对吧?

是的,彻底正确!

若是你使用的是 IDE(集成开发环境),那么它们通常就在你的 IDE 的安装目录里。

若是是在纯 Linux 环境下,那就要到系统文件夹里去找,这里不讨论了,感兴趣的读者能够去网上搜索。

在个人状况,由于安装的是 CodeBlocks 这个 IDE,因此在 Windows下,个人头文件们“隐藏”在这两个路径下:

C:\Program Files\CodeBlocks\MinGW\include

C:\Program Files\CodeBlocks\MinGW\x86_64-w64-mingw32\include

通常来讲,都在一个叫作 include 的文件夹里。

在里面,你会找到不少文件,都是 .h 文件,也就是 C语言系统定义的标准头文件,也就是系统库的头文件(对 Windows,macOS,Linux 都是通用的,C语言原本就是可移植的嘛)。

在这众多的头文件当中,你能够找到咱们的老朋友:stdio.h 和 stdlib.h。

你能够双击打开这些文件或者选择你喜欢的文本编辑器来打开,不过也许你会吓一跳,由于这些文件里的内容不少,并且好些是咱们还没学到的用法,好比除了 #include 之外的其余的预处理指令。

你能够看到这些头文件中充满了函数原型,好比你能够在 stdio.h 中找到 printf 函数的原型。

你要问了:“OK,如今我已经知道标准库的头文件在哪里了,那与之对应的标准库的源文件(.c 文件)在哪里呢?”

很差意思,你见不到它们啦。由于 .c 文件已经被事先编译好,转换成计算机能理解的二进制码了。

“伊人已去,年华不复,吾将何去何从?”

既然见不到原先的它们了,至少让我见一下“美图秀秀”以后的它们吧…

能够,你在一个叫 lib 的文件夹下面就能够找到,在个人 Windows 下的路经为:

C:\Program Files\CodeBlocks\MinGW\lib

C:\Program Files\CodeBlocks\MinGW\x86_64-w64-mingw32\lib

被编译成二进制码的 .c 文件,有了一个新的后缀名:.a(在 CodeBlocks 的状况,它的编译器是 MinGW。MinGW 简单来讲就是 GCC 编译器的 Windows 版本)或者 .lib(在 Visual C++ 的状况),等。这是静态连接库的状况。

你在 Windows 中还能找到 .dll 结尾的动态连接库;你在 Linux 中能找到 .so 结尾的动态连接库。暂时咱们不深究静态连接库和动态连接库,有兴趣的读者能够去网上自行搜索。

这些被编译以后的文件被叫作库文件或 Library 文件(library 表示“库,图书馆,文库”),不要试着去阅读这些文件的内容,由于是看不懂的乱码。

学到这里可能有点晕,不过继续看下去就会渐渐明朗起来,下面的内容会有示意图帮助理解。

小结一下:
在咱们的 .c 源文件中,咱们能够用 #include 这个预处理指令来引入标准库的 .h 头文件或本身定义的头文件。这样咱们就能使用标准库所定义的 printf 这样的函数,电脑就认识了这些函数(借着 .h 文件中的函数原型),就能够检验你调用这些函数时有没有用对,好比函数的参数个数,返回值类型,等。

4. 分开编译


如今咱们知道了一个项目是由若干文件组成的,那咱们就能够来了解一下编译器(compiler)的工做原理。

以前的课里面展现的编译示例图是比较简化的,下图是一幅编译原理的略微详细的图,但愿你们用心理解并记住:

上图将编译时所发生的事情基本详细展现了,咱们来仔细分析:

  • 预处理器(preprocessor):顾名思义,预处理器为编译作一些预备工做,因此预处理器是在编译以前启动的。它的任务是执行特殊的指令,这些指令是经过预处理命令给出的,预处理命令以 # 开头,很容易辨认。

预处理指令有好多种,目前咱们学过的只有 #include,它使咱们能够在一个文件中引入另外一个文件的内容。#include 这个预处理指令也是最经常使用的。

预处理器会把 #include 所在的那一句话替换为它所引入的头文件的内容,好比

#include <stdio.h>

预处理器在执行时会把上面这句指令替换为 stdio.h 文件的内容。因此到了编译的时候,你的 .c 文件的内容会变多,包含了全部引入的头文件的内容,显得比较臃肿。

  • 编译(compilation):这是核心的步骤,之前的课咱们说过,正是编译把咱们人类写的代码转换成计算机能理解的二进制码(0 和 1 组成)。编译器编译一个个 .c 文件。对于 CodeBlocks 这样的 IDE 来讲,就是你放在项目列表中的全部 .c 文件;若是你是用 gcc 这个编译器来编译,那么你要指定编译哪几个 .c 文件。

编译器会把 .c 文件先转换成 .o 文件(有的编译器会生成 .obj 文件),.o 文件通常叫作目标文件(o 是 object 的首字母,表示“目标”),是临时的二进制文件,会被用于以后生成最终的可执行二进制文件。

.o 文件通常会在编译完成后被删除(根据你的 IDE 的设置)。从某种程度上来讲 .o 文件虽然是临时中间文件,好像没什么大用,但保留着不删除也是有好处:假如项目有 10 个 .c 文件,编译后生成了 10 个 .o 文件。以后你只修改了其中的一个 .c 文件,若是从新编译,那么编译器不会为其余 9 个 .c 文件从新生成 .o 文件,只会从新生成你更改的那个。这样能够节省资源。

  • 连接器(linker):顾名思义,连接器的做用是连接。连接什么呢?就是编译器生成的 .o 文件。连接器把全部 .o 文件连接起来,“制做成”一个“大块头”:最终的可执行文件(在 Windows下是 .exe 文件。在 Linux 下有很多种形式)。

如今你知道从代码到生成一个可执行程序的内部原理了吧,下面咱们要展现给你们的这张图,很重要,但愿你们理解并记住。

大部分的错误都会在编译阶段被显示,但也有一些是在连接的时候显示,有多是少了 .o 文件之类。

以前那幅图其实还不够完整,你可能想到了:咱们用 .h 文件引入了标准库的头文件的内容(里面主要是函数原型),函数的具体实现的代码咱们还没引入呢,怎么办呢?

对了,就是以前提到过的 .a 或 .lib 这样的库文件(由标准库的 .c 源文件编译而成)。

因此咱们的连接器(linker)的活还没完呢,它还须要负责连接标准库文件,把你本身的 .c 文件编译生成的 .o 目标文件和标准库文件整合在一块儿,而后连接成最终的可执行文件。

以下图所示:

这下咱们的示意图终于完整了。

这样咱们才有了一个完整的可执行文件,里面有它须要的全部指令的定义,好比 printf 的定义。

5. 变量和函数的做用范围


为告终束这一课,咱们还得学习最后一个知识点:变量和函数的做用范围(有效范围)

咱们将学习变量和函数何时是能够被调用的。

函数的私有变量(局部变量)

当你在一个函数里定义了一个变量以后,这个变量会在函数结尾时从内存中被删除。

int multipleTwo(int number)
{
    int result = 0;  // 变量 result 在内存中被建立
    result = 2 * number;

    return result;
}  // 函数结束,变量 result 从内存中被删除

在一个函数里定义的变量,只在函数运行期间存在。

这意味着什么呢?意味着你不能从另外一个函数中调用它。

#include <stdio.h>

int multipleTwo(int number);

int main(int argc, char *argv[])
{
    printf("15 的两倍是 %d\n", multipleTwo(15));
    printf("15 的两倍是 %d", result);   // 错误!

    return 0;
}

int multipleTwo(int number)
{
    int result = 0;
    result = 2 * number;

    return result;
}

能够看到,在 main 函数中,咱们试着调用 result 这个变量,可是由于这个变量是在 multipleTwo 函数中定义的,在 main 函数中就不能调用,编译会出错。

记住:在函数里定义的变量只能在函数内部使用,咱们称之为 局部变量,英语是 local variable。local 表示“局部的,本地的”,variable 表示“变量”。

全局变量(请避免使用)


全局变量的英语是 global variable。global 表示“全局的,整体的”。

能被全部文件使用的全局变量

咱们能够定义能被项目的全部文件的全部函数调用的变量。咱们会展现怎么作,是为了说明这方法存在,可是通常来讲,要避免使用能被全部文件使用的全局变量。

可能这样作一开始会让你的代码简单一些,可是不久你就会为之烦恼了。

为了建立能被全部函数调用的全局变量,咱们需要在函数以外定义。一般咱们把这样的变量放在程序的开头,#include 预处理指令的后面。

#include <stdio.h>

int result = 0;  // 定义全局变量 result

void multipleTwo(int number);  // 函数原型

int main(int argc, char *argv[])
{
    multipleTwo(15); // 调用 multipleTwo 函数,使全局变量 result 的值变为原来的两倍

    printf("15 的两倍是 %d\n", result);  // 咱们能够调用变量 result

    return 0;
}

void multipleTwo(int number)
{
    result = 2 * number;
}

上面的程序中,咱们的函数 multipleTwo 再也不有返回值了,而是用于将 result 这个全局变量的值变成 2 倍。以后 main 函数能够再使用 result 这个变量。

因为这里的 result 变量是一个彻底开放的全局变量,因此它能够被项目的全部文件调用,也就能被全部文件的任何函数调用。

注:这种类型的变量是很不推荐使用的,由于不安全。通常用函数里的 return 语句来返回一个变量的值。
只能在一个文件里被访问的全局变量

刚才咱们学习的彻底开放的全局变量能够被项目的全部文件访问。咱们也可使一个全局变量只能被它所在的那个文件调用。

就是说它能够被本身所在的那个文件的全部函数调用,但不能被项目的其余文件的函数调用。

怎么作呢?

只须要在变量前面加上 static 这个关键字。以下所示:

static int result = 0;

static 表示“静态的,静止的”。

函数的 static(静态)变量


注意:
若是你在声明一个函数内部的变量时,在前面加上 static 这个关键字,它的含义和上面咱们演示的全局变量是不一样的。
函数内部的变量若是加了 static,那么在函数结束后,这个变量也不会销毁,它的值会保持。下一次咱们再调用这个函数时,此变量会延用上一次的值。

例如:

int multipleTwo(int number)
{
    static int result = 0;   // 静态变量 result 在函数第一次被调用时建立
    result = 2 * number;

    return result;
}   // 变量 result 在函数结束时不会被销毁

这到底意味着什么呢?

就是说:result 这个变量的值,在下次咱们调用这个函数时,会延用上一次结束调用时的值。

有点晕是吗?没关系。来看一个小程序,以便加深理解:

#include <stdio.h>

int increment();

int main(int argc, char *argv[])
{
    printf("%d\n", increment());
    printf("%d\n", increment());
    printf("%d\n", increment());
    printf("%d\n", increment());

    return 0;
}

int increment()
{
    static int number = 0;
    number++;
    return number;
}

上述程序中,在咱们第一次调用 increment 函数时,number 变量被建立,初始值为 0,而后对其作自增操做(++ 运算符),因此 number 的值变为 1。

函数结束后,number 变量并无从内存中被删除,而是保存着 1 这个值。

以后,当咱们第二次调用 increment 函数时,变量 number 的声明语句(static int number = 0;)会被跳过不执行(由于变量 number 还在内存里呢。你想,一个皇帝还没驾崩,太子怎么能继位呢?)。

咱们继续使用上一次建立的 number 变量,这时候变量的值沿用第一次 increment 函数调用结束后的值:1,再对它作 ++ 操做(自加 1),number 的值就变为 2 了。

依此类推,第三次调用 increment 函数后 number 的值为 3。第四次 number 的值为 4。

因此程序的输出以下:

1
2
3
4

一个文件中的局部函数(本地函数或静态函数)


咱们用函数的做用域来结束咱们关于变量和函数的做用域的学习。

正常来讲,当你在一个 .c 源文件中建立了一个函数,那它就是全局的,能够被项目中全部其余 .c 文件调用。

可是有时咱们须要建立只能被本文件调用的函数,怎么作呢?

聪明如你确定想到了:对了,就是使用 static 关键字,与变量相似。

把它放在函数前面。以下:

static int multipleTwo(int number)
{
    // 指令
}

如今,你的函数就只能被同一个文件中的其余函数调用了,项目中的其余文件中的函数就只“可远观而不可亵玩焉”…

小结一下变量的全部可能的做用范围


  1. 在函数体内定义的变量,若是前面没加 static 关键字,则是局部变量,在函数结束时被删除,只能在本函数内被使用。
  2. 在函数体内定义,可是前面加了 static 关键字,则为静态变量,在函数结束时不被删除,其值也会保留。
  3. 在函数外面定义的变量被称为全局变量,若是前面没有static关键字,则其做用范围是整个项目的全部文件,就是说它能够被项目的全部文件的函数调用。
  4. 函数外面定义的变量,若是前面加了 static 关键字,那就只能被本文件的全部函数调用,而不能被项目其余的文件的函数调用。

小结一下函数的全部可能的做用范围


  1. 一个函数在默认状况下是能够被项目的全部文件的函数调用的。
  2. 若是咱们想要一个函数只能被本文件的函数所调用,只须要在函数前加上 static 关键字。

6. 总结


  1. 一个程序包含一个或多个 .c 文件(通常称为源文件,source file。固然,咱们通常也把全部的高级语言代码叫作源代码)。一般来讲,每一个 .c 文件都有一个和它同名但不一样扩展名的 .h 文件。.c 文件里面包含了函数的实际定义,而 .h 文件里包含函数的原型声明。
  2. .h 文件的内容被一个叫作预处理器(preprocessor)的程序引入到 .c 文件的开头。
  3. .c 文件被一个叫作编译器(compiler)的程序转换成 .o 的二进制目标文件。
  4. .o 文件又被一个叫作连接器(linker)的程序连接成一个最终的可执行文件(在 Windows 操做系统里可执行程序的扩展名是 .exe,由于 exe 是英语 executable 的前三个字母,表示“可执行的”。在 Linux 系统里,可执行程序有很多扩展名(.elf,等),也能够没有扩展名)。
  5. 变量和函数都有“有效范围”,某些时候是访问不到的。

7. 第二部分第二课预告


今天的课就到这里,一块儿加油吧!

下一课:C语言探索之旅 | 第二部分第二课:进击的指针,C语言的王牌!


我是 谢恩铭,公众号「程序员联盟」(微信号:coderhub)运营者,慕课网精英讲师 Oscar 老师,终生学习者。 热爱生活,喜欢游泳,略懂烹饪。 人生格言:「向着标杆直跑」
相关文章
相关标签/搜索