C指针算术片段

时间:2009-05-12 03:24:49

标签: c pointers while-loop nested-loops

我有一个我正在尝试解码的程序。它被另一种语言(whose name is not spoken here)翻译成C,并且我想了解它是如何工作的,我正在慢慢地重写代码并简化它以使用C提供的所有好的逻辑结构。

我的代码中不断出现以下一点,XY的值不同:

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

4 个答案:

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

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

答案 1 :(得分: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.

答案 2 :(得分:2)

它的网站 - 不可命名的状态:

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似乎相当容易。

编辑: Here is the Hello World BF converted to C++.

答案 3 :(得分: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 ];
    }
}
祝你好运:)