百度笔试题——找出程序中的错误(关于中文字符赋值给char时它是一个负数的问题),今天我是做错了!悲剧了!

来源:互联网 发布:2017ipad视频软件 编辑:程序博客网 时间:2024/03/29 08:26

今天本来就打算去体验一下公司招聘的笔试题,结果不笔不是知道,一笔吓一跳(自己被鄙视了快哭了

今天上午百度的笔试题:

如下程序,统计字符串中字母a~z出现的次数,foo函数有错误,请指出:

 

int foo(char a[], int cun[256]){memset(cun, 0, sizeof(cun));
while(*a != '\0'){cun[*a]++;++a;}for(char ch='a'; ch<='z'; ch++){if(cun[ch]>0)printf("char %c, cun=%d\n", ch, cun[ch]);}return 0;}int main(){char a[] = "百度abc";int cun[256];foo(a, cun);return 0;}

 

我今天上午参加百度笔试, 一看这道题,我心想总算是遇到一道简单题了, 二话不说直接答道:

“错误在于‘++a"操作,因为a为数组名,是const char *类型,不能改变其值,因此也不能进行"++a"操作”。

 结果今天回来跟同学一讨论,我还告诉他错误就在‘++a’,后来他写了类似的程序测试不对, 再将他的程序发给我,我才意识到我今天答错了。后来我直接凭今天上午做题的记忆写出上面的程序一运行,结果自己傻眼了! 我确实答错了!后来发现原来"++a"操作”并没有错, 因为在foo()里a数组名是形参,所以这里的a实际上是一个普通指针(char *),而不再是指针常数(const char *),因此可以改变其值,当然‘++a’操作也正确。(这一点可以在我转载的文章“C/C++数组名与指针区别深入探索”中看到。 我杯具就杯具在这里,才几个月前看的这篇文章,结果今天就不记得了!犯这样的错误!悲催呀!)

 

真正的错误在于:a[] = "百度abc";中含有中文,而中文字符是采用2字节编码,且各个字节的最高位(第8位)为1,这是为了与ASCII码相区别。所以在foo()中处理到中文字符时,“*a"的值为负数,所以cun[*a]访问数组就越界,发生内存访问错误!因此应该在具体统计计数处将”cun[*a]++;“改为"cun[*((unsigned char*)a)]++;"

 

我当时第一眼看到中文”百度“两个,就对其起了一下疑心(心想要统计字母a~z出现的次数,中间冒出中文不易出错吗?),但我立即想到这是百度的招聘笔试,他在字符串中加个”百度“2字没什么蹊跷的。 结果就一眼认定foo()函数中的a为const char *类型。 结果杯具了!丫丫的百度!题出得还很有水平呀!
 
当然这里还有第二个错误:
foo()中的第一行:memset(cun, 0, sizeof(cun)) ;
这里的sizeof(cun)= 4 了,而不再是 sizeof(cun)= 4 * 256;原因同上。应该改为:”memset(cun, 0, 256*sizeof(int));“
 
 嗨!还是自己基础不扎实啊! 发现基础不扎实,一切都是虚的! 今后得多注意基础知识的深入学习! 今天其他的题还有答错的, 所以这次笔试肯定挂了! 笔试成鄙视了!!!
 
我写这篇文章不是为了晒什么笔试题,仅为了今后提醒自己注意基础知识的深入学习且自己学过的内容也要常温习之!