IE盒子

搜索
查看: 133|回复: 1

1、初始C语言

[复制链接]

2

主题

10

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2023-4-4 13:49:09 | 显示全部楼层 |阅读模式
1、C语言的发展史:

学习和掌握一门新技术,首先需要掌握的就是它的历史,尽管我们无法详尽的了解其发展的每个过程,但也应该对其发展中的关键节点有所了解。
C语言是由来自贝尔实验室的丹尼斯·里奇(Dennis Ritchie)于1972年11月发布的。
丹尼斯·里奇,全名丹尼斯·麦卡利斯泰尔·里奇(Dennis MacAlistair Ritchie,1941年9月9日-2011年10月12日),美国计算机科学家。黑客圈子通常称他为“dmr”。他是C语言的创造者、C语言之父、Unix操作系统的关键开发者,对计算机领域产生了深远影响,并与肯·汤普逊同为1983年图灵奖得主。



更详细的内容可以参考这篇文章:C语言发展史的点点滴滴 - 腾讯技术工程的文章 - 知乎 https://zhuanlan.zhihu.com/p/257089138
C语言之所以能历经即几十年而不倒,除了它本身的语言特点之外,关键在于其在全球统一的标准。
1、“K&R”标准
1978年,丹尼斯·里奇与布莱恩·科尔尼汗联合出版了名为《C程序设计语言》,这是一份非正式标准,人们称这个版本的C语言为“K&R C”。
2、C89/C90标准
1983年,美国国家标准局(American National Standards Institute,ANSI)开始制定C语言标准,并于1989年12月完成,该标准称为“ANSI C”标准,也称为“C89”标准;
后来ANSI把“C89”标准提交到ISO(国际化标准组织),1990年被ISO采纳为国际标准,称为“ISO C”标准,因此也被称为“C90”标准。
3、C99标准
1999年发布ISO/IEC 9899:1999标准,通常被称为“C99”标准。
4、C11标准
2011年正式发布了ISO/IEC 9899:2011标准,简称为“C11”标准。
5、C17标准
C17(也被称为为 C18)是于2018年6月发布的 ISO/IEC 9899:2018 的非正式名称,也是目前为止最新的 C语言编程标准。
需要注意的是,不同的编译器支持的C语言标准是不一样的版本的,也并不是所有的编译器都完全支持C语言标准,有些编译器可能会增减一部分的C语言特性,我们需要根据不同的编译器灵活运用。这里先简单介绍一下,就像我们把英文翻译成中文一样,编译器就像一个翻译官,它可以把C语言翻译成计算机可以识别的机器语言,以便于计算机能够按照我们的需求来完成任务,更多有关编译器的内容在后面会详细介绍。
<hr/>2、C语言的语言特点

