《21天学通C语言》第一天

21天学通C语言

第1部分 C语言基础

第1课 初识C语言

欢迎学习本课程!本课将是你成为C程序员高手之路的开始。本课将介绍以下内容:

  • 在众多程序设计语言中,为什么C语言是首选
  • 程序开发周期中的步骤
  • 如何编写、编译和运行第1个C程序
  • 编译器和链接器生成的错误消息

1.1 C语言发展简史

读者一定非常好奇C语言的起源及其名字的由来。1972年,丹尼斯·里奇(Dennis Ritchie)在贝尔电话实验室发明了C语言。发明该语言的初衷是为了设计UNIX操作系统(现在用于许多计算机上)。从一开始,C语言就致力于为程序员排忧解难。

C语言因功能强大和灵活,很快便广泛应用于贝尔实验室以外的各领域。世界各地的程序员都开始用它编写程序。不久,各个组织开始使用自己版本的C语言,但是各种版本C语言的实现存在细微差别,这让程序员头疼不已。为解决这一问题,美国国家标准协会(ANSI)于1983年成立了一个委员会,制定了C语言的标准定义,即ANSI C标准。当前的C编译器(极少例外)都支持这个标准。

注意 :C语言极少改动,最新的改动是2011年的ANSI C11标准。该标准在C语言中添加了一些新特性(本书已涵盖)。但是,旧的编译器可能不支持目前的最新标准。

为什么叫C语言? 之所以叫C语言,是因为它的前辈是B语言。B语言由贝尔实验室(Bell Labs)的**肯·汤普逊(Ken Thompson)**发明。至于为什么叫B语言就不言而喻了。

1.2 为何要使用C语言

如今,在计算机程序设计领域,可供选择的高级语言很多,如C、Perl、BASIC、Java、PHP和C#。这些语言都能很好地完成程序设计任务,但是基于以下几个原因,使得C语言仍是众多计算机专业人士的首选:

  1. 功能强大、十分灵活:你完全想不到C语言能帮你完成什么工作。语言本身不会给你带来任何限制。C语言可用于各种操作系统、文字处理软件、图形、电子表格、甚至是其他语言的编译器。

  2. 非常流行:是众多专业程序员的首选。因此,市面上很容易找到各种C语言的编译器和辅助工具。

  3. 可移植性:可移植意味着一台计算机系统(如IBM PC)中写出的C程序,无需修改或少量修改便可在其他操作系统(如DEC VAX系统)中运行。除此之外,在微软Windows操作系统中编写的程序,也可移到Linux系统的机器中(无需修改或少量修改)。ANSI标准进一步改善了C语言的可移植性,为C编译器添加了一系列规则。

  4. 短小精悍:只包含少量关键字(keyword)。C语言以关键字为基础构建语言的功能,C语言编程离不开关键字。你可能认为一门语言中关键字(有时也称为保留字)越多功能越强大,其实并非如此。

  5. 模块化:C代码可以(且应该)以例程形式编写,这些例程称为函数(function)。函数可复用于其他程序或应用。通过传递信息给函数,可以创建有用且能重复使用的代码。

正是由于上述特性,使得C语言成为程序设计语言的首选。那C++怎样?你可能在别处了解过C++和面向对象程序设计(object-oriented programming)技术。C与C++有何不同?是否应该自学C++?

别担心!C++是C的超集,这意味着C++中不仅包含了C的所有内容,还添加了面向对象程序设计的新特性。如果你继续学习C++,会发现C中所学的知识几乎都可应用于C++。学习C语言,不仅学了一门现在功能最强大、最流行的程序设计语言,而且还为学习面向对象程序设计做好了准备。

另一门备受关注的语言是Java。Java和C++一样,也是基于C语言发展起来的。如果将来学习Java,你会发现在C语言中学过的所有知识点都用得上。

最新的一门语言是C#(发音为"See-Sharp")。与C++和Java类似,C#也是一门源自C的面向对象语言。同样,在C语言中学到的内容可以直接用于C#程序设计。

注意:许多学过C语言的人,后来都会选择学习C++、Java或C#。先学习C语言,再学其他语言会轻松许多。

1.3 准备编程

