写在前面,由于学过C语言,导致想要跳跃式地翻阅《C和指针》,后来发现这实为错误,对于这本经典著作,要做的是从头到尾保持体系的完整性。
《C和指针》配套代码请移步网站:Pointers on C
作者Kenneth A. Reek的个人网站

文章目录

  • 2.1环境
    • 2.1.1 翻译
    • 2.1.2 执行
  • 2.2 词法规则
    • 2.2.1 字符
    • 2.2.2 注释
    • 2.2.3 自由形式的源代码
    • 2.2.4 标识符
    • 2.2.5 程序的形式
  • 2.7 问题

2.1环境

在ANSI C的任何一种实现中,存在两种不同的环境。第1种是翻译环境(translation environment),在这个环境里,源代码被转换为可执行的机器指令。第2种是执行环境(execution environment),它用于实际执行代码。标准明确说明,这两种环境不必位于同一台机器上。例如,交叉编译器(cross compiler)就是在一台机器上运行,但它所产生的可执行代码运行于不同类型的机器上。操作系统也是如此。标准同时讨论了独立环境(freestanding environment),就是不存在操作系统的环境。

2.1.1 翻译

翻译阶段由几个步骤组成,组成一个程序的每个(有可能有多个)源文件通过编译过程分别转换为目标代码(object code)。然后,各个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。链接器同时也会引入C函数库种任何被该程序所用到的函数,而且它也可以搜索程序员个人的程序库,将其中需要使用的函数也链接到程序中。

编译过程本身也由几个阶段组成,首先是预处理器处理。在这个阶段,预处理器在源代码上执行一些文本操作。例如,用实际值代替由#define指令定义的符号以及读入由#include指令包含的文件的内容。

然后,源代码经过解析(parse),判断它的语句的意思。第2个阶段是产生绝大多数错误和警告信息的地方。随后,便产生目标代码。目标代码是机器指令的初步形式,用于实现程序的语句。如果我们在编译程序的命令行中加入了要求进行优化的选项,优化器(optimizer)就会对目标代码进一步进行处理,使它效率更高。优化过程需要额外的时间,所以在程序调试完毕并准备生成正式产品之前一般不进行这个过程。至于目标代码是直接产生的,还是先以汇编语言语句的形式存在,然后再经过一个独立的阶段编译成目标文件,对我们来说并不重要。

一 文件名约定
c源代码通常保存在以.c扩展名命名的文件中。由#include指令包含到c源程序的文件被称为头文件,通常具有扩展名.h.
至于目标文件名,不同的环境可能具有不同的性质。例如,在UNIX系统中,它们的扩展名是.o,但在MS-DOS系统中,它们的扩展名是.obj。

二 编译和链接
用于编译和链接c程序的特定命名在不同的系统中各不相同,但许多都和这里所描述的两种系统差不多。在绝大多数UNIX系统中,C编译器被称为cc,它可以用多种不同的方法来调用。
1 编译并链接一个完全包含于一个源文件的C程序:

cc program.c

这条命令产生一个称为a.out的可执行文件。中间会产生一个名为program.o的目标文件,但它在链接过程完成后会被删除。

2 编译并链接几个C源文件:

cc main.c  sort.c lookup.c

当编译的源文件超过一个时,目标文件便不会被删除。这就允许你对程序进行修改后,只对那些进行过改动的源文件进行重新编译,如下一条命令所示。

3 编译一个C源文件,并把它和现存的目标文件链接在一起:

cc main.o lookup.o  sort.c

4 编译单个C源文件,并产生一个目标文件(本例中为program.o),以后再进行链接:

cc -c program.c

5 编译几个C源文件,并为每个文件产生一个目标文件

cc -c main.c sort.c lookup.c

6 链接几个目标文件

cc main.o sort.o lookup.o

2.1.2 执行

程序的执行过程也需要经历几个阶段。首先,程序必须载入到内存中。在宿主环境(也就是具有操作系统的环境),这个任务由操作系统完成。那些不是存储在堆栈中的尚未初始化的变量将在这个时候得到初始值。

然后,程序的执行便开始了。在宿主环境中,通常一个小型的启动程序于程序链接在一起。它负责处理一系列日常事务,如收集命令行参数以便使程序能够访问它们。接着,便调用main函数。

现在,便开始执行程序代码。在绝大多数机器里,程序将使用一个运行时堆栈,它用于存储函数的局部变量和返回地址。程序同时也可以使用静态内存,存储于静态内存中的变量在程序的整个执行过程中将一直保留它们的值。

2.2 词法规则

一个ANSI C程序由声明和函数组成。函数定义了需要执行的工作,而声明则描述了函数和函数将要操作的数据类型(有时候是数据本身)。

2.2.1 字符

标准并没有规定C环境必须使用哪种特定的字符集,但它规定字符集必须包括英文所有的大写和小写字母,数字0到9,以及下面这些符号:

