技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 编程语言
    熟悉C的人都知道,C语言支持可变参数函数(Variable Argument Functions),即参数的个数可以是不定个,在函数定义的时候用(...)表示,比如我们常用的printf()\\execl函数等;printf函数的原型如下: int printf(const char *format, ...); 注意,采用这种形式定义的可变参数函数,至少需要一个普通的形参,比如上面代码中的*format,后面的省略号是函数原型的一部分。 C语言之所以可以支持可变参数函数,一个重要的原因是C调用规范中规定C语言函数调用时,参数是从右向左压入栈的;这样一个函数实现的时候,就无需关心调用他的函数会传递几个参数过来,而只要关心自己用到几个;以printf为例: printf("%d%s\n",i,s); printf函数在定义的时候,不知道函数调用的时候会传递几个参数。
    很久以前,我接触的最初几本C语言书中,我记得有类似这么一句话“C语言是一种弱类型的语言,类型之间可以进行隐式的转换;而C++是强类型的语言,需要进行强制类型转换”。我忘了是哪本书,但这句话我一直记得。因为实际写代码中一直也没有触碰隐式的转换(我一般都会强制转换),所以也没有深究过这个问题。然而最近的一段代码却给我带来了一些困惑。
    最近感冒,昨天流着鼻涕去一直很想去的某M面试,居然还迟到了,一紧张,鼻涕不流了- -# 问的问题不难,都是基础,可是自己不争气,答的不怎么样,一直自诩C语言用的很不错,可是还是在基础上被鄙视- -!都是那些个关键字们阿~今天,让我挨个把C的关键字给详细的整一整,加深一下印象~ 首先,C语言中到底有多少个关键字呢?木有错,ANSI C规定是32个! 他们分别是:auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if while static。 别看那一堆了字母了,直接看下面的分类接受.......
    “undefined reference to XXX”是一类挺常见的链接错误,原因通常是链接时找不到声明成extern类型的函数的定义点。不过这次遇到的undefined reference中的XXX函数明明在一个库中定义,而且该库明明已经在命令行用-l指定了,ld -verbose也显示能找到该库文件。
    过去的一年我在微软亚洲研究院做输入法,我们的产品叫“英库拼音输入法” (下载Beta版),如果你用过“英库词典”(现已更名为必应词典),应该知道“英库”这个名字(实际上我们的核心开发团队也有很大一部分来源于英库团队的老成员)。整个项目是微软亚洲研究院的自然语言处理组、互联网搜索与挖掘组和我们创新工程中心,以及微软中国Office商务软件部(MODC)多组合作的结果。至于我们的输入法有哪些创新的feature,以及这些feature背后的种种有趣故事… 本文暂不讨论。虽然整个过程中我也参与了很多feature的设想和设计,但90%的职责还是开发,所以作为client端的核心开发人员之一,我想跟大家分享这一年来在项目中全面使用C++11以及现代C++风格(Elements of Modern C++ Style)来做开发的种种经验。
    在普林斯顿大学和伯克利的加州大学,两位研究人员试图在为什么有些编程语言能走进它们的黄金时代而众多余下的却不能的原因上贡献出自己的智慧。在一个他们自称为“业余研究”里,Leo Meyerovich 和 Ari Rabkin 调查了数万个程序员,梳理了流行的代码库SourceForge上超过30万个项目——所有的这些努力都是为了能清楚为什么老的编程语言仍然处于霸权地位。
    相对于Java的假泛型(编译型泛型,类型擦除)来说,真泛型是.NET的一个亮点。Anders Heisenberg多次提到.NET的真泛型有利于编程语言的进一步发展,可以带来更丰富的编程模型。不过.NET支持的泛型是一方面,具体到语言本身则又涉及到编译器的实现,而编译器的实现又收到运行时的限制等等,所以要谈语言的设计缺陷的“原因”就会变得很复杂。不过这里我们就把C#作为一个“成品”来对待,谈下它不允许以void作为泛型参数的“后果”,“原因”则略为一提,不做深究。 泛型的限制 话说C#中泛型是很常用的特性,很多朋友都应该遇到过一些这方面令您不爽的地方。
    其实使用C#这么多年,我时不时会遇到一些令人不爽的设计缺陷。这些缺陷大都是些限制,虽说无伤大雅,也很容易避免,但一旦遇到这些情况,总会令人心生不快,毕竟都是些无谓的限制。而且令人遗憾的是,虽说去除这些限制也不会带来什么问题,但我认为C#设计团队也基本不会去修复这些问题了,毕竟它们大都是些细枝末节。作为一名用C#的纯种码农,我突然一时兴起也要把这些设计缺陷记录下,也方便和大伙一起讨论下。那么这次就先从实现接口内的事件说起,当我们需要显式实现一个接口内的事件时,会发现我们必须提供add和remove访问器,这还会稍许影响到事件常用的使用模式。 强制add和remove访问器 这个问题听上去有些绕,不过看代码便一清二楚。
    任何异步编程的类库要做的第一件事往往便是统一异步编程的模型,例如Jscex的异步模块自带一个类似于.NET中的异步任务模型。围绕统一的模型,开发人员便可以尽情地提供各种扩展,例如Jscex异步增强模块中的whenAll或whenAny一样。换句话说,假如要混用两种异步编程模型,往往需要将其中一种适配至另外一种,因此异步增强模块中也提供了fromCallback及fromStandard辅助,能够轻易地将最简单的(也是Node.js里使用的)两种异步函数接口绑定为异步任务。
    昨晚跟一位Node.js专家讲解了我的Wind.js类库。之前那位仁兄对Jscex(Wind.js的前身)的看法是“就是不喜欢”,也在微博上对Jscex冷嘲热讽,于是我私信他说建议看一下文档了解一下Jscex。昨天我们的争论主要围绕在eval的使用上,他认为更好的做法是像CoffeeScript那样使用一个额外的进程监听改变,这样更方便。我说CoffeeScript这么做是因为它没有像Wind.js那样借助eval实现完全动态的运行时转化,且生产环境中不会出现eval。最后他坚持认为“eval就是有性能问题”,因此开发时也不应该使用,否则Wind.js为什么要提供预编译器?虽然最后不欢而散,不过我忽然也打算验证一下eval生成的代码效率到底会差到什么样的地步,于是便有了这次试验。 测试代码 有人可能会问,eval每次动态的执行代码时需要重新分析代码,还不能进行优化,为什么会“不慢”?
    我很喜欢编程语言,但我争论语言时有着基本的原则和必备的知识,没有这些在我看来就不应该参与讨论。讨论时我也会严格控制范围,因此我基本不会使用类比,因为类比其实就是在用外部知识来理解当前的话题,很容易把话题扯开出去。同理,我也不会像高级分析师们讲一些初级程序员们都懂——但往往我不怎么理解或赞同的大道理。我就是怎么没出息,就像今天早上还有人在IM上对我说“老赵怎么可能还在写程序,你是冒牌的吧?”。
    高级语言有一个问题,就是它只能在一个非常有限的小环境使用。它的目的是为了效率和准确。如果对于大众沟通,我们就必须重新回到最通用的语言上来。乔布斯在公共演讲的时候尽量用短句,用小学生都能听懂的词,是为了沟通。再准确的词,一旦受众脑子里面没有定义,还不如用最简单的每人都有的模块。当然低级语言不代表着通用,C就比汇编通用,look就比定义look的另外一个词gaze更加通用。
    脚本语言ymd ymd全称yamada script,是某一淘数据部员工业余时间完成的一个玩具脚本语言,其语法类似lua和javascript。代码托管在github 目前只支持Linux x86_64,预计未来会支持Windows/Mac OS。 yamada名称由来是动画《Working!!》角色:山田 葵(Yamada Aoi)
    最近, 我提交的关于finally的RFC:Supports finally keyword已经提交到了PHP主干, 今天就给大家介绍一下这个新特性的背景, 和使用方法. 关于这个特性的需求, 最早是在2005年提出来的: FR #32100, 但一直没有人去实现它. 对于现在的PHP来说, 如果我们需要在发生我们当前不能处理的异常的时候, 做一些工作, 那么就会写下类似于这样代码...
    我们已经有好几个程序员都把Go语言描述为是一种所见即所得(WYSIWYG)的编程语言。这是说,代码要做的事和它在字面上表达的意思是完全一致的。
    最近, 我在 review 组员的 Python 代码时, 发现了一个递归调用, 我立即发现了其中的问题. 先说一下编程中递归. 只有会用递归, 并且能随心应手地写出递归程序的程序员, 才是已经入门了的程序员. 不过, 许多程序员并没有发现编程中的递归的一个限制: recursion depth limit, 逻辑上的递归可以无次数限制, 但语言执行器或者程序堆栈会限制递归的次数.
    一加一等于几, 这是个问题某些所谓的动态语言是名不副实的 – 我称之为伪动态语言. 这些伪动态语言之所以是伪的, 是因为它们只是在代码层面的变量是动态的, 而它们的类型系统并不是真正动态的, 一个简单的例子, 考虑字符串能否直接和整数进行拼接成为一个新的字符串. 当然, 语言维护者用另一个名词”类型强度(type strength)”来表示这种行为, 然后把这种本质上不动态的行为称为”强类型(strong typing)”, 把真正的动态称为”弱类型(weak typing)”, 这样, 它们就可以心安理得地继续辨称自己所喜欢的语言是动态语言. 但我认为, “动态语言”的概念应该重新定义, “动态”应该脱离字面的意义, 去探究真正本质的动态.
     其实所谓编码问题,不外乎若干概念,弄明白了这些概念,编码问题就可以迎刃而解了,所以这里按照概念来展开讲解。 字符和字符集 字符,就是我们日常使用的各种文字,比如中文的你、我、他,英文的A、B、C,日文的に、ほ、ん、ご,都是字符。手写可以用到的字符几乎是无限的,但在计算机中,必须事先约定好字符的范围,也就是穷举出所有“可以使用”的字符。这个范围,就是通常说的“字符集”(Character Set)。 ISO8859-1是开发中常见的字符集(MySQL默认就采用这种字符集),它支持的语言有英语、德语、法语等,也即包含了英语、德语、法语中的字符。
    在做策划表格解析的时候,我们希望可以在表格里直接填写一些脚本代码。我们的脚本语言使用的 Lua ,所以,直接填写 Lua 代码最为简单。但是,策划同学强烈需要在脚本中直接使用中文。而 Lua 原生并不支持使用中文作为变量名。一开始我们使用了一些变通的方案:比如建立一个字典,把中文词通过程序替换成相应的拼音。倒也能工作。 昨天在午饭途中的电梯里,我想到了另一个方案,用了一个下午实现出来验证可用。 修改 Lua 的语法解析代码,让其支持汉字并非难事。但我不太想通过给 Lua 打补丁,修改 Lua 语言的方式来做这件事情。即,我不想因为这个项目为 Lua 创造一门方言。但是,我们却可以把策划表格中填写的代码当成一种 DSL ,正如之前我实现的公式解析 那样。把这部分用 Lua 的方言来实现,把修改的影响减少到最小,而不蔓延到整个系统的实现语言中去,或许是个更好的方法。
    这篇文章展示了一些常见环境下main函数的汇编码,并简单的进行分析,内容比较粗浅。其实只要能完全理解栈帧的概念,不管将来遇到什么样的函数汇编码,都能轻松突破各种混乱的操作,找到其关键内容,这也正是本文的初衷。今后经过进一步的学习,我还将尝试完整地解析各个操作系统的可执行文件的内容,而不仅仅只是一个空的main函数。
[ 共183篇文章 ][ 第6页/共10页 ][ |< ][ 1 ][ 2 ][ 3 ][ 4 ][ 5 ][ 6 ][ 7 ][ 8 ][ 9 ][ 10 ]
赞助商广告
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1