首页 > 编程语言 > 最为奇怪的程序语言的特性

最为奇怪的程序语言的特性

2010年1月21日 发表评论 阅读评论 8,122 人阅读    

这些最为奇怪的程序语言的特性,来自stackoverflow.com,原贴在这里。我摘选了一些例子,的确是比较怪异,让我们一个一个来看看。 

1、C语言中的数组 

在C/C++中,a[10] 可以写成 10[a] 

“Hello World”[i] 也可以写成 i["Hello World"] 

这样的特性是不是很怪异?如果你想知道为什么的话,你可以看看本站的这篇文章——《C语言的谜题》中的第12题。 

2、在Javascript中 

 ’5′ + 3 的结果是:’53′
 ’5′ – 3 的结果是:2 

3、C/C++中的Trigraphs 

int main() {
   cout << "LOL??!";
}

上面的这段程序会输出: “LOL|”,这是因为 ??! 被转成了 | ,关于Trigraphs,下面有个表格: 

??= #
??( [
??/ \
??) ]
??’ ^
??< {
??! |
??> }
??- ~

  

4、JavaScript 的条件表 

看到下面这个表,不难理解为什么Javascript程序员为什么痛苦了——《Javascript程序员嘴最脏??》 

''        ==   '0'           //false
0         ==   ''            //true
0         ==   '0'           //true
false     ==   'false'       //false
false     ==   '0'           //true
false     ==   undefined     //false
false     ==   null          //false
null      ==   undefined     //true
" \t\r\n" ==   0             //true

 

5、Java的Integer cache 

Integer foo = 1000;
Integer bar = 1000;
 
foo <= bar; // true
foo >= bar; // true
foo == bar; // false
 
//然后,如果你的 foo 和 bar 的值在 127 和 -128 之间(包括)
//那么,其行为则改变了:
 
Integer foo = 42;
Integer bar = 42;
 
foo <= bar; // true
foo >= bar; // true
foo == bar; // true

为什么会这样呢?你需要了解一下Java Interger Cache,下面是相关的程序,注意其中的注释

