初学者深入理解C语言

    • C语言起源
    • 为什么选择C语言呢
    • 计算机能为C语言干啥
    • 编译器
    • C语言标准
    • 使用C语言的7个步骤
    • 编程机制
            • 目标代码文件,可执行文件和库

这篇博客是为我的朋友准备的,是我对C语言的理解与认识,当然新手老手都可以看一下,当作温习一下了嘛,顺便还可以指出一些不足之处。

C语言起源

首先先介绍一下C语言的起源,了解一门语言知道它的历史也是很重要的。
话说1972年的一个美好的一天,突然!突然编不下去了。好了进入正题,贝尔实验室的丹尼斯·里奇(Dennis Ritch)和肯·汤普逊(Ken Thompson)在开发UNIX操作系统时设计了C语言。然而C语言并不是突发奇想来的,是在B语言的基础上来的,B语言大家有兴趣可以去了解一下,这里不做介绍。C语言设计的初衷是将其作为程序员使用的一种编程工具。

为什么选择C语言呢

C语言为什么能够经久不衰,这是凭借C语言的自身实力。这里介绍一下C语言的几个突出优点:

  • 设计特性。C语言很好的融合了计算机科学理论和控制特性。C语言的设计理念可以帮助我们自顶向下规划,结构化编程和模块化设计(两个字,好用!)。
  • 高效。C语言在设计时充分利用了计算机的优势,C语言具有汇编语言的微调控能力(反正很nb,可以控制硬件,这是其他语言做不到的),可以根据具体情况微调程序以获得最大运行速度或最高效利用内存。
  • 可移植。就可以C语言在一台机器运行移植到其他机器照样可以运行。比如你在家睡觉很香,睡大街依然可以睡得香(当然这是不恰当的比喻),但是某些人睡大街就睡不着。
  • 强大灵活。UNIX操作系统大部分都是用C语言编写的,你说6不6吧。
  • 面向程序员。C语言是为了满足程序员的需求设计的,程序员可以利用C语言访问硬件,操纵内存中的位。在我们脑海中操纵硬件一般都要亲自动手实践才行,但是这个我们只用敲几行代码就可以访问硬件了,6不6。
  • C语言很灵活。你可以自由发挥,编写有意思的程序,有个国际大赛叫C语言混乱代码大赛(IOCCC),目的就是就是写出最有创意且让人难以理解的C语言代码。当然C灵活也是它的缺点,你可能一不小心就让你电脑出故障了。

计算机能为C语言干啥

要理解C语言在计算机上的工作流程,首先要知道计算机能干些啥。当然计算机能干的可多了,这里只讲一下与C语言有关的。CPU承担了计算机绝大部分运算工作,先来看一下CPU工作原理。它从内存中获得一条指令并执行这条指令,然后再从内存中获取并执行下一条指令,诸如此类。(1GHz的CPU一秒钟可以执行这样的操作10亿次,6不6)CPU有自己的小工作区——寄存器,相当于一个小仓库,每个仓库可以存放一个数字。有一个仓库用来储存下一条指令的地址,CPU找到这个地址就获取了下一条指令了。还有一个小仓库用来存放指令,就相当于一个仓库存放房间号,一个仓库存放房间里的东西。找到房间号就可以获取房间里东西了。下面介绍两个有趣的小知识:

  • 存放在计算机中的所有内容都是数字,所有内容最终都是转换成0和1存储在计算机中。
  • 计算机程序最终必须以数字指令码来表示(只能存储数字肯定只能用数字指令码啦)。即C语言程序最终都是被转换成0和1的数字指令码。
    OK,那现在以一个加法运算的例子来理解一下。
    1.从内存2000把一个数字拷贝到寄存器1。
    2.从内存2004把另一个数字拷贝到寄存器2。
    3.把寄存器1和寄存器2中的内容相加,结果放在寄存器1中。
    4.把寄存器1的内容拷贝到内存2008。
    CPU最终是以数字码来表示以上的每一个步骤的。
    如何把C语言转化成计算机可识别的数字码呢?这就是编译器的作用了。

编译器

