我为何不看好D语言

最近发现关于D语言的消息不少,看来他也在逐步被人关注。我第一次接触到D语言的时候是在大约5年前,差不多和我接触到Lua语言同时,我当时对Lua语言下结论是这个是好东西,将来有前途,所以我翻译了Lua的手册;当时我认为D语言也绝对是个强劲的工具:

D语言是由Digital Mars公司开发的编程语言,起因是为了改进C++。它与C二进制兼容(不完全),可编译为本地码,有GC也可手动管理内存,语法上借鉴多种语言,模板则 在C++的基础上做了相当大的扩充。D 语言既有 C 语言的强大威力,又有 Python 和 Ruby 的开发效率。它是一种集垃圾回收、手工内存操作、契约式设计、高级模板技术、内嵌汇编、内置单元测试、Mixin 风格多继承、包管理机制、内置同步机制、内建基本运行时信息的系统级编程语言。1

然而我却觉得D语言没有太大的生命力。原因并非在于D语言本身不好,很可能这些因素将导致D语言不能最终流行:

首先看D语言背后公司Digital Mars(以下简称DM),虽然DM在C/C++编译器方面有着很久的经验,但是DM并不是一个具有很大影响力的公司。Java当年的流行很大程度上是拜 IBM所赐,当然本身Sun也是非常有影响力的公司。C#在微软的推动下,一下就非常流行。然而DM则没有这种实力,除非被哪个IT贵人看上。同时DM甚 至不是一个上市公司,我虽然不能推断DM的赢利能力,但根据DM的网站看出来,DM的主要产品就是Digital Mars C/C++编译器加上一些书籍。编译器这个市场我不了解,不过我清楚竞争者很多,微软、Borland、Intel、IBM、SUN、Apple都有自己 的编译器,微软还有强悍的整套IDE、Visual Studio。Borland这么历史悠久做开发工具的,现在被贱卖了,Intel的C/C++编译器对Intel芯片最最好的优化。过去DM卖这个开发 工具,现在所有的东西都可以在其网上下载了,所以Digital Mars的C/C++编译器只能是小范围的应用,不可能有太多的利润。编译器和语言开发工具这些个东西,由于市场问题,小公司很难搞大——他们的客户是开 发者,而开发者限于项目的要求,一般不会使用不成熟的工具,同时很多工具的应用往往由一些不懂技术的人(老总)来拍板,他们往往看哪些东西比较流行,而小 公司限于其规模,推广这些东西很困难,需要很长的周期。

既然DM不是一个大公司,自己没有十足的能力去把D语言做大,那么还有一条路子可走,那就是开放。GCC也是一个相当不错的编译器,Linux和 FreeBSD等一系列*nix操作系统都是构建于其上,而它却是一个自由开放的工具。现在相当多的流行的编程语言,如PHP、Python、Ruby, 都是开放的,仅仅在几个人创始人的手中,以很小初始的成本,就走到了今天,获得了巨大的成功。而D语言却是封闭的,仅仅只做了一个语言标准,如果D语言打 算像Java那样,必须有大公司支持——然而Java现在也逐步开源了。虽然D语言已经有了一个开源的实现Dgcc,然而由于D语言不开放,标准由DM一家控制,也是非常危险的,未来开源的版本势必落后于商业版本。

希望D语言能真正走上开放自由的道路,开放的才是有生命力的。