换行符用于标志源代码每一行的结束,当正在执行的程序的字符输入就绪时,它也用于标志每个输入行的结尾。 如果运行时环境需要,换行符也可以是一串字符,但它们被当作单个字符处理。字符集还必须包括空格、水平制表符、垂直制表符和格式反馈字符。这些字符加上换行符,通常被称作空白字符,因为当它们被打印出来时,在页面上出现的是空白而不是各种记号。

标准还定义了几个三字母词(trigrph),三字母词就是几个字符的序列,合起来表示另一个字符。 三字母词使C环境可以在某些缺少一些必需字符的字符集上实现。

三字母词 含义
??( [
??) ]
??! |
??< {
??> }
??’ ^
??= #
??/ \
??- ~

两个问号开头再尾随一个字符一般不会出现在其他表达式中,所以把三字母词用这种形式来表示,这样就不致引起误解。

当你在编写某些C源代码时,你在一些上下文环境里想要使用某个特定的字符,却可能无法如愿,因为该字符在这个环境里有特别的意义。 例如,双引号“” 用于界定字符串常量,你如何在一个字符串常量内部包含一个双引号呢? K&R C 定义了 几个转义序列(escape sequence) 或字符转义(character escape),用于克服这个难题。 ANSI C 在它的基础上又增加了几个转义序列。转义序列由一个反斜杠\加上一个或多个其他字符组成。 下面列出的每个转义序列代代表反斜杠后面的那个字符,但并未给这个字符增加特别的意义。

转义序列 含义
\? 在书写连续多个问号时使用,防止它们被解释为三字母词
\’’ 用于表示一个字符串常量内部的双引号
\’ 用于表示字符常量’
\\ 用于表示一个反斜杠,防止它被解释为一个转义序列符

有许多字符并不在源代码中出现,但它们在格式化程序输出或操纵终端显示屏时非常有用。C语言也提供了一些这方面的转义符,方便你在程序中使用它们。

转义序列 含义
\a 警告字符。它将奏响终端铃声或产生其他一些可听见或可看见的信号
\b 退格键
\f 进纸字符
\n 换行符
\r 回车符
\t 水平制表符
\v 垂直制表符
\ddd 表示1~3个八进制数字。这个转义符表示的字符就是给定的八进制数值所代表的字符
\xddd 用于表示十六进制数字

2.2.2 注释

C语言的注释以字符/*开始,以字符 * / 结束,中间可以包含除 */ 之外的任何字符。所有的注释都会被预处理器拿掉,取而代之的时一个空格。因此,注释可以出现在任何空格可以出现的地方。

下面这种嵌套是非法的

2.2.3 自由形式的源代码

C是一种自由形式的语言,也就是说并没有规则规定什么地方可以书写语句,一行中可以出现多少条语句,什么地方应该留下空白以及应该出现多少空白等。唯一的规则就是相邻的标记之间必须出现一至多个空白字符(或注释),不然它们可能被解释成单个标记。因此,下面语句是等价的

y=x+1;y= x +  1;y =x
+
1

至于下面这组语句,前3条语句是等价的,但第4条语句是非法的

int
x;int  x;int /*comment */ x; 合法intx; //非法

对于第三条语句进行实验

#include<stdio.h>int main() {/*/**/int /*这是个什么玩意?*/  x=1;printf("Hello,world:%d\n",x);
}

运行结果

Hello,world:1

2.2.4 标识符

标识符(identifier)就是变量、函数、类型等的名字。它们由大小写字母、数字和下划线组成,但不能以数字开头。C是一种大小写敏感的语言,所以abc,Abc,abC和ABC是4个不同的标识符。标识符的长度没有限制,但标准允许编译器忽略第31个字符以后的字符。标准同时允许编译器对用于表示外部名字(也就是由链接器操纵的名字)的标识符进行限制,只识别前六位不区分大小写的字符。

下列C语言关键字是被保留的,它们不能作为标识符使用

auto do goto  signed unsigned
break double if sizeof void
case else int static volatile
char enum long struct while
const extern register switch
continue float return typedef
default for  short union

2.2.5 程序的形式

一个C程序可能保存于一个或多个源文件中。虽然一个源文件可以包含超过一个的函数,但每个函数都必须完整地出现于同一个源文件中。标准并没明确规定,但一个C程序的源文件应该包含一组相关的函数,这才是较为合理的组织形式。这种做法还有一个优点,就是它使实现抽象数据类型称为可能。

2.7 问题

3.输出

"Blunder??!??"

代码

 printf("\"Blunder?\?!??\"");

