×

Loading...

对于问题二的讨论

本文发表在 rolia.net 枫下论坛while (!vals[max]) {
*(ptr = vals) += 1;

while (*ptr == 10) {
*ptr++ = 0;
*ptr += 1;
}
}

当时,为了满足题目中10行程序的要求,我省去了数据初始化的部分。
(问题:有些朋友告诉我,现在的嵌入系统已经都转到用 Embeded C 或者 Embeded C++ 了。请问专家,在内存有限的的条件下,某些初始化的的命令是否可以省略。比如,本题中我不清零,有潜在的危险嘛?)

这段程序其实是很巧妙的。我没有足够的聪明来写这样的程序,即使看懂这段程序也花了不少的精力。

这短短的5行中,最主要的就是指针的调用。比起其他高级语言来,C/C++最强大的功能就是能够通过指针,直接控制内存。当初我用 Delphi 写程序,到了需要控制内存的时候,就是没有办法。最后只好用 C++ 写了个动态连接库。

好了再回到这段程序。
*(ptr=vals)+=1
vals 已经被分配了地址,在第一行,就把这个地址赋给了ptr。然后该地址的数值加1。
如此累加到该地址的数值为10,满足了第二个 while 的条件 (*ptr==10)。
*ptr++=0
"这一行比较绕人。请注意操作符的优先顺序。是指针 ptr 先加一,然后再给 ptr 指向的地址赋零。"谢谢 HH 的帮助,我终于发现原先的解释是错误的。正确的解释应该是 : 将ptr所指的地址赋零,然后指针加一。如果用 ++ptr 就不行了。移动指针以后,个位数没有清零。
*ptr+=1
新地址(指针 ptr 移动后的地址)的值加1。
!!!注意了,当这次 +1 后,如果 *ptr 也变成了 10,就会重复着一步骤。就像 99+1 一样,不但个位变成了0,十位也要变成0,而百位变成1。
因为 ptr=vals,所以 ptr指向的各个地址和 vals数组的各个单元也是对应的。ptr指向的地址的数值的变化,其实就是 vals[]数组各个单元数值的变化。
依此类推,最后 vals[max]也变成了1。就退出了while(!vals[max]) 的循环。

其实我一开始就想到了用循环的方法,但是后来看到这个程序,觉得这个更有意思。

我自己总结面试失败的原因:
1. 基础概念不清楚。第一问中,运行一个指令,需要几个时钟周期,我就没有明确的概念。
2. 正如 HH 指出来的,内存分配有问题(在嵌入系统中,如果程序员已经知道所要占用的内存空间范围,是否还有必要明确的分配内存?)。虽然我知道是键入错误。但是起码也是 not detail-oriented。
3.程序的风格可能有问题。我这样的半瓶子醋,写程序很不规范。还请专业人士能给大家讲讲,写程序中的一些规则。(比如有的人提倡匈牙利命名法,有的人则对此很反感,到底那个是公认的规范)更多精彩文章及讨论,请光临枫下论坛 rolia.net
Report

Replies, comments and Discussions: