搜索
bottom↓
回复: 17

晕菜!C语言奇特的特性

[复制链接]

出0入93汤圆

发表于 2011-12-26 22:43:56 | 显示全部楼层 |阅读模式
根据堆栈溢出网站上内容改编成一道C语言测试题,全部做正确很难啊,虽然题目看上去很简单。
C++的更多,Javascript的最多,简直就是不可理喻!

C++版的:
C++1x Lambda表达式:
    [] (int x) { std::cout << x << std::endl; } ();
    调用:[](){}();[]{[]{}();}();
晕菜了没有?还好,现在使用C++1x特性的人还不多。

Javascript版的:
    '5'+3 = '53'
    '5'-3 = '2'
    这个才是超级坑爹的。
    还有,2=[2]=[[[2]]]

好了,相信你已经晕的差不多了,现在上正餐,C语言版。没有上面的那么变态,不过也够喝一壶的了。因为C++兼容C89(不兼容C99),下面的内容都是同样适用于C++的。

#include "stdio.h"

int Array[] = {
    123, 456, 789, 012, 345, 678, 901, 234, 567, 890,                   //Array[3] = ?
};

typedef char c;

int main(int argc, char* argv[])
{
    {
        int i;

        for(i = sizeof(Array) / sizeof(int); i --> 0; ){                // -->在这里很直观啊
            printf("%d\n", Array);
        }

        i = 0;
        Array[i++] = i;                                                 //到底是先赋值还是先自增?
        printf("i:%d Array: %d %d %d\n", i, 0[Array], 1[Array], 2[Array], 3[Array]);    //数组访问有问题吗,有问题吗?
    }

    printf("LOL?" "?"                     "!LOL\n");                    //结果是多少
    printf("LOL" "??!"                     "LOL\n");                    //结果又是多少

    http://www.ourdev.cn                                                直接输入URL,不需要注释

    {                                                                   //代码都变成天书了
        struct c {c c;} c;
        c: c.c = 'c';
        printf( "%c\n", c.c);
    }

    {                                                                   //奇怪的sizeof行为,结果是什么
        int x = 1;
        int sz = sizeof(x++);                                           //sizeof带括号
        char a[] = "Hello";
        int s1 = sizeof a;                                              //sizeof不带括号
        //int ss = sizeof int;                                          //为什么就不行呢?
        int s2 = sizeof ("Hello", a);
        printf("%d %d %d\n", x, s1, s2);
    }

    return 0;
}




附上原始出处:http://stackoverflow.com/questions/1995113/strangest-language-feature?page=1&tab=votes#tab-top

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2011-12-26 23:30:51 | 显示全部楼层
Array[3]=012=10

0开头为8进制数

出0入0汤圆

发表于 2011-12-27 08:47:33 | 显示全部楼层
啥玩意儿啊……

出0入93汤圆

 楼主| 发表于 2011-12-27 08:52:06 | 显示全部楼层
下面是VC(含VC6和VS2005)的执行结果:
890
567
234
901
678
345
10
789
456
123
i:1 Array: 0 456 789
LOL??!LOL
LOL|LOL
c
1 6 4


我只在VC和Keil上测试过,未测试其他编译器。结果如下:

回复【1楼】hsztc  
array[3]=012=10
0开头为8进制数
-----------------------------------------------------------------------
对的。

for(i = sizeof(Array) / sizeof(int); i --> 0; )      这里只管看起来就是i从数组最后一个元素递减到0,等价于
for(i = sizeof(Array) / sizeof(int) - 1; i >= 0; i--)
C语言没有-->操作符,i --> 0会被解析成(i--) > 0

Array[i++] = i,优先级的问题,貌似跟编译器相关?
VC显示:      i:1 Array: 0 456 789
Keil C51显示:i:1 Array: 1 456 789
Keil MDK显示:i:1 Array: 0 456 789


1[Array] = Array[1],这是个C语言的奇怪特性,在编程语言的奇怪特性中击败了其他所有语言的奇怪特性荣登榜首。

printf("LOL?" "?"                     "!LOL\n");            直接组合成LOL??!LOL
printf("LOL" "??!"                     "LOL\n");            转义字符不仅有\,还有??,??!会被转义成|,一不小心就会犯错

http://www.ourdev.cn                这个是用来好玩的,http:解析成标号了,//解析成注释


    {                                                                   //代码都变成天书了
        struct c {c c;} c;
        c: c.c = 'c';
        printf( "%c\n", c.c);
    }
这个在Keil C51中编译不通过,VC和MDK中没有问题。


int sz = sizeof(x++);这个我实在分析不出来,VC和Keil都显示结果为1。

出0入0汤圆

发表于 2011-12-27 08:56:42 | 显示全部楼层
相当的晕  没见过的用法啊  我是菜鸟

