📄 ch01s01.html
字号:
<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>1. 简单的CPS例子</title><link rel="stylesheet" href="html.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.69.1"><link rel="start" href="index.html" title="Java网络程序员看Continuation"><link rel="up" href="ch01.html" title="Chapter 1. CPS与网络程序流程控制"><link rel="prev" href="ch01.html" title="Chapter 1. CPS与网络程序流程控制"><link rel="next" href="ch01s02.html" title="2. CPS猜数字游戏"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">1. 简单的CPS例子</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch01.html">Prev</a> </td><th width="60%" align="center">Chapter 1. CPS与网络程序流程控制</th><td width="20%" align="right"> <a accesskey="n" href="ch01s02.html">Next</a></td></tr></table><hr></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e46"></a>1. 简单的CPS例子</h2></div></div></div><p>我们首先来看一个例子。您能看出下面的两个C程序是等价的吗?</p><pre class="programlisting">/* normal style 一般风格 */#include <stdio.h>int add(int i, int j) { return i + j;}void main() { int i = add(3, 5); printf("%d\n", i);}/*************************************//* continuation-passing style (CPS) */#include <stdio.h>int add(int i, int j, void *continuation(int)) { int k = i + j; continuation(k);}void print(int i) { printf("%d\n", i);}void main() { add(3, 5, print);}</pre><p>第一个C程序是用我们都熟悉的结构写的,它进行两步操作,首先add,然后printf。如果运行这个程序,我们就会得到答案8。第二个程序就有些奇怪了。它也进行两步操作,add和print。不过在main里,我们只调用add,同时我们把print作为一个参数传递给add。在add函数里,我们首先进行加法运算,不过add不会返回,而是直接调用自己的第三个参数。当然,我们进行的运算是一样的,最后的结果也是一样的 。</p><p>第二个程序就是用所谓的continuation passing style (CPS)写的。在CPS中,函数不会返回,所有剩下的操作被当作参数一步一步传下去。下面我们看一个进行三步操作的例子:</p><pre class="programlisting">#include <stdio.h>#include <stdlib.h>void step1();void step2();void step3();void add(int a, int b, void (*continuation)(int)) { int c = a + b; continuation(c);}void multiply(int a, int b, void (*continuation)(int)) { int c = a * b; continuation(c);}void print(int a, void (*continuation)(void)) { printf("%d\n", a); continuation();}void nothing() {}void step1(int a) { add(a, 2, step2);}void step2(int b) { multiply(b, 3, step3);}void step3(int c) { print(c, nothing);}void main() { step1(5);}</pre><p>前面的几个函数,add,multiply,print,是典型的CPS函数。注意到add和multiply所接受的continuation的声明是void (*continuation)(int)而print所接受的continuation的声明是void (*continuation)(void)。想想这是为什么?后面的几个函数,step1,step2,step3和nothing,则定义了程序的一个接一个步骤;每个step把下一个step作为continuation传下去。最后,在main()里,我们只需要调用step1就行了。</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch01.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch01.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch01s02.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 1. CPS与网络程序流程控制 </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 2. CPS猜数字游戏</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -