《The C Programming language》 -- Brian W. Kernighan / Dennis M. Ritchie
相关笔记:《C和指针》摘录笔记 读《TCPL》II
看电子书是一件非常辛苦的事情。需要长时间的坐在电脑面前,在冬天里还需要牺牲一只手去移动鼠标或者电脑的下滑键(自动翻页只适合小说,看The C Programming language 在某些地方还得停下来)。英文还不是很好and书还是英文的,很多不知道的地方估计都以脑海空白的形式略过了。书还是看纸质的比较好,没那么累,尤其对于一个做一件事情完全没有节制的人来说。
怎么个没节制法呢,花了两天将《The C Programming language》浏览完了。现在的感觉是极度疲劳。坚持电子档而不去打印纸质的原因是PDF有签字功能,将书中看到的“不熟悉的”、“觉得重要的”、“实践中需要常查阅的”、“具启蒙意义的”都给标志在书签里,然后将其整理成笔记。由于学习过C语言课程后,很长的一段时间(一两年)都没有看过进阶方面的书籍,开始看书后,看的第一本也不是这本《C圣经》,其它书籍的很多原型在这本书中都应该找得到。这算是学习C语言的一个弯路。虽然在实践中将一些部分(如指针概念)搞清楚了,毕竟个人的悟性还是带有局限性。前辈们整理的“优秀”书籍对后代人具有启蒙意义,学到的不仅是未知、深入部分的知识。所以,不管眼下在做什么事情,千万不要忘记要多看“优秀的书籍”,不管哪个领域。看“优秀书籍”是进步的灵魂,如果你不是天才的话。
《The C Programming language》, By Brian W.Kernig han and Dennis M.Rithie。
1.C语言程序从main处开始执行(main是C语言程序的入口)。
2. 经声明(declared)的C变量才可被C程序使用。
3.int、short、long、double等基本数据类型占内存的字节数依靠具体的平台(如win32下int占4 bytes)。
4.‘%’(如用于printf中)表示紧跟其后的类型由实参代替。“%%”表示输出‘%’本身(printf)。
5.‘c’为’0’~’9’之间的字符,则++num[c-‘0’]实现c-‘0’数字的个数为num[c-‘0’]。
6.C程序中,函数参数传值方式是一个拷贝过程。实参传递给形参时,就相当于给一个局部变量赋值。
7.字符串数组以’\0’字符结尾。’\0’对字符数组来说是一个很有用的标识。很多函数要依靠此标识来判断字符串是否结束。C语言中没有提供关于字符串数组的任何操作符,唯有通过指针来操作字符串数组。
8. 为什么不同类型(全局,局部,const)的变量的访问性不同。是硬件还是软件的作用?
9.C程序的内部变量名最多可以有31个字符。外部变量名和函数名必须少于31个字符。自定义标识符不可以与C语言中的32个关键字同名。
10.一个字符常量是一个整数(ASCII值存于内存中)。
11.成对的双引号所引的字符串中可以在嵌套由成对双引号引起的字符串。若要单表示一个双引号时需要用“\””的形式。
12.要检查当前系统执行语句是从左到右还是从右到左。不然可能会引起严重错误。
13.将数字字符串转换为对应的数字时可以从高位算起。当还有下一个数字时,将原来得到的数字再乘以10加上当前个位的数字即可。
14.求x指定几位的算法:x >> (p+1 – n) & ~(~0<< n)。
15.运算符的优先级及结合性。可供读他人程序。
一元运算符、复合运算符及条件运算符的结合性由右至左。
16. “{}”的作用是组织声明和其他语句到一块形成一个复合语句(语句块)。
17. switch-case组合时,switch(c)中,c只可以是整型、字符型变量或表达式。case后面必须跟整型、字符型的“常量值”。case之间的值不可相同。因为const限制的变量是只读不为常量,故而const修饰的量也不能跟在case之后。
18. break语句可用于while、for、do-while循环结构中和switch-case结构中。continue只可以用于循环结构中。
20. register只可修饰自动变量和函数参数,数据类型要符合寄存器可支持的类型。register修饰的变量数目不可过多,且不可对register修饰的变量做&操作(取地址)。
21. C程序中,未初始化的全局变量和静态变量都系统自动赋值为0。自动变量和寄存器变量不会被初始化任何值(不定值)。在全局区初始化全局变量必须用常量或常量表达式。但对于整形和字符数组来说,不管哪一种类型,在初始化一部分数组元素后其余元素都为0。
22. 预处理。#include <filename>或#include ”filename”是将以各自方式找到的filename文件的内容来代替#include……语句。#define定义的宏除了注意给参数加括号外,给整体宏外加一层括号也是防错的必要手段。有的语句如sizeof不能够定义在诸如#undef内,编译器不会编译此下的内容。
系统已经定义的宏:
__LINE__当前代码的行数。
__FILE__当前正被编译文件的文件名。
__DATE__以"Mmmm dd yyyy"格式显示日期的字符串。
__TIME__以"hh:mm:ss"格式显示时间的字符串。
__STDC__值为1。若STDC值为1只在标准模式下。
23. void *p指针可以指向任何类型的数据,但是不可以指向void数据。“%p”就是void *类型。
24. 指针比数组块,但指针比较难用。对于指针效率很高的原因:C语言中赋值、传值都是采用拷贝的形式。对于大量数据而言,有了指针就可以只将数据的首地址传给指针,然后用指针访问到数据,避免数据拷贝。既节约空间也节约拷贝的时间。数组作为函数参数时,传递的实参数据块将地址传递给形参,形参被译为指针。所有的a[i]形式都会被编译成*(a+i)形式。
25. 指针若指向某块type数据,指针的加1操作表示地址向前sizeof(type)个字节即指向下个数据元素。
26. 0常被用作地址无效的标志。NULL被定义在stdio.h中,值为0。NULL作为一种助记符,对于指针来说是一个特殊的值。EOF被定义在stdio.h中,值为-1。作为文件结束的助记符。
27. 阅读C语言中的声明从变量名开始着手。熟悉一般的声明。可编写程序自动识别声明。
28. 可在常数后面加上数据的类型。如3.1f就明确的标明了3.1为浮点类型。
29. 重定向符’<’,’>’表示程序接受输入、输出的流发生了变化。如prog < infile表示prog程序从infile文件内接受输入的数据。管道’|’也能实现重定向,otherprog | prog表示同时执行otherprog和prog,otherprog的输出作为prog的输入。
30. 可变参数函数的实现依靠:va_list、va_start、va_arg、va_end实现。va_list定义的变量用来指向参数列表的每一个参数;va_start宏用来指引va_list变量指向下一个参数(必须先使va_list变量指向已知的变量参数);va_arg用数据类型决定返回类型并决定va_list变量的步长;va_end做清理工作,最后调用。
31. system(const char *s)。执行s。
32. void *calloc(size_t n, size_t size);分配n个数量的每个大小为size的内存块。内存块被初始化为0。
33. rand()创造浮点数空间、整数空间。与srand()的连用。
34. 对于unix系统,一切皆是文件。
35. Unix之上的系统调用(想起linux之上用汇编程序实现的系统调用,用标识号)。C语言实现系统调用是通过函数的名称。
write ---- 将缓冲区的数据向文件标识符参数对应的文件中写入。
open ---- 以指定模式打开文件标识符代表的文件。
close ---- 关闭文件标识符代表的文件。
create --- 创建文件。
unlink ---- 移除文件。
lseek ---- 随意定位文件中的内容。
Windows之上将这些函数称为非缓冲文件系统。
36. C的32个关键字中。volatile关键字较为陌生。
37. C标准库和C语言的关系。
C标准库由ANSI规定,它不是C语言的一部分。C标准库是支持标准C的一个库环境,很多的函数和宏都被定义在这些库里。在C标准库中,主要有以下15个库:
<assert.h> |
<float.h> |
<math.h> |
<stdarg.h> |
<stdlib.h> |
<ctype.h> |
<limits.h> |
<setjmp.h> |
<stddef.h> |
<string.h> |
<errno.h> |
<locale.h> |
<signal.h> |
<stdio.h> |
<time.h> |
对主要的库笔记如下:
<ctype.h>:字符测试函数都在此库里,包括isdigit()等函数。
<string.h>:关于字符串两个组别的函数,一类以str开头,如strlen();另一类以mem开头,如memcpy()。
<math.h>:数学函数库和相关宏的定义之处。如sin()。
<stdlib.h>:数据转换、内存管理及类似的函数库。如atof()、malloc()/free()等。
<assert.h>:用于程序断言。宏assert()。
<stdarg.h>:包含va_list、va_start、va_arg及va_end类型的库。
<setjmp.h>:提供函数函数跳转函数。setjmp及longjmp。
<signal.h>:提供处理的函数。如signal()函数。
<time.h>:提供函数和类型处理日期和时间。
<limit.h>:提供各数据类型的范围的宏定义。
<float.h>:浮点数据的宏。
38. The C ProgrammingLanguage的例子重点留给第二次看这本书的时候。
R《TCPL》Note Over。