二、基本概念
环境
ANSI C 有翻译和执行两种环境,且不必在一台机器上,例如交叉编译器(cross compiler);操作系统也是如此(freestanding environment)。
翻译:将源代码转换为可执行机器指令
执行:实际执行代码
翻译(translation environment)
翻译经过以下阶段:
- 编译器(compiler):编译形成目标代码(object code)。还包括预处理(preprocesser)。
- 链接器(linker):把上面的那些代码与c函数库使用的函数链接到一起。
- 解析器(parse):判断语句的意思
- 优化器(optimizer):优化代码提升效率
形成的目标文件后缀可能在不同系统下不同,如(.o/.obj)
cc -c xx.c #编译产生.o目标代码文件
cc xx.c .... 直接产生可执行程序
cc xx.o ... 链接几个目标代码文件
执行(excute environment)
通常有操作系统由操作系统完成
- 用一个堆栈(stack)来存储局部变量和返回地址,也可以使用static内存来存储static变量(整个程序中都会保留里面的变量的值)
词法规则
字符
标准没有定义那些字符可以用,但是必须包含常用的一些字符和空白字符
- 关于三字母词(trigrph):
??( // [
??) // ]
??< // {
??> // }
??= // #
??/ // \
??! // |
??' // ^
??- // ~
- 转义序列(escape sequence)或字符转义(character escape)
//第一类无特殊含义
\?
\'
\"
\\
//第二类有特殊含义
\a //警告字符,可能发出声音,linux需要打开警示音,windows是有声音的。
\b //退格符,从现在\b的位置开始向前移动一个位置,遇到\n,\r停止,开始输出后面的内容
\f //进纸字符,从\f开始换一页输出后面的内容
\n //保持现在列的位置不变,换行输出后面的字符(LF),显示结果和理论有点冲突??结果\n和\r\n显示的结果是一样的??
\r //回车符CR,输出前面的内容后,把光标移到行首,输出后面的内容,不用换行符的话会覆盖之前输出的内容。
\t //相当于一个四个空格的tab键
\v //这个好,显示\n的真实效果,见上。
\ddd //"\ddd"每一位d都是一个8进制数,这个字符串就是表示对应的ASCII字符
\xddd //与上同,只不过换成了16进制
标识符(identifier)
数字,字母,下划线命名,但是不能以数字开头,不能以关键字作为标识符
- 关键字:
1.auto do goto signed unsigned
2.break double if sizeof void
3.case else int static volatile
4.char enum long struct while
5.const extern register switch continue
6.float return typedef default for
7.short union
编程练习
编写一个程序,它从标准输入读取C源代码,并验证所有的花括号"{}"都成对出现。
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void){
5 int ch,braces;
6
7 braces = 0;
8
9 while((ch=getchar())!=EOF){//这里的EOF在windows下是ctrl+z,在linux下是ctrl+d
10 if(ch=='{'){
11 braces+=1;
12 }
13
14 if(ch=='}'){//注意这里是单引号
15 if(braces==0) printf("extra closing brace!");
16 else braces-=1;
17 }
18
19 }
20
21 if(braces>0) printf("%d unmatched closing braces\n",braces);
22
23
24 return EXIT_SUCCESS;
25
26 }