出0入0汤圆

发表于 2011-12-30 18:17:41 | 显示全部楼层

出0入0汤圆

发表于 2011-12-30 19:56:28 | 显示全部楼层
谁写的垃圾程序,你让别人怎么看啊,明天别来上班了。老板如是说

出0入0汤圆

发表于 2011-12-30 20:32:29 | 显示全部楼层
对javascript个人不觉得晕,那是个解释型语言,不严谨的~你随意写一个语句,它能识别就出结果,不能识别就跳过,这就要求尽可能的去解释你所写的,你写的东西格式压根不对,那它爱出啥就是啥,不出也就算了,‘5’-3=‘2’这类东西,很正常啊,‘5’的ASCII码值减去3本来就是‘2’的ASCII码值啊~

出0入0汤圆

发表于 2011-12-30 22:43:04 | 显示全部楼层
int sz = sizeof(x++);这个我实在分析不出来,VC和Keil都显示结果为1。
--------------------------------
因为sizeof()是运算符,在编译阶段就对括号中的类型进行判断,所以编译后直接成了赋值常数给sz,
类似的:

char a[2]={ 1, 2};
int sz=sizeof(0[a]&1[a]);
sz=sizeof(0[a]);
sz=(-1)[&a[1]];

int s2 = sizeof ("Hello", a); 这个是逗号表达式,其实比较常见的形式是变量声明和for语句中,比如
int a=1,b=2;
for(i=0,j=1;i<8;i++,j++)

看这些题目,让我想起了国际C语言混乱代码大赛……

出0入93汤圆

 楼主| 发表于 2011-12-31 10:59:34 | 显示全部楼层
回复【8楼】yyccaa  
-----------------------------------------------------------------------

int sz = sizeof(x++);这个我实在分析不出来,VC和Keil都显示结果为1。
--------------------------------
因为sizeof()是运算符,在编译阶段就对括号中的类型进行判断,所以编译后直接成了赋值常数给sz,
类似的:


哥们我很想同意你的答案,可是不好意思,你的解释是错的。

按照sizeof后面接类型的解释,sizeof(x++)应该为4,但是结果为1。
现在这里有三个运算符:sizeof、()、++,估计编译器的计算顺序是:
sizeof(x++) ==> sizeof(x), x++  ==> sizeof(1), x++ ==> sizeof(1) = 1, x = 2
但是很不明白。x和x++都是int类型,求sizeof之后应该为4,但是它直接用一个常数代替了。
而且可以肯定的是没有先执行x++,因为sizeof(2) = 2。

出0入93汤圆

 楼主| 发表于 2011-12-31 11:13:23 | 显示全部楼层
回复【7楼】nongxiaoming  
-----------------------------------------------------------------------

哥们你用C去解释Javascript,我很无语啊。照你这意思,'5'+3='8'才对,可是它等于'53'。
再说,Javascript中哪来的字符型?单引号和双引号的都是字符串好不好。

Javascript的字符串重载了+号运算符,没有重载-号运算符,是引起此类问题的根本所在。

'5'-3会被解析成5-3=2,前面的字符串会根据第二个操作数推断转换成数值型,因为数值型才有-号运算符。

举例:'123'-5=118。


同样,C++也可以实现,只不过除了让人犯晕外,没别的用途。这也是微软为什么强制要求C#的操作符重载时必须成对出现的原因。

出0入0汤圆

发表于 2011-12-31 12:45:06 | 显示全部楼层
晕喽,这个还真没用过

出0入0汤圆

发表于 2011-12-31 13:31:37 | 显示全部楼层
按照sizeof后面接类型的解释,sizeof(x++)应该为4,但是结果为1。
--------------------------------------
可惜啊哥们,你没看清printf输出的是哪个变量值:

printf("%d %d %d\n", x, s1, s2);

是 x,不是sz。

出0入0汤圆

发表于 2012-1-2 09:22:55 | 显示全部楼层
晕~~~~~

出0入0汤圆

发表于 2012-1-5 23:30:22 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-1-6 01:54:40 | 显示全部楼层
我一般不去理会这些蛋痛的语法,原因是我不会用这些蛋痛的语法。

去钻研这些蛋痛的语法,我觉得是闲得没事做,搞语言开发的专家的事。

就像现在天_朝教育给学生的一样,什么刁钻的数学题都给你做,却一辈子也不会用到,碰到。

当然我肯定当不了也成了不上面所说的专家,我只能够当一个写出浅显易明,可读性强,易维护的代码的普通人。

出0入0汤圆

发表于 2014-5-20 16:01:31 | 显示全部楼层
有段时间没研究这个了,标记下

出0入0汤圆

发表于 2014-5-20 16:05:19 | 显示全部楼层
你不会是要参加乱码大赛的吧
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 00:11

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表