/**
     * Returns a <tt>Integer</tt> instance representing the specified
     * <tt>int</tt> value.
     * If a new <tt>Integer</tt> instance is not required, this method
     * should generally be used in preference to the constructor
     * <a href="mailto:{@link">{@link</a> #Integer(int)}, as this method is likely to yield
     * significantly better space and time performance by caching
     * frequently requested values.
     *
     * @param  i an <code>int</code> value.
     * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }

5、Perl的那些奇怪的变量

$.
$_
$_#
$$
$[
@_

其所有的这些怪异的变量请参看:http://www.kichwa.com/quik_ref/spec_variables.html 

6、Java的异常返回

请看下面这段程序,你觉得其返回true还是false?

try {
    return true;
} finally {
    return false;
}

在 javascript 和python下,其行为和Java的是一样的。 

7、C语言中的Duff device

下面的这段程序你能看得懂吗?这就是所谓的Duff Device,相当的怪异。

void duff_memcpy( char* to, char* from, size_t count ) {
    size_t n = (count+7)/8;
    switch( count%8 ) {
    case 0: do{ *to++ = *from++;
    case 7:     *to++ = *from++;
    case 6:     *to++ = *from++;
    case 5:     *to++ = *from++;
    case 4:     *to++ = *from++;
    case 3:     *to++ = *from++;
    case 2:     *to++ = *from++;
    case 1:     *to++ = *from++;
            }while(--n>0);
    }
} 

8、PHP中的字符串当函数用

PHP中的某些用法也是很怪异的

$x = "foo";
function foo(){ echo "wtf"; }
$x();

9、在C++中,你可以使用空指针调用静态函数

class Foo {
  public:
    static void bar() {
      std::cout << "bar()" << std::endl;
    }
};
 
int main(void) {
  Foo * foo = NULL;
  foo->bar(); //=> WTF!?
  return 0; // Ok!
}

呵呵。的确是挺怪异的。





分类: 编程语言 标签: , , , ,
好烂啊有点差凑合看看还不错很精彩 (22 人打了分,平均分: 4.68 )
Loading ... Loading ...
  1. 2010年1月21日09:17 | #1

    第8个在PYTHON里面也可以的吧。应该也算是函数指针或者委托~

  2. gugaotianshi
    2010年1月21日10:23 | #2

    @枯藤昏鸦
    python里和这个完全不同。字符串是字符串,函数是函数,不同的对象。

    php的这种字符串特性,使它具有“动态构造变量”的能力。记得这东西04年左右我写FLASH脚本时碰到过(好像是用 eval 实现的)。

    ———— php code ———-
    <?
    $p = 'a_';
    for($i=0; $i
    ——————————–

  3. gugaotianshi
    2010年1月21日10:25 | #3

    @gugaotianshi
    怎么后半段没了?

  4. justsor
    2010年1月21日10:26 | #4

    第9个:前段时间google所受攻击中的IE漏洞是源于此吗?“漏洞是IE中的一个无效指针引用。在一些情况下,这个指针可能在对象删除之后仍然能够访问。在精心设计的攻击中,通过试图访问已被释放的对象,IE可以被用来允许远程代码的执行。”

  5. KNUP
    2010年1月21日11:03 | #5

    第9条应该很正常吧?静态成员函数是类方法,不需要有类的实例,自然可以用空指针调用。

  6. roby
    2010年1月21日11:03 | #6

    不看不崩溃。看了就崩溃

  7. qingshi163
    2010年1月21日11:52 | #7

    javascript的那个字符和数字的+-太诡异了。。
    java的异常返回。。这个。。结果咋样?
    Duff device真没看懂干嘛用的。。。。。。。

    其他的到还是可以理解的

  8. 2010年1月21日12:11 | #8

    @qingshi163
    个人猜测Duff device应该是用来加速拷贝过程的……纯猜测~

  9. 刘鑫
    2010年1月21日16:30 | #9

    @枯藤昏鸦
    明确的告诉你,不行,要显式自省。不过我记得原文上有哥们儿也给出Python一些很二的语法来着。

  10. 刘鑫
    2010年1月21日16:31 | #10

    gugaotianshi :
    @枯藤昏鸦
    python里和这个完全不同。字符串是字符串,函数是函数,不同的对象。
    php的这种字符串特性,使它具有“动态构造变量”的能力。记得这东西04年左右我写FLASH脚本时碰到过(好像是用 eval 实现的)。
    ———— php code ———-
    <?
    $p = ‘a_’;
    for($i=0; $i
    ——————————–

    明确的告诉你,不行,要显式自省。不过我记得原文上有哥们儿也给出Python一些很二的语法来着。

  11. 刘鑫
    2010年1月21日16:32 | #11

    回了两次引用都错了,我自挂东南枝去……

  12. alan
    2010年1月21日19:46 | #12

    第7条用C的同学应该都挺熟的。

  13. hahajerry007
    2010年1月21日21:43 | #13

    好久没更新了,之前还在猜测难道大大们是google中国的员工所以最近都在忙着找工作没时间更新了。duff device好像是个串口的程序,这样写会非常高效,很高兴再次看到coolshell的更新。

  14. 阿拉
    2010年1月22日11:12 | #14

    在以前NXP的一个卡驱动程序中见过duff驱动

    不过,确实神奇~

  15. Yang
    2010年1月23日19:58 | #15

    Perl的奇怪变量倒是经常在用,慢慢的也就熟悉了
    Perl有个English模块,把这些奇怪的变量包装成英语单词,但似乎没人用

  16. 2010年1月24日09:47 | #16

    第一条是从ASM中继承来的。基址变址寻址方式

  17. 2010年1月25日21:37 | #17

    哪里痛苦了,那个的javascript条件表很符合直觉口牙!比如false是一个Boolean对象,当然不等于null或undefined

    唯一可能会让人困惑的是:
    0 == ’0′

    false == ’0′

    但是只要看过ECMA262规定“==”的类型转换算法,就很容易理解:

    对于x == y,如果x和y类型不同
    如果两者有一个是数字,另一个是字符串,则先把数字转换成字符串,再比较,所以0 == ’0′
    如果两者有一个是布尔,则先把布尔值转换成数字,再比较,Number(true)返回1,Number(false)返回0,这时由于另一边是字符串,根据上条规则,1和0还要转换成字符串,于是false == ’0′, true == ’1′
    同理其实false==undefined的时候是在把0和undefined比较

  18. btw616
    2010年1月25日23:30 | #18

    那个Duff Device太酷了,很棒的方法嘛!并不难看的,按规定的顺序来就好了

  19. xLight
    2010年1月26日10:59 | #19

    PHP那个算是一个动态特性吧
    但不能乱用,很难debug

  20. 古歌
    2010年1月28日16:11 | #20

    记得在哪里看过a++,a–可以随便用,++a和–a最好不要到处用,因为在不同的编译器下会有不同的结果。现在方便了,万一以后出现问题,让找bug的人难为死。。。

  21. 古歌
    2010年1月28日16:12 | #21

    @刘鑫
    为何自挂东南枝?西北有高楼^^

  22. zino
    2010年2月23日09:00 | #22

    第三个例子LOLI =,= 难道是我思想不纯洁

  23. 2010年9月27日10:22 | #23

    我是PHP程序员,我觉得PHP的可变函数和可变变量的特性很好用啊,哈哈,其他语言没有吗?

  24. v5
    2010年11月25日12:37 | #24

    忍不住说一下,第七个博主搞错了。
    to是个串口,不应该++。
    不要无人子弟啊:D
    **正确代码**
    send(to, from, count)
    register short *to, *from;
    register count;
    {
    register n=(count+7)/8;
    switch(count%8){
    case 0: do{ *to = *from++;
    case 7: *to = *from++;
    case 6: *to = *from++;
    case 5: *to = *from++;
    case 4: *to = *from++;
    case 3: *to = *from++;
    case 2: *to = *from++;
    case 1: *to = *from++;
    }while(–n>0);
    }
    }

  25. 莽东
    2010年12月10日16:39 | #25

    我们看一下Integer Cache代码如下:
    private static class IntegerCache {
    private IntegerCache(){}

    static final Integer cache[] = new Integer[-(-128) + 127 + 1];

    static {
    for(int i = 0; i < cache.length; i++)
    cache[i] = new Integer(i – 128);
    }
    }

    这个私有类的cache字段的值实际上从-128到+127,这256个数值,结合valueOf的代码,发现如果输入了从-128到+127的数值,必然返回Integer形式的-128到+127。所以Integer诡异行为得另外分析啊

  26. 2010年12月10日17:08 | #26

    我现在终于明白为什么出现Java的Integer cache 的异常情况,对于象Integer这样的对象,如果用象“>=”、“<=”、“==”的操作符的时候,实际上是比较的是两者句柄的地址,对于不在-128到+127之间的数,当然是由于两者不是同一个对象导致两者比较不会相同;但是对于在其范围之内的数比较的是两个数的cache的地址,由于两者序号一致所以,cache的地址自然一样所有就出现的这样的诡异的现象,如果把“==”换成“equals”方法自然就露出了狐狸尾巴啊!呵呵看来对JAVA又有了更进一步的理解!

  27. 昵称
    2011年4月10日16:29 | #27

    看见标题第一个想到的是Scheme的call/cc

  28. 2011年4月21日21:47 | #28

    我测试第三个的时候出现问题了,如果不加-trigraphs参数的话,用gcc编译不会出现这种效果欧~

  1. 2010年6月2日09:53 | #1
  2. 2010年11月26日02:06 | #2
  3. 2010年12月21日22:20 | #3
  4. 2010年12月30日00:48 | #4
  5. 2010年12月30日00:58 | #5

无觅相关文章插件,快速提升流量