计算机是只能读懂机器语言的,C语言是高级语言,计算机读不懂,我们编写的C语言程序最终都要通过编译器转化成计算机可以识别的机器语言。编译器还有一个优势,不同CPU制造商使用的指令系统和编码格式不同,也就是这个指令在这台计算机可以运行,但是在另一台它根本不认识你是啥。编译器可以把高级语言转化成不同类型CPU使用的机器语言,相当于一个多语言翻译官,可以翻译成英语,德语,giao语,郭语给不同的人听。
编译分为编译和链接这两个过程。编译就是把你的源代码转化成可执行的代码(即机器语言的形式)。你的C语言经常会用到C库(C库就是一个大仓库,里面很多函数功能可以直接使用,比如交换函数,打印函数等等),链接就是把你用到的C库的代码和你的程序结合起来形成一个完整的可执行程序,然后计算机执行就可以了。

C语言标准

每个语言都有它的标准,英语有语法,汉语也有语法,C语言也是一样,有格式要求。第一个C标准是ANSI C,国际标准组织管它叫IOS C,它们的最终版本叫C89(89年批准该标准的)。后来又陆续出现了C90,C99,C11。C99标准的目标是为适应科学和工程项目中的关键数值计算,提高C的适应性(瞟一眼就行,知道C标准干啥就行)。

使用C语言的7个步骤

  • 定义程序的目标。你写这个程序是干嘛用的。
  • 设计程序。如何设计这个程序实现你的目标。很多人直接忽略了前两步,当程序很短很简单这是可以的,当程序很复杂时这两步就很重要了。
  • 编写代码。这一步最关键,也是头秃之根源。
  • 编译。这是编译器干的事。
  • 运行程序。CPU执行程序
  • 测试和调试程序。你的程序难免会出现一些小毛病(计算机行话叫bug),查找并修复程序的过程叫调试。刚开始编程肯定会出现很多错误,不过熟练后错误会越来越少。
  • 维护和修改代码。你想加入一个新功能或者想到一个更好方法就修改代码。

编程机制

想学好C,必须深入理解C语言程序的编程机制。前面介绍了一个C语言程序是通过编译和链接这两个步骤转化成机器语言让计算机执行的。但这其中具体的细节是什么?第一步先干啥,然后再干啥?这里来具体介绍一下C语言的编程机制。

  • 我们编写的C程序被存储在文本文件中,这个文件被称为源代码文件,大部分C系统要求这个文件名是以".c"结尾的。比如helloworld.c和wordcount.c。点号前面的部分称为基本名,点号后边的部分叫做扩展名。基本名和扩展名的组合就是文件名。文件名在不同操作系统有不同限制,比如有的UNIX操作系统文件名不能超过14个字符,有的可以达到255个字符。
目标代码文件,可执行文件和库

这三个概念是编程机制最重要三个概念。
我们知道是先进行编译,把源程序转化成中间代码(一般为机器语言),再把中间代码和其它代码链接起来生成一个完整的可执行文件。这种方式就很就很方便了,编译之后是一个一个的模块,然后链接器再把这些模块链接起来,如果你需要修改一个模块,剩下模块就不需要改动了,很利于程序的修改。
编译形成的中间文件有很多形式,一般就是机器语言,这里只讲机器语言。编译之后把源代码转化成的机器语言放在一个文件里,这个文件叫目标代码文件。扩展名为.obj,目标代码文件是不能够执行的,因为这是编译来的,还不是一个完整的程序,因为还没有把库函数链接进来呢,怎么可能完整呢?
目标代码文件不完整体现在以下两个方面。

  • 目标代码文件缺失启动代码,顾名思义,启动代码充当程序和操作系统之间的接口。例如Windows操作系统和Linux操作系统所需要的启动代码就不同,可以这样理解启动代码就类似一个店铺的窗口,通过不同的窗口可以买不同店家的东西。
  • 目标代码文件缺少库函数,几乎所有的C程序都要用到库函数的,这就是为什么你每个C程序开头都会有若干个include的原因,实际上就是引用库函数。比如你程序要用到打印函数printf(),这个函数的真正代码其实就在C库中。链接器要把目标代码文件、启动代码、库这三部分合并成一个部分,即可执行文件扩展名为.exe。这个文件双击就可以运行了,在我们计算机上经常可以看到这种文件。

下面以在UNIX系统和Linux系统上编译C程序举例。在UNIX系统上C编译器会创建一个与源代码基本名相同的目标代码,扩展名是.o。比如源代码是hello.c,那么这个目标代码文件就是hello.o。但是我们找不到这个文件,这是为什么呢?因为链接器生成可执行文件后就会将目标代码文件删除了。而在Linux系统上呢,目标代码文件扩展名是.obj。而且与UNIX不同的是,Linux不会删除这些目标代码文件。

更多推荐

初学者深入理解C语言