解决问题之前肯定要经过一些步骤。首先,必须定义问题。如果不知道问题是什么,根本不可能找到解决方案!知道问题所在,才能设法修正。如果你想到一个解决方案,通常会去实施它。之后,你必须知道问题是否解决了。这样解决问题的逻辑可以应用到各个领域,包括程序设计。

用C语言创建一个程序(或者说,用任意语言编写的计算机程序)时,应该遵循以下步骤的顺序:

  1. 确定程序的目标------明确你要解决什么问题
  2. 确定在编程时所使用的方法------规划如何解决问题
  3. 创建程序解决问题------编写代码实现方案
  4. 运行程序查看结果------测试并验证解决方案

目标(步骤1) 可能是编写一个文字处理软件或数据库程序。简单的目标可以是在屏幕上显示你的姓名。没有目标就不可能写出程序,因此,如果要写程序就已经准备好第一步了。

接下来,第2步要确定你编写的程序中所使用的方法。你是否需要计算机程序来解决问题?要记录什么信息?程序中要使用什么公式?在这一步中,应该明确自己需要了解什么知识以及实施方案的具体步骤。

例如,假设你要写一个计算圆面积的程序:

  • 第1步已经完成,因为目标明确:计算圆的面积。
  • 第2步,分析如何确定圆的面积。例如,假设用户提供圆的半径。了解这些以后,便可通过公式π*r²计算得出结果。

现在,可以继续第3步和第4步,进入程序开发周期。

1.4 程序开发周期

程序开发周期的步骤是:

  1. 使用编辑器创建磁盘文件保存源代码
  2. 编译源代码创建目标文件
  3. 链接已编译的代码创建可执行文件
  4. 运行程序,看看程序是否能按原计划运行
1.4.1 创建源代码

源代码(source code) 是一系列语句或命令,指导计算机执行特定的任务。如前所述,程序开发周期的第1步是编辑器中输入源代码。例如,下面这行C源代码:

c 复制代码
printf("Hello, Mom!");

这行语句命令计算机在屏幕上显示消息Hello, Mom!(到目前为止,不用管如何执行语句)。

1.4.2 使用编辑器

绝大多数C语言都是在集成开发环境(IDE) 中进行编译的,集成开发环境能让你在它的编辑器中输入程序并编译程序,同时还能调试和创建应用(这些概念今后会学到)。你完全不必使用额外的编辑器。

尽管如此,绝大多数计算机系统仍包含可用作编辑器的程序:

  • 如果使用Linux或UNIX系统,可以使用ed、ex、edit或vi编辑器
  • 如果使用微软Windows系统,可以使用Notepad或WordPad

大部分文字处理软件都使用特殊的代码格式化文档,在其他程序中无法正确读取这些代码。美国信息交换标准码(ASCII) 几乎为所有的程序(包括C)指定了一个标准文本。许多文字处理软件(如WordPerfect、Microsoft Word、WordPad和WordStar)都能以ASCII形式保存源文件(将源文件作为文本文件而不是文档文件保存)。如果要以ASCII文件保存一个文字处理软件的文件,在保存时必须选择ASCII选项或文本选项。

如果不想用上述编辑器,也可以购买其他的编辑器。市面上有许多专门为输入源代码而设计的软件包(包括商业的和共享软件)。

在保存文件之前必须先给文件命名。文件名应描述该程序的用途。另外,保存C程序的源文件时,文件的扩展名是.c。尽管可以为源文件取任意文件名和扩展名,但是.c是公认较合适的扩展名。

1.4.3 编译源代码

虽然你明白C源代码(至少在学习本书后你会明白),但是计算机不明白。计算机只能理解数字或二进制(binary)的机器语言(machine language)指令。在计算机运行C语言之前,必须先将源代码翻译成机器语言。

这个翻译过程属于程序开发的第2步,由编译器(compiler) 来执行(编译器也是一个程序)。编译器将源代码作为输入,生成磁盘文件,其中包含源代码相应的机器指令。编译器创建的机器语言指令被称为目标代码(object code) ,包含目标代码的文件称为目标文件(object file)

注意 :本书涵盖ANSI C标准,这意味着只要编译器遵循ANSI标准,你可以使用任意编译器进行编译。然而,并非所有的编译器都支持该标准。当前的C语言标准名为ISO/IEC 9899:2011 。为简单起见,本书在提到该标准时均用C11代替复杂的标准名。

