做一些考试准备,以下是过去的问题。 描述下面的C代码所做的事情,并用良好的编程实践进行重写。
int g (int *y, unsigned size,int z){
int tmp = y [0];
int * b = y+size;
y[0] = z;
while(1)
if(*(--b)==z) {
y[0]= tmp; return b-y;
};
y[0] = tmp;
if(tmp == z)
return 0;
else
return -1;
}
似乎无法弄清楚它在做什么,主要是因为while(1)这并不意味着while循环将永远运行,或者if语句取消while(1)。我以前从未见过这样做过。谢谢你的帮助。
答案 0 :(得分:2)
lurker的回答很好地解释了函数的功能,但没有解决如何将其重写为更易于维护的形式。
这是我的建议:
int find_last_occurrence(int y[], unsigned size, int z) {
int first_pos = y[0];
int i = size;
y[0] = z;
while (y[--i] != z)
; /* Intentionally left blank */
y[0] = first_pos;
return i;
}
在参数列表中将y
从int *
更改为int []
表达了y
是数组而不是指向整数的指针的想法。虽然在这种特定情况下它最终是相同的,但是使用数组表示法通常是一个很好的选择。
tmp
是一个变量名称的糟糕选择,它没有说明它的含义。 first_pos
是一个更好的描述。我也完全删除了指针算法并使用了索引:指针算法容易出错,这里完全没必要。此外,它可以立即返回而无需进行任何进一步的计算。
可以说,while
循环空体可能是一个坏主意,因为我们依赖于循环条件的副作用。我觉得它很容易阅读和紧凑,特别是当身体显然是空的并且评论说它是有意的时(但是,我完全期待对此有不满的评论)。
最后,您可能希望重命名变量以避免使用单字母变量名称。
答案 1 :(得分:1)
该函数将返回y
中y[]
中等于z
(大小为size
)的最后一个元素的索引。默认情况下,它会返回0
,因为它实际上会在z
循环之前将y[0]
分配给while (1)
。因此while (1)
如果在b == y
中找不到其他z
,y[]
保证会退出。
顺便说一句,这是一个非常困惑且编写得很糟糕的函数,因为只有while (1)
只能通过return
退出时才会到达while循环块之后的所有指令。
然后错误的是,如果数组中没有z
,它将返回0
,暗示在0
位置有一个。{/ p>