我有一个正在尝试解码的程序。它从另一种语言 (whose name is not spoken here) 翻译成 C,并且由于我想了解它是如何工作的,所以我正在慢慢重写代码并简化它以使用 C 必须提供的所有良好的逻辑结构。
我的代码中不断出现以下小片段,X
和 Y
的值各不相同:
ptr[X]--;
while(ptr[X])
{
ptr[X]--;
ptr += Y;
}
ptr
是 char *
类型,我无法在任何时候对数组的状态做出真正的假设,因为它非常深入地嵌入循环和依赖关于输入和输出。我可以成功地将其“简化”为:
for(ptr[X]--; ptr[X]; ptr[X]--, ptr += Y);
但这太糟糕了。稍微好一点的是:
for(ptr[X]--; ptr[X]; ptr += Y) ptr[X]--;
我想知道是否有人可以对上述代码提出更好的简化,我将不胜感激。这发生在不少于五个地方,并且削弱了我简化和理解流程控制的能力,所以如果有人能提供更简洁/可读性更高的版本,那就太棒了。如果有人能提供对该代码的任何奇特见解,那也太棒了,尽管我基本上理解它的作用。
深入了解特定 X
和/或 Y
的代码也有帮助。 Y
往往介于 -2 和 2 之间,而 X
通常为 1,就其值(value)而言。
最佳答案
ptr[X]
等同于*(ptr + X)
,所以我们可以改写如下:
for((*(ptr + X))--; *(ptr + X); (*(ptr + X))--, ptr += Y);
现在这里有很多冗余,所以我们可以将其简化为:
char *ptr_plus_x = ptr + X;
for((*ptr_plus_x)--; *ptr_plus_x; (*ptr_plus_x)--, ptr_plus_x += Y);
然后我们可以完全摆脱 ptr_plus_x
:
ptr += X;
for((*ptr)--; *ptr; (*ptr)--, ptr += Y);
在英语中,我们访问偏移量为 X、X+Y、X+2Y、X+3Y 的内存位置,递减每个内存位置,直到找到一个为 0 的内存位置。但是,测试因为 0 总是出现在递减之后,所以我们实际上是在寻找该序列中值为 1 的第一个内存位置。一旦找到,我们将其递减为 0 并退出。
如果 Y 为 1,则我们递减一串连续的内存位置,直到并包括第一个 1。如果 Y 为 -1,同样的事情发生,但从偏移量 X 向后搜索。如果 Y 为 0 ,就会出现无限循环。如果 Y 是任何其他值,搜索模式将跳过各种条目。
这不是一个非常直观的函数,所以我明白您为什么会感到困惑。
关于C指针算术片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/851023/