跳转至

01. 程序的基本概念

1. 程序和编程语言

编写程序可以说就是这样一个过程:把复杂的任务分解成子任务,把子任务再分解成更简单的任务,层层分解,直到最后简单得可以用以上指令来完成。

表 1.1. 一个语句的三种表示

编程语言 表示形式
C语言 a=b+1;
汇编语言 mov 0x804a01c,%eax
add $0x1,%eax
mov %eax,0x804a018
机器语言 a1 1c a0 04 08
83 c0 01
a3 18 a0 04 08

习题

1、解释执行的语言相比编译执行的语言有什么优缺点?

解释执行的语言优点

  1. 快速开发和调试:解释执行的语言无需编译过程,可以直接执行代码,因此可以快速进行开发和调试。开发人员可以立即看到代码的结果,减少了开发周期。

  2. 跨平台性:解释执行的语言通常具有良好的跨平台性,因为解释器可以在不同的操作系统上运行。这意味着开发人员可以编写一次代码,并在不同的平台上执行,无需进行额外的适配工作。

  3. 动态性:解释执行的语言通常具有更大的灵活性和动态性。代码可以在运行时进行修改和调整,允许更快速地进行实验和迭代。

解释执行的语言缺点

  1. 执行效率相对较低:与编译执行的语言相比,解释执行的语言通常会牺牲一定的执行效率。因为在解释执行过程中,解释器需要逐行解释和执行代码,而不是直接将代码编译成机器语言。

  2. 依赖解释器:解释执行的语言需要依赖特定的解释器来执行代码。这意味着在执行代码之前,需要确保解释器已经安装并配置正确。这可能会导致一些可移植性问题,尤其是在一些嵌入式系统或特定的环境中。

  3. 代码保护性差:由于解释执行的语言通常将源代码暴露给解释器,代码的保护性较差。这使得代码更容易被反编译或修改,可能导致安全性问题。

并非所有的解释执行的语言都具有相同的优缺点,每种语言都有自己的特性和实现方式。

2. 自然语言和形式语言

自然语言:人讲的话——汉语英语...... 形式语言:数字符号、物理字母......

形式语言有严格的语法(Syntax)规则,由符号(Token)和结构(Structure)的规则组成。比如\(p \Rightarrow q\)

中间的是符号,左右两边的是对应结构的顺序。也就是说,假设这个情况是p为真推出q为真,那么如上从左到右书写,而不是从上到下或者以对角线形式书写。而q为真推出p为真的形式为\(q \Rightarrow p\)

解析(Parse):分析句子结构,比如英语中的定语从句,哪个是修饰前面单词的句子。

上下文(Context):语境

语义(Semantic):每个词在该场景表达的意思

现在给出一些关于阅读程序(包括其它形式语言)的建议。首先请记住形式语言远比自然语言紧凑,所以要多花点时间来读。其次,结构很重要,从上到下从左到右读往往不是一个好办法,而应该学会在大脑里解析:识别Token,分解结构。最后,请记住细节的影响,诸如拼写错误和标点错误这些在自然语言中可以忽略的小毛病会把形式语言搞得面目全非。

3. 程序的调试

编译时错误:出现在语法上 运行时错误:编译没查出来,比如说C语言中运行语句printf(1),会出现类型错误。

在C语言中,printf函数的第一个参数是一个格式化字符串,用于指定输出的格式。格式化字符串中包含了占位符,用于指定输出的数据类型和格式。例如,%d用于输出整数,%f用于输出浮点数,%s用于输出字符串等。

当你提供一个整数值 1 作为 printf 函数的第一个参数时,编译器会发现这个参数与格式化字符串不匹配,因为 1 不是一个格式化占位符。因此,编译器会报告一个格式错误,而不是类型错误。

要修复这个问题,你需要在格式化字符串中使用一个合适的占位符,以匹配要输出的数据类型。例如,如果你想输出整数值 1,你可以使用 %d 占位符,代码应该是 printf("%d", 1);

//报警告选项 -Wall
gcc -Wall main.c