重读经典:《C和指针》学习笔记
《C和指针》、 《C专家编程》、 《C陷阱和缺陷》并称c语言三本经典著作,笔者在许多年前囫囵吞枣读完了这三本经典,然后把这三本书束之高阁。时至今日,大部分内容都已忘记,前些时间偶然翻出来,重读这些经典,顺便做做笔记,记录其精华。
《C和指针》通过对指针的基础知识和高级特性的探讨,帮助程序员把指针的强大功能融入到自己的程序中去。
第1章 快速上手
本章讲的是C语言的基础知识,目的是使读者对C语言有一个整体的初步的认识。
这一章给读者一些忠告,包括:
- 使用/*和*/进行块注释时,需要注意块中是否包含有*/这样的结束符号,还有一种块注释的方法,就是使用#ifdef预编译命令
- 编程时注意=和==、&和&&的区别,不要漏写或者多写
- 在调用scanf函数时,传入的参数为指针类型,不要忘记写&
- 使用#include指令可以避免重复声明,同时减少代码量
- getchar()函数的返回值是整数而不是字符类型(《C陷阱和缺陷》也强调这个问题)
第2章 基本概念
第二章仍然讲C语言的基础知识,主要知识点包括:
1、程序的编译链接环境和运行环境可以有所不同;
程序的编译和链接,编译是将源文件翻译成目标文件,包括对define和include等预处理器的替换;链接是将目标文件和所需要的库文件生成可执行文件;
2、标识符
- 对于标识符的长度,ANSI标准规定外部标识符长度至少能由前6个字符唯一区分,并且不区分大小写,内部标识符长度至少能由前31个字符唯一区分。为保证代码的可移植性,最好严格遵守这一标准。(《C陷阱和缺陷》也强调过这个问题)
- 当然,程序猿定义的标识符是不能与C语言保留关键字冲突的。
3、字符转义
C中定义了一些字母前加”\”来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。
C语言中转义字符有两种表示方式,一种是在字符前加”\”,还有一种是三字母词。大多数程序猿只了解第一种,对第二种并不熟悉。
三字母词就是几个字符的序列,合起来表示另一个字符,比如
三字母词 | 含义 |
---|---|
??( | [ |
??< | { |
??= | # |
??) | ] |
??> | } |
??/ | \ |
??! | |
??’ | ^ |
??- | ~ |
“\”转义
部分转义字符定义:
转义字符 | 含义 |
---|---|
\a | 警告字符,可能会奏响铃声或者产生一些其它可见字符 |
\b | 退格 |
\f | 进纸 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | 表示1-3个八进制数字,给定的八进制数转义为对应的ASCII字符 |
\xddd | 表示1-3个十六进制数字,给定的十六进制数转义为对应的ASCII字符,这个值大小可能超出范围 |
注:
1,\v垂直制表和\f换页符对屏幕没有任何影响,但会影响打印机执行响应操作。
2,\n其实应该叫回车换行。换行只是换一行,不改变光标的横坐标;回车只是回到行首,不改变光标的纵坐标。
3,\t 光标向前移动四格或八格。
4,\b是退格键,往前移动光标,不删除字符,但该字符可能会被后续字符覆盖。
5,这些都是从电传打字机沿用下来的。
4、编程风格
C语言是一种自由形式的语言,语法较为宽松,但良好的程序风格和文档将使代码更容易阅读和维护。
第3章 数据
第3章仍然讲C语言的基础知识,主要讲数据类型的定义。
1、C语言数据类型
C语言的数据类型包括基本类型、聚合类型和指针类型,基本类型主要包括int,char,float,double,聚合类型包括结构体、数组、枚举和联合,具体类型见下图:
其中有些细节需要注意:
ANSI标准规定:长整型至少应该和整型一样长,整型至少应该和短整型一样长。标准同时规定长整型的长度至少为32位,短整型至少为16位,对于整型的长度并没有明确规定。究竟整型数的长度是32位还是16位或者是64位,取决于编译器。当然,编译器可以把这三种类型的长度都设置为32位。
设计char类型的初衷是为了容纳字符类型,但其本质是8位的整型数据。至于缺省的char类型是signed还是unsigned,由编译器决定。为确保可移植性,char类型变量应该位于signed和unsigned的交集,即ascii字符集中。
2、指针类型
int *a;
int* a;
这两种定义的结果是一样的,都是将a定义为一个int类型的指针。
但是,如果要定义三个指针,正确的方式是:
int *a,*b,*c;而不是int* a,b,c;
3、常量
常量使用const修饰,常量在运行过程中不可修改,初始化一个常量由两种方法,
一种是在定义的时候进行初始化;
另一种是在函数调用的时候,声明为const类型的形参将被初始化为实参
int * const p;这种定义,p是常量,指针的值不可改变,但指针指向的内容可以改变;
int const * a;这种定义,*p是常量,指针的值可改变,但指针指向的内容不可改变;
这两种定义的含义不同
4、作用域
一个标识符的作用域有四种类型:
- 文件作用域:
- 代码块作用域:
- 函数作用域:goto语句后的标识符
- 原型作用域:函数声明中形参名字
5、static关键字
static关键字有两种用法,