Арифметический снимок

У меня есть программа, которую я пытаюсь расшифровать. Он переведен на C с другого языка ( имя которого здесь не указано ), и поскольку я хочу понять, как это работает, я медленно переписываю код и упрощаю его, чтобы использовать все полезные логические конструкции, которые C может предложить.

Следующий маленький бит продолжает появляться в моем коде с различными значениями X и Y :

 ptr[X]--; while(ptr[X]) { ptr[X]--; ptr += 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]--; 

Я хочу знать, может ли кто-нибудь придумать лучшее упрощение вышеуказанного кода, я был бы очень признателен. Это происходит не менее чем в пяти местах, и это ухудшает мою способность упрощать и понимать управление streamом, поэтому, если кто-то может предоставить более понятную / удобочитаемую версию, это будет потрясающе. Если кто-то может просто предложить какое-то причудливое понимание этого кода, это тоже будет потрясающе, хотя я в основном понимаю, что он делает.

Также может помочь понимание кода для конкретного X и / или Y Y имеет тенденцию быть между -2 и 2, а X обычно 1, для чего его стоит.

    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, то мы уменьшаем строку последовательных мест памяти, идущих вперед, вплоть до первого включительно. Если Y равно -1, происходит то же самое, но выполняется поиск назад от смещения X. Если Y равно 0, петля. Если Y – любое другое значение, шаблон поиска пропускает различные записи.

    Это не очень интуитивная функция, поэтому я могу понять, почему вы смущены.

    Я заберу:

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

    сначала оценивайте, затем уменьшайте (в то время как условие, то есть)

    Edit: Хорошо, я буду ненавидеть себя утром. Гото, все в порядке на этом уровне, не так ли?

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

    (я честно не знаю, оставить это или нет).

    EDIT2: так, как насчет этого? (tcc не жаловался)

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

    EDIT 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. 

    Веб-сайт для него, который не должен быть назван, гласит:

     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.

    EDIT: Здесь Hello World BF преобразован в C ++.

    Это довольно просто, как есть. Вместо того, чтобы писать меньше заявлений, я скорее попытаюсь понять намерение и добавить комментарий.

    Пример значения «a» fragmentа: уменьшите все элементы столбца (X) матрицы из Y столбцов. Вам понадобится, чтобы нарисовать вертикальную линию + ‘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 ]; } } 

    Удачи 🙂