1、值传递的一个错误认识 先看一段关于Exchg1 函数的代码: void Exchg1(int x, int y) /* 定义中的x,y变量被称为Exchg1 函数的形式参数 */ { int tmp; tmp = x; x = y; y = tmp; printf("x = %d, y = %d.\n", x, y); } 问:你认为这个函数是在做什么呀? 答:好像是对参数 x、y 的值对调吧? 请往下看,我想利用这个函数来完成对 a,b 两个变量值的对调,程序如下: int main() { int a = 4,b = 6; Exchg1(a, b); /*a,b 变量为 Exchg1 函数的实际参数。*/ printf("a = %d, b = %d.\n”, a, b); return(0); } 我问:Exchg1()里头的 printf(“x = %d, y = %d.\n”, x, y);语句会输出什么啊? 我再问:Exchg1()后的 printf("a = %d, b = %d.\n”, a, b);语 句输出的是什么? 程序输出的结果是: x = 6, y = 4. a = 4, b = 6. 为什么是 a = 6,b = 4 呢? 奇怪,明明我把 a、b 分别代入了 x、y 中,并在函数里完成了两个变量值的交换,为什么 a、b 变量值还是没有交换(仍然是 a = 4、b= 6,而是 a = 6、b = 4)?如果你也会有这个疑问,那是因为你根本就知实参 a、b 与形参 x、y 的关系了。 2、一个预备的常识 为了说明这个问题,我先给出一个代码: int a = 4; int x; x = a; x = x + 3; 看好了没,现在我问你:最终 a 值是多少,x 值是多少? (怎么搞的,给我这个小儿科的问题。还简单,就是 a = 4、x = 7 嘛!) 在这个代码中,你要明白一个东西:虽然 a 值赋给了 x,但是 a 变量并是x 变量哦。我们对 x 任何的修改,都会改变 a变量。呵呵!虽然简单,并且一看就理所当然,过可是一个很重要的认识喔。 3、理解值传递的形式 看调用 Exch1 函数的代码: int main() { int a = 4,b = 6; Exchg1(a, b) /* 这里调用了 Exchg1 函数 */ printf("a = %d, b = %d.\n", a, b); } Exchg1(a, b)时所完成的操作代码如下所示。 int x = a; /* ← */ int y = b; /* ← 注意这里,头两行是调用函数时的隐含操作 */ int tmp; tmp = x; x = y; y = tmp; AI写代码 c 运行 1 2 3 4 5 6 请注意在调用执行 Exchg1 函数的操作中我人为地加上了头两句: int x = a; int y = b; AI写代码 c 运行 1 2 3 这是调用函数时的两个隐含动作。它确实存在,现在我只过把它显式地写了出来而已。问题一下就清晰起来啦。(看到这里,现在你认为函数里面交换操作的是a、b 变量或者只是 x、y 变量呢?) 原来 ,其实函数在调用时是隐含地把实参 a、b 的值分别赋值给了 x、y,之后在你写的 Exchg1 函数体内再也没有对 a、b 进行任何的操作了。交换的只是 x、y 变量。并是 a、b。当然 a、b 的值没有改变啦!函数只是把 a、b 的值通过赋值传递给了 x、y,函数里头操作的只是 x、y 的值并是 a、b 的值。这就是所谓的参数的值传递了。 哈哈,终于明白了,正是因为它隐含了那两个的赋值操作,才让我们产生了前述的迷惑(以为 a、b 已经代替了 x、y,对 x、y 的操作就是对a、b 的操作了,这是一个错误的观点啊!) 总结这段文字,提取重要知识点,帮我改写成一篇讲述值传递的文章
最新发布
07-02
<think>我们被要求总结并改写关于C语言中函数参数值传递机制的解释,形成一篇清晰的技术文章。根据引用[1]:在C语言中,函数参数的传递机制是值传递,这意味着调用函数时实际传递的是参数值的副本。我们可以这样组织文章:1.解释值传递的概念2.通过示例代码展示值传递的行为3.分析值传递的优缺点4.讨论如何通过指针实现类似引用传递的效果注意:文章中需要包含代码示例,并按照要求使用LaTeX格式行内公式(如变量名等)和独立公式(如果有数学表达式)。同时,在文章末尾生成相关问题。由于引用中只提到了值传递的基本概念和一个简单示例,我们将围绕这个核心展开。</think>### C语言函数参数传递机制:深入理解值传递 在C语言中,**函数参数的传递机制本质上是值传递**,这是理解函数行为的关键基础。当调用函数时,实际传递的是参数值的副本而非原始变量本身[^1]。这种机制直接影响函数内对参数的操作结果。 #### 值传递的核心特征 1. **副本创建机制** 调用函数时,系统会为每个参数创建独立的临时副本: $$ \text{原始变量} \xrightarrow{\text{复制}} \text{函数内副本} $$ 2. **操作隔离性** 函数内对参数的所有修改仅作用于副本: ```c void modify(int n) { n += 10; // 仅修改副本 } int main() { int value = 5; modify(value); printf("Value = %d", value); // 输出 5(原始值未变) } ``` 如示例所示,函数内对`n`的修改会影响外部的`value`变量[^1]。 3. **内存独立分配** 原始变量与函数参数副本占用同的内存地址: ```c void checkAddress(int param) { printf("副本地址: %p\n", ¶m); // 与原始变量地址同 } ``` #### 值传递的底层原理 当函数被调用时,参数传递过程遵循以下步骤: 1. **参数求值**:计算实参表达式的值 2. **副本创建**:将计算结果复制到栈帧中的参数存储区 3. **函数操作**:函数内所有操作基于副本进行 4. **栈帧销毁**:函数返回时副本自动释放 该过程可用内存模型表示: ``` 调用前内存: [main::value = 5] 调用时内存: [main::value = 5] → [modify::n = 5] (副本) 修改后内存: [main::value = 5] → [modify::n = 15] (仅副本变化) ``` #### 值传递的实践意义 1. **数据保护优势** 避免函数意外修改外部变量,增强代码可靠性: ```c void processData(int input) { // 安全处理,原始数据受保护 } ``` 2. **指针突破限制** 通过传递指针实现"类引用传递"效果: ```c void realModify(int *ptr) { *ptr += 10; // 通过指针修改原始数据 } // 调用: realModify(&value); ``` 3. **结构体处理** 传递结构体时产生完整副本(注意性能影响): ```c struct Point { int x, y; }; void movePoint(struct Point p) { p.x += 10; // 仅修改副本 } ``` #### 与其他语言的对比 | 特性 | C语言值传递 | C++引用传递 | Java对象传递 | |--------------|----------------|----------------|---------------| | 传递内容 | 变量值的副本 | 变量的别名 | 对象引用的副本 | | 修改原始数据 | 需用指针 | 直接修改 | 间接修改 | | 内存开销 | 按值大小复制 | 无额外开销 | 引用复制 | > **关键结论**:C语言的函数参数传递本质是值传递,理解这一机制能避免常见的逻辑错误,也是掌握指针应用的基础[^4]。 --- ### 相关问题 1. 值传递机制如何影响大型结构体的函数调用性能? 2. 在C语言中如何实现真正的引用传递效果? 3. 值传递与指针传递在内存管理上有何本质区别? 4. 递归函数调用中的参数传递遵循什么特殊规则? 5. const修饰符如何与值传递机制协同工作?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值