使用图形集成开发环境来编译程序非常简单。在大多数图形环境中,通过选择"编译"图标或相应的菜单选项即可编译程序清单。在编译代码后,选择"运行"图标或相应的菜单选项来执行程序。在使用编译器之前,应先查看编译器的用户手册,了解编译器编译和运行程序的规范。

Code::Blocks就是一个图形开发环境,有各种操作系统的版本,可免费下载。除此之外,还有许多适用于多平台的其他图形开发环境,读者可依自己喜好免费下载或购买。

编译完成后,生成一个目标文件。如果查看编译目录或文件夹中的文件列表,会发现一个与源文件同名的文件,但是扩展名是.obj(不是.c)。扩展名为.obj的文件是目标文件,供链接器使用。在Linux和UNIX系统中,编译器生成的目标文件扩展名是.o,不是.obj

1.4.4 链接以创建可执行文件

在运行程序之前,还要完成一步。函数库 是ANSI C语言定义的一部分,其中包含了预定义函数的目标代码(已编译过的代码)。预定义函数(predefined function) 包含已编写好的C代码,在编译器的软件包中可随时使用。

1.4.1节中使用的printf()函数就是一个库函数(library function) 。库函数用于执行一些经常需要完成的任务(如,在屏幕上显示信息、从磁盘文件中读取数据等)。如果在程序中使用了这些函数(几乎所有的程序都需要使用库函数),必须将编译源文件时生成的目标文件与库函数的目标文件合并,创建最终的可执行程序(可执行的意思是,可以在计算机上运行或执行程序)。上述过程称为链接(link) ,执行这一过程的程序称为链接器(linker)

复制代码
计算机 --> 使用编辑器 --> 源代码 --> 编译源代码 --> 目标代码
                                                  ↓
                                             库文件 链接目标文件 --> 可执行文件
1.4.5 完成开发周期

程序经过编译和链接将创建一个可执行文件,点击"运行"按钮即可运行该文件(假设在集成开发环境中进行操作)。如果运行程序后得到的结果与预期不符,则需要回到第1步。必须找出问题所在,并更正源代码。一旦改动了源代码,就要重新编译和重新链接程序,以创建更正后的可执行文件。重复这个过程直至程序的执行情况与预期相符。

关于编译和链接还要注意一点,虽然本书将编译和链接分成两个独立的步骤来讲解,但是大多数编译器都将其合为一个步骤。通常,图形开发环境会提供一个选项,让用户设置是分开完成编译和链接还是一步完成。无论以哪种方式完成编译和链接,都要明白,即使只使用一条命令来完成编译和链接,它们仍是两个独立的行为。

C程序的开发周期如下

步骤 操作 输入 输出 说明
1 使用编辑器编写源代码 想法和算法 源代码文件(.c) 传统上,C源代码文件的扩展名是.c(如myprog.c、database.c)
2 使用编译器编译程序 源代码文件(.c) 目标文件(.obj或.o) 如果编译器发现错误会报错。必须返回步骤1,在源代码中更正错误
3 使用链接器链接程序 目标文件 + 库文件 可执行文件(.exe) 如果不出错,链接器将创建可执行程序
4 执行程序 可执行文件 程序运行结果 测试程序,判断它是否如期正常运行。如果不是,返回步骤1

除最简单的程序外,在完成程序前,几乎所有的程序都要按顺序执行这些步骤多次。即使是经验丰富的程序员也不可能一蹴而就,写出没有任何错误的程序!因为要多次重复编辑-编译-链接环节,所以必须熟悉你所使用的工具:编辑器、编译器和链接器。

1.5 第1个C程序

按以下步骤输入和编译hello.c程序。

推荐开发环境

  • Dev C++
  • VS Code
  • Visual Studio 2022/2025
  • Code::Blocks
  • CLion

第一个C程序:hello.c

c 复制代码
#include <stdio.h>

int main(void) {
    printf("Hello, World!\n");
    return 0;
}