《C和指针》读书笔记第二章基本概念相关推荐

  1. 《计算传播学导论》读书笔记——第二章文本分析简介

    <计算传播学导论>读书笔记--第二章文本分析简介 第一节 文本分析研究现状 常用文本挖掘技术 第二节 文本分析与传播学研究 (一)为什么文本挖掘技术逐渐受到传播学者的关注 (二)不同文本分 ...

  2. 深入理解 C 指针阅读笔记 -- 第二章

    Chapter2.h #ifndef __CHAPTER_2_ #define __CHAPTER_2_/*<深入理解C指针>学习笔记 -- 第二章*//*内存泄露的两种形式1.忘记回收内 ...

  3. In-memory Computing with SAP HANA读书笔记 - 第二章:SAP HANA overview

    本文为In-memory Computing with SAP HANA on Lenovo X6 Systems第二章SAP HANA overview的读书笔记. 本章最重要的部分是SAP HAN ...

  4. C++ Primer Plus读书笔记第二章

    自学了一段时间的C++打算还是要系统的整理一下一些知识点,让学习思路更清晰,不然老是学一点忘一点,这个读书笔记用来记录这段时间对C++ Primer Plus一书中知识点的记录,尽量会写的详细一点.直 ...

  5. 《软件测试经验与教训》读书笔记---第二章

    <软件测试经验与教训>读书笔记--目录 第一章 测试员的角色 第二章 按测试员的方式思考 第三章 测试手段 第四章 程序错误分析 第五章 测试自动化 第六章 测试文档 第七章 与程序员交互 ...

  6. 计算机网络(第五版 作者:AndrewS.Tanenbaum David J.Wetherall 清华大学出版社)读书笔记----第二章的学习

    计算机网络第二章--物理层读书笔记 1.物理层是网络的技术设置,物理层的材质和带宽决定了最大的传输速率. 2.传输介质的分类:引导性(有线介质)和非引导性(无线介质). (1)有线介质:磁介质.双绞线 ...

  7. 《辛雷学习方法》读书笔记——第二章 心态

    第二章 心态   (1)保持良好心态:学习时保持良好心态,你才能比较容易入门.深入掌握知识.灵活运用知识.学习时始终保持着轻松愉悦振奋的心情,你就容易产生学习心得,更容易灵活运用. (2)爱情对心态影 ...

  8. 《暗时间》读书笔记--第二章 进度条,第三章 有效记忆和学习

    第二章 进度条 要点: 进度条的例子 过早的退出 专注和持之以恒 饿死在甘草间的驴子 我的总结: 开篇作者讲了一个进度条的例子,我们的生活中充满着各种各样的进度条,工作的之前我们要做工作计划,要指定T ...

  9. 计算机系统导论——读书笔记——第二章 信息的表示和处理(持续更新)

    第二章 信息的表示和处理 2.1 信息存储 2.1.1 十六进制 2.1.2 字数据大小 2.1.3 寻址和字节顺序 1.地址:对象所使用的字节中最小的地址 2.大端法:最高有效字节在前 小端法:最低 ...

最新文章

  1. java中override快捷键_【基础回溯1】面试又被 Java 基础难住了?推荐你看看这篇文章。...
  2. MATLAB从入门到精通:MATLAB识别 自带手写数字集的CNN(LeNet5)
  3. 【Prometheus】存储
  4. Python进阶之路:namedtuple
  5. jdbc连接mysql传参_将参数传递给JDBC PreparedStatement
  6. Jenkins在AWS上(第1部分)
  7. java创建读取文件_Java实现文件的创建、读取、写入操作-Fun言
  8. 空间组网(卫星组网)概述
  9. I2C总线时序模拟(二)-加深理解总线协议
  10. idea社区版已经足够强大了
  11. python爬虫和八爪鱼哪个快_八爪鱼采集器能取代python爬虫吗?
  12. tianmao项目的学习笔记
  13. JavaScript截取文件扩展名
  14. 记忆碎片之python爬虫APP数据爬取fiddler抓包及多线程爬取流程分析(四)
  15. WebStorm下载及破解
  16. pythonturtle写字_python用turtle写字
  17. 假如我年少有为不自卑
  18. 不同坐标系下角速度_悠悠球的物理学原理(下)
  19. Python爬取携程最新车票(附导出EXCEL)
  20. 计算机指纹应用领域,指纹识别是计算机在什么方面的应用

热门文章

  1. 优秀的软件测试人员应该具备的素质
  2. Razor语法(一)
  3. [网站链接]Debbie博客上的链接: [求职网站][博客链接][信息资源]……
  4. 是否可能有一台算力无穷大的计算机?
  5. 用神经网络学习Fe原子光谱并反向求导计算权重
  6. java弱引用怎么手动释放,Java 如何有效地避免OOM:善于利用软引用和弱引用
  7. 【控制】《多智能体系统的协同群集运动控制》陈杰老师-第9章-多任务约束下多智能体协同编队控制
  8. VCS-bilibili教程篇1-Simulation Basics
  9. 【CMAC小脑】CMAC逼近sin(t)函数的训练和测试
  10. 【Kmeans】基于Kmeans的聚类算法的MATLAB仿真