“茴字有六种写法”式的C语言笔试题

今天在CSDN上真的看见了孔乙己式的问题:用C语言,不用四则运算,对一个变量进行加1操作。答案是(i在某处定义了):
i = (int)&(((char*)i)[1]);

想出这个问题的兄台真是够孔乙己的——除了用+、-、*、/和++,还有别的方法对一个变量加1——茴香豆的“茴”字有六种写法……据说这是一道笔试题。sigh……有钻研精神,可是没有实用主义。
 
在这里解释一下为什么能够实现对i加1,以免有些初学者不懂,另一个目的也是希望大家引以为戒,不要这么孔乙己(关于指针的问题,可以参考我的文章“ 指针是通往地狱的捷径”):
 
首先,看最里面两层括号:
((char*)i)
 
这里将i从整型转换成一个ulong,并使之成为一个指向字符(字符串)的指针,记为ptr。然后是:
i = (int)&(ptr[1]);
 
这就是说,将ptr作为一个指向字符串的指针,这里ptr[1]就相当于*(ptr + 1),因为数组名其实就是地址,所以ptr[1]与*(ptr + 1)等价(有疑问的请参考“The C Programming Language, by Kernigham & Ritchie”)。比如:
 
/* C代码 */
char a[] = "hello, world";
char * ptr = a;
 
printf("%c, %c, %c, %c/n", *(ptr+4), ptr[4], a[4], *(a+4));
 
输出的结果将是:o, o, o, o
 
好了,既然ptr[1]等价于ptr + 1,那么整个表达式可以写成:
int i = (int)(ptr + 1);
 
由于char *所指向的是字符,只占用一个字节,那么指针算术ptr+1将导致ptr的ulong值加1,这样就相当于:
int i = int((ulong)i + 1);
 
这里有这些知识点:指针、数组、指针算术、强制类型转换。看起来出题人对这些知识点的了解还是比较深刻。可我必须说:真是孔乙己式的问题!这点稍微有点深刻的理解只不过为了炫耀而已!这种人能出面试题,且被该公司采用,简直就是中国IT人的耻辱,希望以后这位老兄不要说他是干IT的,咱丢不起那人!自作聪明的家伙!这就跟为了放屁就脱了裤子坐在马桶上,拿本书,然后放个屁走人是一个道理。只可惜,他还崩了一屁股水。
 
这种解答很有技巧性,也说明该老兄脑子里的筋很多,很多弯——去忽悠赵本山都绰绰有余,可是他不像搞IT的,更像是本山大叔,出的题也像“茴字有六种写法你知道吗?”和“1加1在什么情况下等于3?”,三者如出一辙。建议这位老兄搞点好本子,上春晚忽悠去,那里还有人捧场,还能逗乐子。
 
为什么说他崩了自己一屁股水:
1、这条语句的效率问题。要实现对一个变量加1,写成:
i + 1;
或者++i;
翻译成汇编代码基本就是:
ADD i, 1
而且这是单条指令的运算,用ALU就能完成,效率多高!再看看答案,两次强制类型转换,一个指针算术,最后一个赋值,翻译成汇编代码,不知道要多少条(与编译器有关)!效率当然低下!
 
2、溢出问题导致的错误。假如i的值正好是最大的有符号整数(假设int只有16位,那就是65535),将其转换成ulong,值不会变。然后加1,再转换成int,然后,你的答案就是绝对错误的,溢出了!
 
3、安全问题。i的初始值为0,转换成指针后指向了内存0,没关系,相当于NULL,加1后指向了1,不巧有个黑客发现了这段代码,并得到了这个指针,然后……你就等着哭吧,老兄!
 
出这道题的老兄,省省劲吧。要是我笔试or面试碰上这样的题,我绝对会鄙视他一番,然后问他:“茴香豆的茴字有六种写法,你会么?”问完之后,扬长而去——为出这种题的公司干活,不丢人么?
 
说实在的我也挺无聊,闲着没事跟孔乙己叫什么真?看来真得约上这位出题的老兄去后海边的孔乙己酒吧喝点酒,看他排出九文大钱,用手指蘸着酒在桌上画着,再听他拽一遍:“茴香豆的茴字有六种写法,你会么?”
 

你可能感兴趣的:(c,面试,汇编,null,语言,编译器)