程序解释

  1. #include <stdio.h>:包含标准输入输出头文件,让程序可以使用printf()等函数
  2. int main(void):程序的主函数,每个C程序都必须有且只有一个main函数
  3. { }:花括号内是函数体,包含要执行的语句
  4. printf("Hello, World!\n");:在屏幕上显示"Hello, World!",\n表示换行
  5. return 0;:函数返回值,0表示程序正常结束

编译运行步骤

  1. 打开你选择的IDE
  2. 创建新项目或新文件
  3. 输入上面的代码
  4. 保存文件为hello.c
  5. 点击编译按钮(通常是一个齿轮或锤子图标)
  6. 点击运行按钮(通常是绿色三角形)

如果一切正常,你将在控制台看到输出:Hello, World!

1.6 小结

本章介绍了C语言的基础知识,为后续学习奠定了坚实的基础。我们学习了:

  1. C语言的历史:从贝尔实验室的丹尼斯·里奇发明C语言,到ANSI标准化,再到今天的C11标准。
  2. 为什么选择C语言:因其功能强大、流行、可移植、简洁和模块化等优点。
  3. 编程准备:明确问题、规划方案、编写代码、测试结果的四步法。
  4. 程序开发周期:编辑->编译->链接->测试的循环过程。
  5. 第一个C程序:编写并运行了经典的"Hello, World!"程序。

