第五周读书笔记——读《程序员的自我修养》有感

读《程序员的自我修养》有感git

花了几天时间,研读了《程序员的自我修养——连接、装载与库》。我的感受它在操做系统的底层机制和运行原理可谓是一本好书。惋惜我的修为不够、根底太浅,对Linux一样不熟悉。等之后有积累了再来回读一番。程序员

做者在序言里这样提出:计算机思想其实都是相通的,由于它们的核心思想是稳定不变的。这在我看来很大程度上是因为底层架构决定的,现行的计算机大多仍是冯·诺依曼架构(量子计算机还有待成熟),所以万变不离其宗。算法

做者是个极爱钻研的人,到处可见一斑。对于最简单的入门程序hello world”,做者对其提出了一连串的问题,这让我大感意外。“C语言程序为何要被编译后才能运行?”、“编译过程当中发生了什么?”、“不一样状况下的编译结果是否相同”。如此简单的程序背后每每蕴含着复杂机制,若是单单是做为一个编译器的使用者,天然没必要考虑这一切。可是若是但愿进一步对此有了解,乃至可以创造出更好的机制,那么这都是不可或缺的。从“预处理”、“编译”到“汇编”再到“连接”,编译器开始为咱们所理解。原来“#define”,“#include”在一开始就会被展开和替代。而在扫描过程当中进行源代码的生成,以后再进行一步步的工做。于此咱们能够见微知著,一部分原来有些强硬的规范其实有着深入的内涵。例如宏语句使用时的注意事项(尽可能加个括号),调试时“莫名其妙”被省略的变量(编译器提供的代码优化),开数组的时候全局变量每每能比局部变量分配更大的空间(堆栈与静态存储的不一样)。这些小细节不是空穴来风、而是底层架构在上层的具象反映。而掌握底层架构,可以使咱们更加精细地利用计算机的功能。编程

计算机科学有至关一部分须要依赖于自个人实践。做者为了了解操做系统及装载等这些关键的技术,他从头写了一个很小的内核、装载器及一个简单的运行库,作成了一个简单但较为完备的操做系统。尽管这些没什么直接收益(让GPA增长是不可能的,让本身发paper也是不可能的……),可是能够从中举一反三。我的做业时写简单的hash的时候和大数组搜索算法时由于好久不动,致使码了好久,因此说仅仅是领悟思想是不够的,还要付诸实践。看这本书的时候看到了语法树部分,感受它比数据结构课上所讲的中序表达式二叉树很为类似,就顺手写了个解释C语言代码(极简版)的代码,中间参考了别人的一些想法(主要是《C专家编程》),完成后让本身很有所得(尽管这无法计入成绩(*^_^*))。数组

 

 1 #include"stdio.h"
 2 #include"string.h"
 3 #include"ctype.h"
 4 #include"stdlib.h"
 5 
 6 #define MAXTOKENS 100        //设置语句中标识符的最大数量100
 7 #define MAXTOKENLEN 64        //设置标识符的最大长度64
 8 
 9 enum type_tag {IDENTIFIER,QUALIFIER,TYPE};        //IDENTIFIER=0,QUALIFIER=1,TYPE=2
 10 
 11 struct token    //结构体:标识符(token)
 12 {  13     char type;        //type:数据类型
 14     char string[MAXTOKENLEN];    //string[MAXTOKENLEN]:存储标识符名称的数组
 15 };  16 
 17 int top=-1;  18 struct token stack[MAXTOKENS];        //stack[]:存储整句语句的标识符的数组(堆栈)
 19 struct token these;        //these:临时存储单个标识符的变量
 20 
 21 #define pop stack[top--]
 22 #define push(s) stack[++top] = s    //push(s):将变量s压入stack数组顶端
 23 
 24 enum type_tag classify_string(void)        /*推断标识符的类型*/
 25 {  26     char *s = these.string;            /*用指针s代替these的string数组使用(简洁)*/
 27     if(!strcmp(s,"const"))            //若是string中是"const"
 28  {  29         strcpy(s,"read-only");        //将s中的"const"翻译为"read-only"
 30         return(QUALIFIER);  31  }  32     if(!strcmp(s,"volatile"))  33         return(QUALIFIER);  34     if(!strcmp(s,"void"))            //下面一系列if判断,返回type:数据类型说明
 35         return(TYPE);  36     if(!strcmp(s,"char"))  37         return(TYPE);  38     if(!strcmp(s,"signed"))  39         return(TYPE);  40     if(!strcmp(s,"unsigned"))  41         return(TYPE);  42     if(!strcmp(s,"short"))  43         return(TYPE);  44     if(!strcmp(s,"int"))  45         return(TYPE);  46     if(!strcmp(s,"long"))  47         return(TYPE);  48     if(!strcmp(s,"float"))  49         return(TYPE);  50     if(!strcmp(s,"double"))  51         return(TYPE);  52     if(!strcmp(s,"struct"))  53         return(TYPE);  54     if(!strcmp(s,"union"))  55         return(TYPE);  56     if(!strcmp(s,"enum"))  57         return(TYPE);  58     return(IDENTIFIER);  59 }  60 
 61 void gettoken(void)            /*读取下一个标记到"these"*/
 62 {  63     char *p = these.string;  64 
 65     /*跳过空白字符*/
 66     while((*p = getchar()) == ' ');  67 
 68     if(isalnum(*p))            /*输入的字符以A-Z,0-9开头*/
 69  {  70         while(isalnum(*++p = getchar()));  71         ungetc(*p,stdin);  72         *p='\0';  73         these.type = classify_string();  74         return;  75  }  76 
 77     if(*p == '*')  78  {  79         strcpy(these.string,"pointer to");  80         these.type = '*';  81         return;  82  }  83     these.string[1] = '\0';  84     these.type = *p;  85     return;  86 }  87 
 88 /*理解全部分析过程的代码段*/
 89 void read_to_first_identifier(void)  90 {  91  gettoken();  92     while(these.type != IDENTIFIER)  93  {  94  push(these);  95  gettoken();  96  }  97     printf("%s is ", these.string);  98  gettoken();  99     return; 100 } 101 
