目录

  • 1 Chapter 1 Introduction
    • 1.1 1.0 Course Contents
    • 1.2 1.1 Basic Conception
      • 1.2.1 Lecture 1
      • 1.2.2 Lecture 2
    • 1.3 1.2 Compiler Structure
      • 1.3.1 Lecture 1
      • 1.3.2 Lecture 2
      • 1.3.3 Lecture 3
    • 1.4 1.3 The Technique of Compiler Developing
  • 2 Chapter 2 Conspectus of Formal Language
    • 2.1 2.1 Alphabets and Strings
      • 2.1.1 Lecture 1
      • 2.1.2 Lecture 2
    • 2.2 2.2 Grammars and its Categories
      • 2.2.1 Lecture 1
      • 2.2.2 Lecture 2
    • 2.3 2.3 Languages and Parse Tree
      • 2.3.1 Lecture 1
      • 2.3.2 Lecture 2
    • 2.4 2.4 Notes of Formal Language
    • 2.5 2.5 Basic Parsing Techniques
      • 2.5.1 Lecture 1
      • 2.5.2 Lecture 2
  • 3 Chapter 3 Finite Automata
    • 3.1 3.1 Formal Definition of FA
      • 3.1.1 Lecture 1
      • 3.1.2 Lecture 2
    • 3.2 3.2 Transition from NDFA to DFA
      • 3.2.1 Lecture 1
      • 3.2.2 Lecture 2
      • 3.2.3 Lecture 3
    • 3.3 3.3 RG and FA
    • 3.4 3.4 Regular Expression & Regular Set
      • 3.4.1 Lecture 1
      • 3.4.2 Lecture 2
  • 4 Chapter 4 Scanner(Lexical Analyzer)
    • 4.1 4.1 Lexical Analyzer and Tokens
      • 4.1.1 Lecture 1
      • 4.1.2 Lecture 2
    • 4.2 4.2 Step for developing a lexical analyzer
    • 4.3 4.3  Dealing with Identifier
    • 4.4 4.4  Using Regular Expressions
    • 4.5 4.5 Using Flex
      • 4.5.1 Lecture 1
      • 4.5.2 Lecture 2
  • 5 Chapter 5 Top-Down Parsing
    • 5.1 5.0 Push Down Automata (PDA, Added)
      • 5.1.1 Lecture 1
      • 5.1.2 Lecture 2
      • 5.1.3 Lecture 3
    • 5.2 5.1 Elimination Left-Recursion
    • 5.3 5.2 LL(k) Grammar
      • 5.3.1 Lecture 1
      • 5.3.2 Lecture 2
    • 5.4 5.3 Deterministic LL(1) Analyzer Construction
    • 5.5 5.4 Recursive-descent (Non-backtracking) parsing
    • 5.6 5.5 复习与结课
      • 5.6.1 Lecture1 结课感言
      • 5.6.2 Lecture 2 关于复习
      • 5.6.3 Lecture 3 习题讲解
  • 6 Chapter 6 bottom-up Parsing and precedence analyzer
    • 6.1 6.1 Bottom-Up Parsing
    • 6.2 6.2 Phrase, Simple Phrase and Handle
    • 6.3 6.3 A Shift-Reduce Parser
    • 6.4 6.4 Some Relations on Grammar
    • 6.5 6.5 Simple Precedence Parsing
    • 6.6 6.6 Operator-Precedence Parsing
      • 6.6.1 Lecture 1
      • 6.6.2 Lecture 2
      • 6.6.3 Lecture 3
    • 6.7 6.7 Precedence Functions and Construction
  • 7 Chapter 7  LR Parsing
    • 7.1 7.1 LR Parsers
      • 7.1.1 Lecture 1
      • 7.1.2 Lecture 2
    • 7.2 7.2 Building a LR(0) parse table
      • 7.2.1 Lecture 1
      • 7.2.2 Lecture 2
    • 7.3 7.3 SLR Parse Table Construction
    • 7.4 7.4 Constructing Canonical LR(1) Parsing Tables
    • 7.5 7.5 LALR Parsing Tables Construction
    • 7.6 7.6 Using Ambiguous Grammars
    • 7.7 7.7 Yacc/Bison Overview
  • 8 Chapter 8 Syntax-Directed Translation
    • 8.1 8.1 Syntax-Directed Translation
      • 8.1.1 Lecture1
      • 8.1.2 Lecture 2
      • 8.1.3 Lecture 3
    • 8.2 8.2 Abstract Syntax Tree
    • 8.3 8.3 Intermediate Representation
      • 8.3.1 Lecture 1
      • 8.3.2 Lecture 2
  • 9 Chapter 9 Run-Time Environment
    • 9.1 9.1 Data Area & Attribute
    • 9.2 Section 9.2~9.4 & Section 9.8~9.9
    • 9.3 9.5 Parameter Passing
    • 9.4 9.6 Stack Allocation
    • 9.5 9.7 Heap allocation
  • 10 Chapter 10 Symbol Tables
    • 10.1 10.1 A symbol Table Class
    • 10.2 10.2 Basic Implementation Techniques
    • 10.3 10.3 Block-structured Symbol Table
    • 10.4 10.4 Implicit Declaration
    • 10.5 10.5 Overloading
  • 11 Chapter 11 Code Optimization
    • 11.1 11.1 Control Flow Graph
    • 11.2 11.2 Redundancies
    • 11.3 11.3 Loop Optimizations
    • 11.4 11.4 Instruction Dispatch
      • 11.4.1 Lecture 1
      • 11.4.2 Lecture 2
  • 12 Chapter 12 Code Generation
    • 12.1 12.1 Code generation issues
    • 12.2 12.2 Simple Stack Machine
    • 12.3 12.3 Register Machine
    • 12.4 12.4 A Simple Code Generator
  • 13 13 Extended Reading扩展阅读1 斯坦福大学公开课
    • 13.1 Lecture 1
    • 13.2 Lecture 2
    • 13.3 Lecture 3
    • 13.4 Lecture 4
    • 13.5 Lecture 5
    • 13.6 Lecture 6
    • 13.7 Lecture 7
    • 13.8 Lecture 8
    • 13.9 Lecture 9
    • 13.10 Lecture 10
    • 13.11 Lecture 11
    • 13.12 More sources
  • 14 14 Extended Reading 2 扩展阅读2 illinois.edu lectures
    • 14.1 Lecture 1 Overview
    • 14.2 Lecture 2 Strings, Languages, DFAs
    • 14.3 Lecture 3 More on DFAs
    • 14.4 Lecture 4 Regular Expressions and Product Construction
    • 14.5 Lecture 5 Nondeterministic Automata
    • 14.6 Lecture 6 Closure properties
    • 14.7 Lecture 7 NFAs are equivalent to DFAs
    • 14.8 Lecture 8 From DFAs/NFAs to Regular Expressions
    • 14.9 Lecture 9 Proving non-regularity
    • 14.10 Lecture 10 DFA minimization
    • 14.11 Lecture 11 Context-free grammars
    • 14.12 Lecture 12 Cleaning up CFGs and Chomsky Normal form
    • 14.13 Lecture 13 Even More on Context-Free Grammars
    • 14.14 Lecture 14 Repetition in context free languages
    • 14.15 Lecture 15 CYK Parsing Algorithm
    • 14.16 Lecture 16 Recursive automatas
    • 14.17 Lecture 17 Computability and Turing Machines
    • 14.18 Lecture 18 More on Turing Machines
    • 14.19 Lecture 19 Encoding problems and decidability
    • 14.20 Lecture 20 More decidable problems, and simulating TM and “real” computers
    • 14.21 Lecture 21 Undecidability, halting and diagonalization
    • 14.22 Lecture 22 Reductions
    • 14.23 Lecture 23 Rice Theorem and Turing machine behavior properties
    • 14.24 Lecture 24 Dovetailing and non-deterministic Turing machines
    • 14.25 Lecture 25 Linear Bounded Automata and Undecidability for CFGs
  • 15 15 Extended Reading3 扩展阅读3 Extended  Reference Books
    • 15.1 15.1 English Text Book
    • 15.2 15.2 编译原理(何炎祥,伍春香,王汉飞 2010.04)
    • 15.3 15.3 编译原理(陈光建主编;贾金玲,黎远松,罗玉梅,万新副主编 2013.10)
    • 15.4 15.4 编译原理((美)Alfred V. Aho等著;李建中,姜守旭译 2003.08)
    • 15.5 15.5 编译原理学习与实践指导(金登男主编 2013.11)
    • 15.6 15.6 编译原理及编译程序构造 第2版(薛联凤,秦振松编著 2013.02)
    • 15.7 15.7 编译原理学习指导(莫礼平编 2012.01)
    • 15.8 15.8 JavaScript动态网页开发案例教程
  • 16 16 中文版课件(pdf)辅助学习
    • 16.1 第1章 引论
    • 16.2 第2章 形式语言概论
    • 16.3 第3章 有穷自动机
    • 16.4 第4章 词法分析
    • 16.5 第5章 自上而下分析
    • 16.6 第6章 优先分析方法
    • 16.7 第7章 自下而上的LR(k)分析方法
    • 16.8 第8章 语法制导翻译法
    • 16.9 第9章 运行时的存储组织与管理
    • 16.10 第10章 符号表的组织与查找
    • 16.11 第11章 优化
    • 16.12 第12章 代码生成
  • 17 17 Extended Reading4 扩展阅读4 Static Single Assignment
    • 17.1 17.1 SSA-based Compiler Design
    • 17.2 17.2 A Simple, Fast Dominance Algorithm (Rice Computer Science TR-06-33870)
    • 17.3 17.3 The Development of Static Single Assignment Form(KennethZadeck-Presentation on the History of SSA at the SSA'09 Seminar, Autrans, France, April 2009)
    • 17.4 17.4 SPIR-V Specification(John Kessenich, Google and Boaz Ouriel, Intel Version 1.00, Revision 12 January 16, 2018)
    • 17.5 17.5 Efficiently Computing Static Single Assignment Form and the Control Dependence Graph
    • 17.6 17.6 Global Value Numbers and Redundant Computations
  • 18 18 Extended Reading4 扩展阅读5 Computer Science
    • 18.1 1 实地址模式和保护模式的理解
    • 18.2 2 实模式和保护模式
    • 18.3 3 实模式和保护模式区别及寻址方式
    • 18.4 计算机专业术语
    • 18.5 Bit Math in c Language
    • 18.6 Auto-generating subtitles for any video file
    • 18.7 Autosub
    • 18.8 C语言中的内联函数(inline)与宏定义(#define)
  • 19 19 相关学习
    • 19.1 龙书、鲸书和虎书
    • 19.2 Complexity
    • 19.3 MPC Complexity
    • 19.4 NP-completeness
    • 19.5 Computational complexity theory
  • 20 20 全球战疫-武汉战疫延伸与扩展
    • 20.1 Extraordinary G20 Leaders’ Summit Statement on COVID-19
    • 20.2 Experts urge proactive measures to fight virus
    • 20.3 covid-19病毒下贫穷国家
    • 20.4 正确理解病亡率、压平曲线、疫情高峰术语
    • 20.5 为什么全球经济可能陷入长期衰退
    • 20.6 为何新冠病毒检测会出现“假阴性”
    • 20.7 在纽约,几乎每个人身边都有人感染病毒
    • 20.8 An Address by Her Majesty The Queen
    • 20.9 Boris Johnson admitted to hospital over virus sympto
    • 20.10 Edinburgh festivals cancelled due to coronavirus
    • 20.11 US set to recommend wearing of masks
    • 20.12 Boris Johnson in self-isolation after catching coronavirus
    • 20.13 Covid-19:The porous borders where the virus cannot be controlled
    • 20.14 当欧洲人开始戴上口罩
    • 20.15 Lockdown and ‘Intimate Terrorism’
    • 20.16 Us Election 2020: Bernie Sanders Suspends Presidential Campaign
    • 20.17 The aircraft carrier being infected with the coronavirus
    • 20.18 Spent to the W.H.O.
    • 20.19 Unemployment
    • 20.20 The beat of a heart the glimmer of a soul
    • 20.21 Coronavirus pandemic: EU agrees €500bn rescue package
    • 20.22 the world after coronavirus冠状病毒之后的世界
  • 21 21 课程思政方案
    • 21.1 21.1 课程思政
    • 21.2 21.2 实施方案
C语言中的内联函数(inline)与宏定义(#define)

C语言中的内联函数(inline)与宏定义(#define)详细解析

From: https://www.jb51.net/article/41520.htm

先简明扼要,说下关键:
1、
内联函数在可读性方面与函数是相同的,而在编译时是将函数直接嵌入调用程序的主体,省去了调用/返回指令,这样在运行时速度更快。

2、内联函数可以调试,而宏定义是不可以调试的。
内联函数与宏本质上是两个不同的概念如果程序编写者对于既要求快速,又要求可读的情况下,则应该将函数冠以inline。下面详细介绍一下探讨一下内联函数与宏定义。

一、内联函数是什么?
内联函数是代码被插入到调用者代码处的函数。如同 #define 宏(但并不等同,原因见下文),内联函数通过避免被调用的开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。

二、 内联函数是如何在安全和速度上取得折衷?
在 C 中,你可以通过在结构中设置一个 void* 来得到“封装的结构”,在这种情况下,指向实际数据的 void* 指针对于结构的用户来说是未知的。因此结构的用户不知道如何解释void*指针所指内容,但是存取函数可以将 void* 转换成适当的隐含类型。这样给出了封装的一种形式。

不幸的是这样做丧失了类型安全,并且也将繁琐的对结构中的每个域的访问强加于函数调用。(如果你允许直接存取结构的域,那么对任何能直接存取的人来说,了解如何解释 void* 指针所指内容就是必要的了;这样将使改变底层数据结构变的困难)。

虽然函数调用开销是很小的,但它会被累积。C++类允许函数调用以内联展开。这样让你在得到封装的安全性时,同时得到直接存取的速度。此外,内联函数的参数类型由编译器检查,这是对 C 的 #define 宏的一个改进。
 
三、为什么我应该用内联函数?而不是原来清晰的 #define 宏? 
因为#define宏定义函数是在四处是有害的:
和 #define 宏不同的是,内联函数总是对参数只精确地进行一次求值,从而避免了那声名狼藉的宏错误。换句话说,调用内联函数和调用正规函数是等价的,差别仅仅是更快:


代码如下:


// 返回 i 的绝对值的宏
#define unsafe(i) \
         ( (i) >= 0 ? (i) : -(i) )

// 返回 i 的绝对值的内联函数
inline
int safe(int i)
{
   return i >= 0 ? i : -i;
}

int f();

void userCode(int x)
{
   int ans;

   ans = unsafe(x++);   // 错误!x 被增加两次
   ans = unsafe(f());   // 危险!f()被调用两次

   ans = safe(x++);     // 正确! x 被增加一次
   ans = safe(f());     // 正确! f() 被调用一次
}

和宏不同的,还有内联函数的参数类型被检查,并且被正确地进行必要的转换。宏定义复杂函数是有害的;非万不得已不要用。


四、如何告诉编译器使非成员函数成为内联函数?

声明内联函数看上去和普通函数非常相似:
void f(int i, char c);
当你定义一个内联函数时,在函数定义前加上 inline 关键字,并且将定义放入头文件:inlinevoid f(int i, char c){   // ...}
注意:将函数的定义({...}之间的部分)放在头文件中是强制的,除非该函数仅仅被单个 .cpp 文件使用。尤其是,如果你将内联函数的定义放在 .cpp 文件中并且在其他 .cpp文件中调用它,连接器将给出 “unresolved external” 错误。

五、如何告诉编译器使一个成员函数成为内联函数?
声明内联成员函数看上去和普通函数非常类似:
class Fred {public:  
void f(int i, char c);};
但是当你定义内联成员函数时,在成员函数定义前加上 inline 关键字,并且将定义放入头文件中:inline void Fred::f(int i, char c){   // ...}通常将函数的定义({...}之间的部分)放在头文件中是强制的。如果你将内联函数的定义放在 .cpp 文件中并且在其他 .cpp 文件中调用它,连接器将给出“unresolved external”错误。

六、 有其它方法告诉编译器使成员函数成为内联吗?
有:在类体内定义成员函数:class Fred {public:   void f(int i, char c)     {       // ...     }};尽管这对于写类的人来说很容易,但由于它将类是“什么”(what)和类“如何”(how)工作混在一起.小结总之,在嵌入式C(或C++)编程里面,懂得使用内联函数(inline)与宏定义(#define),并使用好它们,对我们是大有裨益的。(注:本文部分内容来源于网络整理,上述探讨属于个人意见,仅供参考。错误之处也是难免!)