免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: OwnWaterloo
打印 上一主题 下一主题

[C] 思考题:语言是工具?重要是思想?那如何表达思想?(修改版) [复制链接]

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
61 [报告]
发表于 2011-10-26 15:20 |只看该作者
回复 59# rover12421

将S这个状态保留下来了对么?
但那个算法要想"继续/延续", i,j也是状态的一部分 —— 这是人肉分析一不小心就会出错的部分。

  1. unsigned rc4(char const* key, size_t len)
  2. {
  3.       unsigned char S[256];
  4.       int i,j;

  5.       for (i=0; i<256; ++i) S[i] = i;
  6.       for (i=0, j=0; i<256; ++i)
  7.       {
  8.             unsigned k;
  9.             j = (j+key[i%len]+S[i]) % 256;
  10.             k = S[i]; S[i] = S[j]; S[j] = k;
  11.       }
  12.       i = j = 0;

  13.       for (;;)
  14.       {
  15.             unsigned k, byte;
  16.             i = (i+1) % 256;
  17.             j = (j+S[i]) % 256;
  18.             k = S[i]; S[i] = S[j]; S[j] = k;

  19.             byte = S[ (S[i]+S[j]) % 256 ];
  20.             return byte;
  21.       }
  22. }
复制代码
上面那段代码,与你给出的第一个版本中将iBuf长度固定为1时类似。
注意末尾的return, 函数/例程(subroutine) 返回后, 它的局部变量就会消失, 局部状态不会保留到下次进入该函数。
而协程(coroutine), 可以用 yield 而非 return 挂起, 并且可以从挂起点, 以挂起时的状态恢复执行
如果将上面代码中的 return 改为 yield, 第1次 yield 时就得到第1个byte, 后续的恢复执行会依次 yield 余下的 byte。
subroutine 是一种特殊的,不会使用yield 的 coroutine。

如果使用 coroutine 表达这个算法,大脑里想的就是算法本身。
而非人肉分析、剥离、保存subroutine中的状态与执行点 —— 不但编码复杂, 而且很容易分析错。


另外, 这种问题, 将两个不相关的循环分离, 是普遍存在的。
但在一些只支持subroutine的语言中,编程时会只能人肉实现类似coroutine的机制。

论坛徽章:
0
62 [报告]
发表于 2011-10-26 15:21 |只看该作者
本帖最后由 狗气球 于 2011-10-26 15:31 编辑

回复 48# mirnshi

    如果从体力活的角度讲,机器语言是世界的真实。
    我用小说做类比的目的是为了表达:编程不是体力活,它是创作。

    语言本身的特质也影响人,更不要说影响思想了。
    思想选择语言,语言也会选择持有不同思想方式的人。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
63 [报告]
发表于 2011-10-26 15:26 |只看该作者
编程不是体力活,它是创作
狗气球 发表于 2011-10-26 15:21


有这么想,但不敢这么说

论坛徽章:
0
64 [报告]
发表于 2011-10-26 15:28 |只看该作者
不是所有语言都能很好的传递思想。
自然语言中的例子,如汉语,那种细致入微的亲戚关系。 妯娌是什么? 要怎么翻译为英文?

而编程语言中rc4算法就是这样一个例子: 在一些编程语言中该算法/思想可以很直接的描述, 而在另一些编程语言里就不能。
rc4算法本身并不是重点。需要的资料我也列出了,也不长。 如果感兴趣就去看看吧。
OwnWaterloo 发表于 2011-10-26 13:41



马克。下班回去看看。

论坛徽章:
0
65 [报告]
发表于 2011-10-26 15:29 |只看该作者
这和语言是工具不冲突吧, 语言是工具不代表语言就不重要了,
语言是思维的载体, 同时思维的载体也可以是任何语言.

