ARTS - No.3
A
Coroutines
Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing execution to be suspended and resumed. Coroutines are well-suited for implementing familiar program components such as cooperative tasks, exceptions, event loops, iterators, infinite lists and pipes. --wikipedia
直观地说,就是在2个函数执行期间来回跳转,类似中断,但是与中断不同的是,这个跳转是程序员可控的。
在Python
中,协程语法使用yield
实现,函数执行到yield
处就会返回,执行完别的函数后,再回到yield
下面继续执行。
Coroutines in C
众所周知,C语言是没有yield
关键字的,如果用return
就无法在断点处继续执行。那么,如何用C语言实现协程?
哈哈,早有前人铺好了康庄大道。作者 Simon Tatham ,如果不知道这个名字的话,总知道 PuTTY 吧 😃
开门见山(不是偷懒)
int function(void) {
static int i, state = 0;
switch (state) {
case 0: goto LABEL0;
case 1: goto LABEL1;
}
LABEL0: /* start of function */
for (i = 0; i < 10; i++) {
state = 1; /* so we will come back to LABEL1 */
return i;
LABEL1:; /* resume control straight after the return */
}
}
哦,当然,这只是一个基本的功能实现,代码并不优雅,首先要干掉goto
。在C语言中,有个关于switch
的技巧,就是case
的位置是可以放到子代码块里去的!
int function(void) {
static int i, state = 0;
switch (state) {
case 0: /* start of function */
for (i = 0; i < 10; i++) {
state = 1; /* so we will come back to "case 1" */
return i;
case 1:; /* resume control straight after the return */
}
}
}
这看起来清爽多了,可是case
仍然需要手动维护,作者用__LINE__
宏给出了更简洁的实现,这也是最终版本了。
#define crBegin static int state=0; switch(state) { case 0:
#define crReturn(x) do { state=__LINE__; return x; \
case __LINE__:; } while (0)
#define crFinish }
int function(void) {
static int i;
crBegin;
for (i = 0; i < 10; i++)
crReturn(1, i);
crFinish;
}
但是需要注意的是,宏定义就是switch
语法块,所以不能在协程里面再使用switch
了。
此外,如果在 VC++ 6 里面应用这个方法,需要关闭 "Program Database for Edit and Continue" 选项。
Note that Visual C++ version 6 doesn't like this coroutine trick, because its default debug state (Program Database for Edit and Continue) does something strange to the
__LINE__
macro. To compile a coroutine-using program with VC++ 6, you must turn off Edit and Continue. (In the project settings, go to the "C/C++" tab, category "General", setting "Debug info". Select any option other than "Program Database for Edit and Continue".)
我这里给出的内容只是原文的冰山一角,原文关于为什么要使用协程,以及这种写法在语言设计的规范和易读上的tradeoff也是非常值得深思的,建议详阅原文。
Any coding standard which insists on syntactic clarity at the expense of algorithmic clarity should be rewritten. If your employer fires you for using this trick, tell them that repeatedly as the security staff drag you out of the building.
R
What every computer science major should know
无法访问的用户可以参考 https://www.cnblogs.com/roostinghawk/p/11396531.html
Ctrl + Shift + I
然后选择Console
标签,键入$x('//h2/text()').forEach(function(e) {console.log(e);})
就可以看到所有小标题,我把它们列在这里。
- Portfolio versus resume
- Technical communication
- An engineering core
- The Unix philosophy
- Systems administration
- Programming languages
- Discrete mathematics
- Data structures and algorithms
- Theory
- Architecture
- Operating systems
- Networking
- Security
- Cryptography
- Software testing
- User experience design
- Visualization
- Parallelism
- Software engineering
- Formal methods
- Graphics and simulation
- Robotics
- Artificial intelligence
- Machine learning
- Databases
- Non-specific reading recommendations
- What else?
- Related posts
不算后三个的话,共列出了25项!学完这些才达到了 Matt Might 推荐的标准:A computer science major. : )
下面是我发现的一些有趣的地方:
-
portfolio 哈哈,学到了新单词……
-
Computer scientists should understand a computer from the transistors up. : )
-
Any of the Art of Computer Programming series by Knuth. -- 这就让我想起来云风的一句话:“在将来,把克努特的《计算机程序设计艺术》三卷本读完,可能只是作为程序员的基本素质!” -- 摘自环境驱动编程 (其实《计算机程序设计艺术》有4卷……)
-
There's a misconception, even among professors, that user experience is a "soft" skill that can't be taught. 被忽略的点啊……
-
...
T
位操作实现字符大小写转换
大写变小写、小写变大写 : ASCII码 ^= 32
大写变小写、小写变小写 : ASCII码 |= 32
小写变大写、大写变大写 : ASCII码 &= -33
Python 3.7.1rc2 (default, Jun 14 2019, 23:23:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> chr(ord('a')^32)
'A'
>>> chr(ord('A')^32)
'a'
>>> chr(ord('a')|32)
'a'
>>> chr(ord('A')|32)
'a'
>>> chr(ord('a')&-33)
'A'
>>> chr(ord('A')&-33)
'A'
S
就说说这次的 What every computer science major should know 吧。每次看完类似的文章,心中就会一阵失落,失落我浪费了大好的青春年华……我上学的时候干了些什么呢?我从上大学之前就开始编程,把它视作一种娱乐手段,打发掉了大部分无聊的时光。在那个朴实无华的岁月,哪晓得什么编程范式和设计模式,实现功能就是快乐源泉了。
时过境迁,我也没有跟大佬交流,一直自己瞎害,所以视野非常有限,在相当长的一段时间里都没有提高。也就是到了快毕业的几年吧,某些偶然的机会,开始看看别的语言,也看看别人是怎么学习和编程的。视野打开了,也就了解到了程序设计的复杂多变。然而,老话说得好,上帝为你关上一扇门的时候,还顺手把窗户也关上了……我了解到的知识不过是冰山一角上面挥发出来的水分子的一个夸克……
任重道远。
由此,我反思,在大学里究竟应该怎么学习呢?应该花时间去啃基础知识呢,还是多留意各种上层应用呢?引用张泽鹏的一句话: 踏踏实实从基础学起,四年时间不够了解冰山一角;讲究实用直接建造空中楼阁,又会缺乏理论基础,很难有突破。-- 环境驱动编程
想一想,试一试,最后的结论是:弃疗。哈哈,根本就不可能在4年里把编程学好嘛,这不符合客观发展规律。之前也分享过一篇文章: Teach Yourself Programming in Ten Years ,还是很深刻的。所以编程的学习就得慢慢来,做好打持久战的准备,然后好好睡一觉吧,在梦里记住下面几个要领:
- 多与大佬交流,聊什么都好,总会有收获;
- 多关注基础知识,好好练内功,方能一通百通;
- 重视编程范式和设计模式,都是上乘武学;
- 忌心浮气躁;
- 悉心保养头发。
推荐阅读:“21天教你学会C++”
(学C++第21天的时候要小心了!)