4

我有一个正在尝试解码的程序。它是从另一种语言(这里没有说出它的名字)翻译成 C 语言的,因为我想了解它是如何工作的,所以我正在慢慢地重写代码并简化它以使用 C 必须提供的所有良好的逻辑结构。

以下一点点在我的代码中不断弹出,具有不同的值XY

ptr[X]--;
while(ptr[X])
  {
    ptr[X]--;
    ptr += Y;
  }

ptr是 type 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,因为它的价值。

4

4 回答 4

8

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 是任何其他值,则搜索模式会跳过各种条目。

这不是一个非常直观的功能,所以我明白你为什么感到困惑。

于 2009-05-12T03:56:59.410 回答
3

我会投入:

ptr[X]--
while (ptr[X]--) ptr+=Y;

先求值,再递减(即对于 while 条件)

编辑:好吧,我早上会恨自己。Goto 在这个级别上还可以,对吧?

dec:  ptr[x]--
      while (ptr[X]){
           ptr+=Y;
           goto dec;
      }

(老实说,我不知道是否要离开这个。)

EDIT2:那么,这个怎么样?(tcc没有抱怨)

 while (ptr[X]--?ptr[X]--,ptr+=Y:0){} 

编辑 2 1/2;

  //longshot
  while (ptr[X]--?ptr[X]--,ptr+=Y, ptr[X]:0){} 

如果一切都失败了..

EDIT3:今晚的最后一个。

while (ptr[X]--?ptr[X]--,ptr+=Y:0){
      if (!ptr[X]) break;
 }//good luck with this, it has been very amusing.
于 2009-05-12T03:31:06.597 回答
2

it-which-shall-not-be-named 的网站指出:

The semantics of the it-which-shall-not-be-named states commands can also
be succinctly expressed in terms of C, as follows (assuming that p has 
been previously defined as a char*):

>   becomes     ++p;
<   becomes     --p;
+   becomes     ++*p;
-   becomes     --*p;
.   becomes     putchar(*p);
,   becomes     *p = getchar();
[   becomes     while (*p) {
]   becomes     }

因此,将其转换为 C 似乎应该相当容易。

编辑: 这是转换为 C++ 的 Hello World BF。

于 2009-05-12T04:32:40.397 回答
0

这已经很简单了。与其试图写更少的陈述,我更愿意尝试抓住意图并添加一些评论。

片段的“a”含义示例:减少 Y 列矩阵的列 (X) 的所有元素。例如,在没有直接赋值的语言中,您将需要它来绘制一条垂直线 +'ses。

您可以通过直接显示索引来阐明此含义:

// set elements of column to cGoal
for( int decrementsToGoal = cGoal; decrementsToGoal != 0; --decrementsToGoal ) {
    // decrease all elements of column X
    for( int row = cMaxRows; M[ row*matrixsizeY + columnX ]; --row ) {
        --M[ row*matrixsizeY + columnX ];
    }
}

祝你好运 :)

于 2009-05-12T04:24:03.593 回答