C语言不仅是学习编程的绝佳起点,也是理解计算机底层工作原理的重要工具。掌握C语言后,学习其他语言(如C++、Java、C#)将更加容易。

1.7 答疑

问:如果要将自己编写的程序提供给他人,应提供哪些文件?

答:通常只需要提供**可执行文件(.exe)**即可。但是,如果你希望他人能够修改或学习你的代码,应该提供:

  • 源代码文件(.c文件)
  • 头文件(.h文件,如果有的话)
  • 项目文件(如果使用IDE)
  • 使用说明文档

如果程序依赖于特定的库,还需要提供相关信息或动态链接库(DLL)。

问:创建可执行文件后,是否还要保留源代码或目标代码?

答:强烈建议保留源代码,因为:

  1. 未来可能需要修改或升级程序
  2. 调试时需要参考源代码
  3. 学习或教学目的
  4. 作为个人项目作品集的一部分

目标文件(.obj/.o)通常可以删除,因为它们可以从源代码重新生成。但是,在大型项目中,保留目标文件可以加快编译速度(增量编译)。

问:如果只有C++编译器没有C编译器,怎么办?

答:大多数C++编译器都可以编译C代码,但需要注意:

  1. 将文件扩展名改为.cpp可能使编译器按C++规则编译
  2. 最好保持.c扩展名,并在编译器设置中指定按C语言编译
  3. C++是C的超集,但有一些细微差别:
    • C++要求函数原型,C不强制
    • C++中const变量的处理方式不同
    • C++有更严格的类型检查
  4. 使用extern "C"链接说明符可以确保C++正确处理C函数

问:是否可以忽略警告消息?

答:不推荐忽略警告消息,因为:

  1. 警告通常是潜在问题的指示器
  2. 某些警告可能预示着未定义行为
  3. 在调试阶段,警告可以帮助发现逻辑错误
  4. 良好的编程习惯是处理所有警告,使程序"零警告"编译

但是,在某些情况下,如果确定警告不影响程序正确性,并且是由于编译器过于严格导致的,可以使用编译器选项暂时禁用特定警告。例如,在GCC中使用-Wno-xxx选项。

1.8.1 简答题

  1. 简述C语言的发展历史及其名称的由来

    C语言由丹尼斯·里奇于1972年在贝尔实验室发明,最初用于开发UNIX操作系统。它的名称来源于其前身B语言(由肯·汤普逊发明),B语言本身又源自BCPL语言。

  2. 列举至少三个选择C语言而不是其他高级语言的理由

    (1) 功能强大且灵活,几乎可用于任何编程任务

    (2) 可移植性好,同一代码可在不同平台运行

    (3) 执行效率高,接近汇编语言的性能

    (4) 为学习其他语言(C++、Java、C#)打下坚实基础

  3. 描述程序开发周期的四个主要步骤

    (1) 编辑:使用文本编辑器编写源代码(.c文件)

    (2) 编译:使用编译器将源代码转换为目标代码(.obj/.o文件)

    (3) 链接:使用链接器将目标代码与库文件合并生成可执行文件(.exe文件)

    (4) 测试:运行可执行文件,验证程序功能

  4. 解释编译器和链接器在程序开发中的作用

    编译器将人类可读的源代码翻译成机器可执行的目标代码,检查语法错误;链接器将多个目标文件及库文件组合成单一的可执行文件,解析外部引用和函数调用。

  5. 为什么说学习C语言有助于学习C++、Java等其他语言?

    因为C++、Java、C#等现代编程语言都深受C语言影响,共享相似的语法结构、控制流程和编程概念。C语言的核心思想(如指针、内存管理)在这些语言中都有体现或变体。

  6. 什么是ANSI C标准?为什么它很重要?

    ANSI C标准是美国国家标准协会制定的C语言规范,确保不同编译器生成的代码具有一致性和可移植性。它很重要因为它定义了C语言的核心特性,使程序员可以编写跨平台的代码。

1.8.2 练习题

  1. 环境配置练习

    下载并安装一个C语言开发环境(如Code::Blocks、Dev C++或VS Code的C/C++扩展),配置编译器路径,确保能够成功编译和运行C程序。

  2. 第一个程序修改

    修改"Hello, World!"程序,使其显示以下内容:

    复制代码
    ====================
    欢迎学习C语言编程!
    这是第1章的学习内容
    作者:[你的名字]
    ====================
  3. 编译错误调试

    故意在程序中制造以下错误,观察编译器的反应:

    • 删除#include <stdio.h>
    • main拼写为mian
    • 删除语句末尾的分号
    • 删除一个花括号
      记录每种错误对应的错误消息,并理解其含义。
  4. 多文件编译练习

    创建两个源文件:

    • main.c包含main函数,调用print_message()函数
    • message.c包含print_message()函数,显示一条消息
      分别编译这两个文件,然后链接它们生成可执行程序。
  5. 程序结构分析

    分析以下程序,预测其输出,然后实际运行验证:

    c 复制代码
    #include <stdio.h>
    
    int main(void) {
        printf("Line 1\n");
        printf("Line 2\n");
        printf("Line 3");
        printf(" still Line 3\n");
        printf("Line 4\n");
        return 0;
    }

    注意\n换行符的作用和多个printf语句在同一行的效果。

  6. 扩展练习:简单计算器

    编写一个程序,计算并显示以下内容:

    • 半径为5.0的圆的面积(公式:π*r²,π取3.14159)
    • 边长为3和4的矩形的周长
    • 1到10的整数和

    程序输出格式如下:

    复制代码
    圆面积:78.53975
    矩形周长:14
    1到10的和:55

学习建议

  • 实际动手敲代码,不要只看不练
  • 遇到错误时仔细阅读错误信息,学会自己排查问题
  • 养成写注释的好习惯,解释代码的意图
  • 尝试修改示例代码,观察不同的效果
  • 加入编程社区,参与讨论和分享

学习编程就像学习游泳,只有跳进水里才能真正学会。不要害怕犯错,每个程序员都是从"Hello, World!"开始的。祝你学习愉快,编程之路一帆风顺!

相关推荐
Rysxt_2 小时前
UniApp pages.json 配置完全指南
开发语言·前端·javascript
三七吃山漆2 小时前
攻防世界——Web_php_wrong_nginx_config
开发语言·nginx·安全·web安全·网络安全·php·ctf
csbysj20202 小时前
XML Schema 复合类型 - 混合内容
开发语言
代码游侠2 小时前
学习笔记——网络基础
linux·c语言·网络·笔记·学习·算法
wjs20242 小时前
Web品质 - 重要的HTML元素
开发语言
枫叶丹42 小时前
【Qt开发】Qt事件(二)-> QKeyEvent 按键事件
c语言·开发语言·数据库·c++·qt·microsoft
leo_2323 小时前
从开发语言角度来谈谈SMP(上)--SMP(软件制作平台)语言基础知识之十三
开发语言·开发工具·smp(软件制作平台)·应用系统
Larry_Yanan11 小时前
Qt多进程(三)QLocalSocket
开发语言·c++·qt·ui
醒过来摸鱼11 小时前
Java classloader
java·开发语言·python