通过静态局部变量看C,C++,C#,Java,PHP的特点

php中文网
发布: 2016-06-23 13:39:58
原创
1314人浏览过

0 问题由来

对这个问题的思考来自于面向对象设计中的单例设计模式的实现。

C++中单例模式实现标准代码为:

C知道
C知道

CSDN推出的一款AI技术问答工具

C知道 45
查看详情 C知道
#include <stdio.h>int init(){    printf("init()\n");    return 22;}int GetTheOnly(){    static int x = init();      return x;}int main(){    int only = GetTheOnly();    return 0;}
登录后复制

在获取实例函数GetTheOnly()中, 静态局部变量用户存储唯一实例,并且初始化时直接使用init()函数动态初始化。

看起来如此简单,但同样的代码作为C来编译却不能通过,编译器在编译 static int x = init()这一行时报错:

立即学习PHP免费学习笔记(深入)”;

错误:初始值设定元素不是常量

可见,C语言中的静态局部变量初始化时必须以常量赋值,也就是说这个初值必须在编译器就能确定

细想一下,以调用函数来初始化静态变量,C++必须保证init();只运行一次。为达此目的,C++编译器必须增加额外代码,我能想到的C++编译器对于static int x = init(); 可能增加的伪代码如下:

    static int x;    static char flag = 0;    if(flag == 0){        x = init();
登录后复制
        flag = 1;    }    return x;
登录后复制
可见,C++编译器又私底下为我们生成了多余的汇编代码。这样导致的结果就是C++容易使用,却不容易理解。

进而想看看其他几门语言对这个问题的处理,随后使用C#,Java,PHP进行了类似的试验,得出了小小的结论。

1 C#,Java根本就不支持静态局部变量

两者只支持静态成员变量,不支持函数内的静态局部变量。想想也对,静态局部变量几乎总是可以使用静态成员变量来代替。

C#测试代码:

using System;namespace ConsoleApplication2{    class Program    {        static int x = 0;        static int init()        {            Console.WriteLine("init()");            return 22;        }        static int GetTheOnly()        {            // static int x = 0;  static local variable is NOT supported by C#.            if(x == 0)            {                x = init();            }            return x;        }        static void Main(string[] args)        {            GetTheOnly();            GetTheOnly();        }    }}
登录后复制

Java测试代码:

public class t{    public static int init(){        System.out.println("init()\n");        return 22;    }    private static int x = 0;    public static int getTheOnly(){        //static int x = 0;  This line cannot be compiled, static local variable is NOT supported by Java        if(x==0){            x = init();        }        return x;    }    public static void main(String[] args) {        getTheOnly();        getTheOnly();    }}
登录后复制

2 PHP对待静态局部变量与C相同,只支持以常量初始化

PHP测试代码:

<?phpfunction init(){    echo "init()\n";    return 22;}function getTheOnly(){    // static $x = init();  PHP only supports initializing static local vairalbel with constant.    static $x = 0;    if($x==0){        $x = init();    }    return $x;}getTheOnly();getTheOnly();
登录后复制

3 一点思考

通过静态局部变量这一非常小的语言细节,可以发现这几门语言的特点。

C++ 编译器是勤劳全面的全才,尽量为用户提供更多的语言功能,而做到这些必须偷偷为用户生成代码,从而导致C++语言的复杂性和“冰山效应”。(想想C++的多重继承,栈上对象,复制构造。。。)


Java和C#则注重易用性,避免二义性,对于同样功能,只给用户一个正确的选择。(想想单继承、对象只能建立在堆上,垃圾回收)


C则始终保持其简洁高效透明,编译器老实巴交,看到了代码也基本上就能预测到生成的汇编。


PHP的结构化部分模仿C的语法,所以很多特性与之类似,然其毕竟是解释性语言,特别是变量名,类名等本身就可以作为变量的解释性语言特性,让其变得异常灵活。面向对象部分则模仿Java的语法,同时又充分体现了解释语言的特点。

相关标签:
c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号