晕菜!C语言奇特的特性
根据堆栈溢出网站上内容改编成一道C语言测试题,全部做正确很难啊,虽然题目看上去很简单。C++的更多,Javascript的最多,简直就是不可理喻!
C++版的:
C++1x Lambda表达式:
[] (int x) { std::cout << x << std::endl; } ();
调用:[](){}();[]{[]{}();}();
晕菜了没有?还好,现在使用C++1x特性的人还不多。
Javascript版的:
'5'+3 = '53'
'5'-3 = '2'
这个才是超级坑爹的。
还有,2==[[]]
好了,相信你已经晕的差不多了,现在上正餐,C语言版。没有上面的那么变态,不过也够喝一壶的了。因为C++兼容C89(不兼容C99),下面的内容都是同样适用于C++的。
#include "stdio.h"
int Array[] = {
123, 456, 789, 012, 345, 678, 901, 234, 567, 890, //Array = ?
};
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; //到底是先赋值还是先自增?
printf("i:%d Array: %d %d %d\n", i, 0, 1, 2, 3); //数组访问有问题吗,有问题吗?
}
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 Array=012=10
0开头为8进制数 啥玩意儿啊…… 下面是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=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,优先级的问题,貌似跟编译器相关?
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,这是个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。 相当的晕没见过的用法啊我是菜鸟 ./emotion/em121.gif 谁写的垃圾程序,你让别人怎么看啊,明天别来上班了。老板如是说 对javascript个人不觉得晕,那是个解释型语言,不严谨的~你随意写一个语句,它能识别就出结果,不能识别就跳过,这就要求尽可能的去解释你所写的,你写的东西格式压根不对,那它爱出啥就是啥,不出也就算了,‘5’-3=‘2’这类东西,很正常啊,‘5’的ASCII码值减去3本来就是‘2’的ASCII码值啊~ int sz = sizeof(x++);这个我实在分析不出来,VC和Keil都显示结果为1。
--------------------------------
因为sizeof()是运算符,在编译阶段就对括号中的类型进行判断,所以编译后直接成了赋值常数给sz,
类似的:
char a={ 1, 2};
int sz=sizeof(0&1);
sz=sizeof(0);
sz=(-1)[&a];
int s2 = sizeof ("Hello", a); 这个是逗号表达式,其实比较常见的形式是变量声明和for语句中,比如
int a=1,b=2;
for(i=0,j=1;i<8;i++,j++)
看这些题目,让我想起了国际C语言混乱代码大赛…… 回复【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。 回复【7楼】nongxiaoming
-----------------------------------------------------------------------
哥们你用C去解释Javascript,我很无语啊。照你这意思,'5'+3='8'才对,可是它等于'53'。
再说,Javascript中哪来的字符型?单引号和双引号的都是字符串好不好。
Javascript的字符串重载了+号运算符,没有重载-号运算符,是引起此类问题的根本所在。
'5'-3会被解析成5-3=2,前面的字符串会根据第二个操作数推断转换成数值型,因为数值型才有-号运算符。
举例:'123'-5=118。
同样,C++也可以实现,只不过除了让人犯晕外,没别的用途。这也是微软为什么强制要求C#的操作符重载时必须成对出现的原因。 晕喽,这个还真没用过 按照sizeof后面接类型的解释,sizeof(x++)应该为4,但是结果为1。
--------------------------------------
可惜啊哥们,你没看清printf输出的是哪个变量值:
printf("%d %d %d\n", x, s1, s2);
是 x,不是sz。 晕~~~~~ mark 我一般不去理会这些蛋痛的语法,原因是我不会用这些蛋痛的语法。
去钻研这些蛋痛的语法,我觉得是闲得没事做,搞语言开发的专家的事。
就像现在天_朝教育给学生的一样,什么刁钻的数学题都给你做,却一辈子也不会用到,碰到。
当然我肯定当不了也成了不上面所说的专家,我只能够当一个写出浅显易明,可读性强,易维护的代码的普通人。 有段时间没研究这个了,标记下 你不会是要参加乱码大赛的吧
页:
[1]