我有一个我正在尝试解码的程序。它被另一种语言(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,因为它的价值。
答案 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似乎相当容易。
答案 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 ];
}
}
祝你好运:)