C语言是一门结构化程序设计语言。
结构化程序设计的概念最早由E. W. Dijikstra在1965年提出,它的主要观点是采用自顶向下、逐步细分和模块化的程序设计方法,使用顺序、选择、循环三种基本控制结构来构造程序。
所谓自顶向下就是要求在程序设计之初要高瞻远瞩、总揽全局,不要太关注旁枝末节,先把程序的主体框架确定下来;逐步细分就是在主体框架确定之后,根据不同的职能划分出不同层次的业务逻辑;模块化就是针对某个业务逻辑制定出一系列具体的实现步骤。所有的模块全部完成之后,整个程序也就基本完成,剩下的就是对这些模块像搭积木一样进行相应的拼装和调试。
C语言之所以历经弥新,至今能够排在编程语言前五,在于它有着自身独特的优点:
1、简洁性
C语言一共只有32个关键字和3种基本控制结构,可通过简短的代码实现模块,并对模块加以整合,从而构建出一个庞大复杂的程序。
2、灵活性
C语言程序书写形式自由,语法限制不太严格,程序设计自由度大。C语言能通过简单的整数类型、实数类型和字符类型,灵活地构造出更加复杂的数组、指针、结构体、联合体等复合数据类型,并以此实现链表、队列、栈、树、图等各种数据结构。
3、高效性
用C语言编译生成的目标代码质量和执行效率仅比用汇编语言编写的程序低一些,但相比使用其他的高级语言(C++、Java、C#等)编写出的程序要高。C语言是可移植语言中的效率最高的语言,其他高级语言能实现的,理论上用C语言也能实现。
需要注意,尽管C语言有着它自身的优点,但同时也是它的缺点,这是一体两面的。C语言的简洁也导致了它在实现更复杂的程序中所要编写的内容会更加复杂更加具体,这相对于其他更高级和抽象的语言来说并不一定是好的;如果滥用C语言的灵活性会导致C语言程序的结构混乱,后期维护将会极其困难;如果一味追求效率,C语言理论上可以实现,但是其耗费的时间和成本会比其他语言高得多。
<hr/>3、C语言的应用领域

基于C语言自身的特点,C语言更适合应用在开发系统软件中,比如操作系统的开发,数据库系统。
在当今物联网的发展中,C语言也在嵌入式领域有着比其他语言更高效和可移植的优点。
另外C语言是其他更高级语言的基础,或许你可以跳过C语言直接学习其他更高级语言,但学习C语言能够帮助你更好地理解计算机,如果想要深耕计算机相关知识,C语言应该是你不可避免的一门语言。
<hr/>4、C语言的开发环境

前面介绍了那么多,归根结底对我们来说最重要的就是要开发C语言程序,那么就需要配置好相应的C语言开发环境。
一个程序的完整开发流程如下:
编写代码——>编译程序——>执行程序
编写代码我们需要用到一个代码编辑器,而编译程序需要使用编译器,执行程序在命令行手动输入命令来执行程序。
代码编辑器可以选择Windows自带的记事本,也可以使用Notepad++(增强版记事本),或者其他代码编辑器如VSCode等。这里我们采用Notepad++。
从C语言诞生至今,出现了许许多多的编译器,这些编译器在不同的时间由不同的厂家和公司以及开发者个人实现出来,其中最主要的、比较流行的和使用比较广泛的就三类:TC、MS C和GCC。
TC是Turbo C的简称,Turbo C是美国Borland公司的产品,该公司在1987年首次推出Turbo C 1.0产品。不过现在使用TC的开发人员较少,没有下面的两个使用广泛。
MS C是Microsoft C的简称,它是鼎鼎大名的美国微软公司的产品,不过它一般都是在集成开发环境(IDE)中来使用,MS C很好地支持C89和C90标准,但对C99标准的支持还不够完美。
GCC是GNU C Compiler的简称,GNU是一个自由的操作系统,其内容软件完全以自由、开放的方式发布。GCC原本作为GNU操作系统的官方编译器,现已被大多数类UNIX操作系统(如Linux、BSD、Mac OS X等)采纳为标准的编译器。这里我们采用GCC编译器。
集成开发环境(Integrated Development Environment,简称IDE)是把代码的编写、程序的编译以及程序执行全部集成在一个软件上。通过简便的操作就能自动地完成三步操作,这样就极大地方便了程序的开发。集成开发环境往往还带有调试的功能,如果程序的运行结果出现错误或异常,可以轻松地对源文件中的代码进行定位和跟踪。
不过为了能够更好地理解和熟悉程序开发的过程,这里不会采用集成开发环境来开发程序。
我们这里采用Notepad++编写代码,在VMware Workstation 17 player平台下的虚拟机ubuntu系统中使用GCC编译器来编译程序,并在命令行输入命令执行程序。
有关Notepad++,VMware Workstation 17 player以及ubuntu系统的下载安装可查看相关网站和文章。
<hr/>5、第一个C语言程序

从本节开始,我们要正式编写C语言程序了,下面先按照层次建立文件夹:
先在Windows系统中新建一个C文件夹(位置自定,建议桌面,可以更方面查看和修改代码),将其设置为虚拟机中的共享文件夹(在虚拟机设置——>选项——>共享文件夹,启用共享并添加这个C文件夹)。在C文件夹下按照每一章建立相应的文件夹,比如本章是第1章,则新建一个“1”文件夹,在其中新建一个文本文档,将其改名为first.c后将下面代码写入文件。以后也按照这样在C文件夹下新建各章节文件夹。
/*第一个C语言程序*/
#include <stdio.h>
int main()
{
        printf("Hello world!\n");
        return 0;
}接着在ubuntu中打开命令行窗口(快捷键Ctrl+Alt+T),进入第1章文件夹(cd /mnt/hgfs/C/1/),查看该文件夹下的内容(ls),可以看到我们刚刚写的first.c文件。
我们编译它(gcc first.c -o first),可以得到一个名字为first的可执行文件,输入命令(./first)执行该文件,可以看到结果如图所示:


下面我们详细这些代码的含义和作用:
5.1代码注释

/*第一个C语言程序*/ :这是一个注释。
注释是为了程序员便于理解的,不管是为了之后能够看懂自己写的代码还是需要给别人看的代码,我们都应该有良好的代码注释的习惯。
块注释
第一行有 /* */ 括起来的内容就是注释的内容了。块注释允许出现在程序的任何地方,但不允许嵌套,即不允许下列情况
/* /*第一个C语言程序*/ */此时编译器会认为第一个“/*”到第一个“*/”才是注释。这时编译器会报错:语法错误。
行注释
用“//”可以表示行注释,从“//”开始,直到该行的末尾,都为注释的部分。
需要注意:
①注释只是给人看的,并不会参与编译,也就是说在真正编译的时候这些注释都会被忽略掉。
②错误的注释比没有注释更糟糕,注释的内容要做到表述清晰、文词达意,若代码被修改,注释也要及时更新。
5.2 文件包含

#include<stdio.h>:这是一个文件包含,它是一个预处理命令。
它的作用是将一个名字叫“stdio.h”的标准库头文件包含到当前源文件中。因为在程序编写中我们并不是所有代码都全部自己来写,而是使用其他人已经写好的代码,这时只需要包含相应的文件,编译器在编译时就会根据头文件路径找到相应的文件,并将文件中的代码复制过来替换这一行文件包含命令。
而我们下面用到的printf函数的相关内容正是在“stdio.h”这个头文件中。这里简单介绍一下函数,函数现在可以理解为一个机器,给它一定的原材料就会自动产出结果。比如printf的作用就是把后面括号中的内容(原材料)按照一定的规则显示在屏幕上(产出结果)。更多有关函数的内容后面会详细介绍。
5.3 main函数

C语言规定,在C程序代码中,必须有一个main函数。也就是C程序中可以没有其他的函数,但必须要有main函数(又称为主函数)。程序一运行,系统就会到程序中查找main函数,然后开始执行它,也就是程序总是从main函数开始执行的,所以又称之为入口函数。
在main函数中(位于一对大括号之间)有两行代码:第一行使用printf函数来输出字符串,最后的“\n”表示换行;第二行使用return语句返回一个0值。C语言的标准规定,main函数在执行完毕需要返回一个整数值,用这个值可以来检查程序的退出状态。若返回的是0值,表示程序执行成功正常退出,返回非0值表示程序是非正常退出的。
5.4 C语言程序编译过程

程序的编译看似一步完成,但是编译其实分别经过了预处理、编译、汇编和链接四个流程。



C语言程序编译流程

1.预处理
在源文件被编译之前,首先要进行预处理的工作,也就是对源代码进行相应的展开、替换和清理。在本例中,预处理工作有两项:①把代码注释部分去掉,不让其参与编译;②把“stdio.h”文件包含进来,即用“stdio.h”中的内容替换在“#include <stdio.h>”位置。
2.编译
源文件被预处理之后,再以字符流的形式进行处理,进行词法和语法的分析,然后通过汇编器将源代码指令转变成汇编指令,生成相应的汇编文件。
3.汇编
汇编是指把汇编语言代码翻译成目标机器指令的过程,也就是把汇编码转换成机器所能识别的二进制码,通常把经过汇编之后生成的文件称为目标文件。
4.链接
经过汇编之后生成的目标文件并不能立即被执行,还需要由链接器将代码在执行过程中用到的其他目标代码及库文件进行链接,最终生成一个可执行程序。例如本例中用到了printf函数,就需要找到包含该函数的标准库文件,对它进行链接。
5.5 C语言程序调试


  • 在代码编写过程中,我们不可避免地会出现各种各样的错误,总体来说:
    代码错误按照出现的时间上可分为两类:
    编译时错误
    运行时错误
    所谓编译时错误就是在写好源文件后,在进行编译时出现的错误,主要分为语法错误和链接错误两种。语法错误比较明显,解决也相对简单,编译器通常会给出错误的代码位置,程序员根据提示位置到代码中进行修改就行了。而链接错误通常是由于所需的库文件找不到或函数没有具体的实现等原因造成的。
    运行时错误,也就是编译可以顺利通过,但程序运行时出现了错误。例如程序崩溃和异常退出,程序运行造成死机,程序运行的结果不正确等。这类错误处理起来相对棘手,通常需要对程序进行反复的调试,才能找到问题所在。
  • 程序的调试主要是针对运行时错误而言的,主要方式有:
    1、人工调试
    人工调试就是通过人的眼看、脑算、手记等方法对程序代码进行调试的过程。这个通常只能解决简单的错误。
    2、代码调试
    代码调试通常采取在程序不同位置设置一些特定条件或可输出信息的程序代码,然后根据特定条件的执行情况或输出信息来判断、寻找错误的大概位置。在一些特定场合,比如嵌入式编程中,这是一种非常好的方式。
    3、工具调试
    工具调试采用功能强大的调试工具来对程序进行跟踪调试,这些调试工具通常都具有代码跟踪、断点设置、内存查询、变量监视等功能,可以通过一步一步地执行代码来观察程序的运行状态,极大地方便了对程序的调试。
  • GDB调试工具
    要使用GDB来调试程序,在使用GCC编译源文件时需要多加一个选项“-g”,即完整的编译命令为“gcc -g first.c -o first”。“-g”选项的作用是让编译后的程序里包含相关的调试信息,这样才能让GDB调试工具发挥作用;-o 的作用是生成可执行文件的名字为first,如果不指定文件名,则默认文件名是a.out。
    在控制台窗口输入命令“gdb first”,这样就进入程序调试界面。


以下是GDB的常用命令:
命令简写说明
backtracebt查看函数调用的相关信息
breakb在程序中设置断点
continuec继续运行至下一个断点处暂停
displaydisp跟踪查看某个变量
file装入需要调试的程序文件
framef查看栈帧
infoi显示程序的状态
killk终止调试程序
listl列出源代码
nextn执行下一条语句(不进入函数内部)
printp打印变量值
quitq退出调试
runr开始调试
set varname=v设置变量
startst开始执行程序,在main函数的第一条语句前停下来
steps执行下一步,可以进入函数内部
watch监视变量
回复

使用道具 举报

0

主题

5

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 昨天 01:58 | 显示全部楼层
大人,此事必有蹊跷!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表