102 void deal_with_arrays(void) 103 { 104     while(these.type == '[') 105  { 106         printf("array "); 107         gettoken();            /*数字或']'*/
108         if(isdigit(these.string[0])) 109  { 110             printf("0..%d ",atoi(these.string)-1); 111             gettoken();        /*读取']'*/
112  } 113         gettoken();        /*读取']'以后的一个标记*/
114         printf("of "); 115  } 116     return; 117 } 118 
119 void deal_with_function_args(void) 120 { 121     while(these.type !=')') 122  { 123  gettoken(); 124  } 125  gettoken(); 126     printf("function returning "); 127     return; 128 } 129 
130 void deal_with_pointers(void) 131 { 132     while(stack[top].type == '*') 133  { 134         printf("%s ", pop.string); 135  } 136     return; 137 } 138 
139 void deal_with_declarator(void)        /*处理标识符以后可能存在的数组或函数*/
140 { 141     switch(these.type) 142  { 143     case '[' : deal_with_arrays();break; 144     case '(' : deal_with_function_args(); 145  } 146 
147  deal_with_pointers(); 148 
149     while(top >= 0)            /*处理在读入到标识符以前压入堆栈中的符号*/
150  { 151         if(stack[top].type == '(') 152  { 153  pop; 154  gettoken(); 155  deal_with_declarator(); 156  } 157         else
158  { 159             printf("%s ", pop.string); 160  } 161  } 162     return; 163 } 164 
165 int main(void) 166 { 167     read_to_first_identifier();        /*将标记压入堆栈中,直到碰见标识符*/
168  deal_with_declarator(); 169     printf("\n"); 170     return(0); 171 }
View Code

 

 

 

这本书感受往后还要再重读一次,可能感悟会更深一些。不过在一周时间内在这本书上搜刮了一些东西,也算是不枉一读了,幸甚幸甚。数据结构

相关文章
相关标签/搜索