论坛徽章:
0
66 [报告]
发表于 2011-10-26 15:30 |只看该作者
本帖最后由 狗气球 于 2011-10-26 15:34 编辑
有这么想,但不敢这么说
OwnWaterloo 发表于 2011-10-26 15:26



    反正我只是二手的软件工程师兼二手的语言学票友,脸皮足够厚。{:3_189:}

    BTW 养的累有那么好么{:3_185:} >你签名档

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
67 [报告]
发表于 2011-10-26 15:33 |只看该作者
如果用Lua(或者python,scheme,C#以及所有支持coroutine的语言),就可以写出这样的实际代码


呵呵,看出来是归结到coroutine上了。既然Lua是用C写成的,C没有一种办法实现coroutine吗?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
68 [报告]
发表于 2011-10-26 15:50 |只看该作者
回复 67# mirnshi

自然必须有办法,还不止一种,实现。

C/C++都有不少coroutine的库。 在Windows上,有一套fiber的函数; 在posix上貌似有ucontext还是什么的。
但无论它们的代价再怎么低(fiber切换只有10来个指令), 还是不适合在循环里这么搞。


如果用纯C/C++, 可以这么搞:

  1. typedef struct
  2. {
  3.       unsigned i, j;
  4.       unsigned char s[256];
  5. } rc4_t;

  6. void rc4(rc4_t* self, char const* key, size_t len)
  7. {
  8.       unsigned char* S = self->s;

  9.       for (unsigned i=0; i<256; ++i)
  10.             S[i] = i;
  11.       for (unsigned i=0, j=0; i<256; ++i)
  12.       {
  13.             j = (j+key[i%len]+S[i]) % 256;
  14.             std::swap(S[i], S[j]);
  15.       }
  16.       self->i = self->j = 0;
  17. }

  18. unsigned rc4_next(rc4_t* self)
  19. {
  20.       unsigned* i = self->i;
  21.       unsigned* j = self->j;
  22.       unsigned char* S = self->s;
  23.       unsigend k;

  24.       *i = (*i+1) % 256;
  25.       *j = (*j+S[*i]) % 256;
  26.       k = S[*i]; S[*i] = S[*j]; S[*j] = k;

  27.       return S[ (S[*i]+S[*j]) % 256 ];
  28. }
复制代码
客户代码就可以:
rc4_t g;
rc4(&g, key, len);
for ( ... ) {
// 这里由用户决定要加密什么
// 当需要一个加密流字节时
unsigned byte = rc4_next(&g);
}


但这其实就是在人肉实现coroutine, 然后再表达rc4算法。
就像是用亲戚关系的具体定义(父亲的亲兄弟的儿子), 而非直接用一个词(堂兄)表达。

人肉实现时需要保存哪些局部状态、 哪些是挂起点(这个例子中挂起点很简单,因为最后是一个无限循环) —— 这种分析很容易出错。
以前与starwing83讨论过是否可以将这种人肉翻译自动化一些, 不过他貌似没什么兴趣, 我也很懒……  就此作罢了……

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
69 [报告]
发表于 2011-10-26 17:00 |只看该作者
本帖最后由 OwnWaterloo 于 2011-10-26 17:03 编辑

回复 66# 狗气球

养的累……  噗……  这不是养的累,而是不敢养啊……

其实吧,无论什么属性,只要发挥到了极致,总归会让人好奇吧?
那动画出来了么自然是会看看啦,而且动画还很不错的说……

BTW,如果萌ヤンデレ,或者反感后宫、N线齐开什么的, 推荐《我和妹妹和青梅竹马和同级生和前辈和后辈在那风华正茂之时》……
绝对比coroutine神马的更给力

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
70 [报告]
发表于 2011-10-26 17:08 |只看该作者
咳咳,最近去了三亚…………

我觉得吧,OW这个问题就不公平。为什么这些功能需要“函数”实现?为什么这些函数需求如此明确,只差问号所在地了?这样明显是在偏袒某种设计,换言之,你的语言已经将思想引入了死胡同。关键在于你想做什么,而不是你需要什么函数。函数是实现功能的部件,然而要实现功能并不仅仅只有你提出的这种构架。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP