2015-04-23 1 views
1

Как я могу переписать следующую программу, чтобы не использовать любые конструкции цикла и ветвления? (Нет, если, в то время, перерыв, продолжать, переключатель, ...)Выполнить цикл x раз без цикла или если операторы

for(int i=0; i < 5; i++){ 
    // do stuff 
} 

Единственный подход, который я могу думать о том, чтобы использовать уродливые заявления GOTO:

loop: 
    // do stuff 
    goto loop; 

Но как я могу выйти из этого цикл после ровно 5 запусков? Или есть другой способ?

Редактировать: Решение не должно быть рекурсивным. Функциональные вызовы еще не разрешены в ходе курса.

+1

Вам понадобится по крайней мере, 'if' с Гото в immitate петлю. –

+0

yes: '// do stuff // do stuff // do stuff // do stuff // do stuff'. Однако точка зрения уклоняется от меня. – amit

+0

Пожалуйста, объясните полезность этого ... Я имею в виду, почему вы НЕ хотите использовать циклы и goto? – unrealsoul007

ответ

1

Вы можете использовать рекурсивную функцию и передать аргумент в качестве счетчика.
Уменьшайте счетчик каждый раз перед вызовом.

int func(int a,int counter) 
{ 
    int c; 


    // .. your logic 
    return counter==0?a:func(a,counter-1);  

} 

Эта линия return counter==0?a:func(a,counter-1); помогает обработке условия, когда counter==0 без использования если.

+0

Извините, я забыл добавить, что рекурсивный вызов не разрешен, так как это должно быть переведено на ассемблер позже, а вызов функции еще не разрешен в задании. – 00FF00FF

+0

Это очень умный, но он не работает. (По крайней мере, в C) 'error: ожидаемое выражение до 'goto'' – 00FF00FF

+0

Да, заметил, что .. goto - это заявление ... поиск альтернативы – Srinath

0

Вы можете использовать цикл Еогеасп:

// An array of ints with 5 values 
int[] someNumbers = new int[] {0, 1, 2, 3, 4}; 

// Then foreach through someNumbers 
foreach (int aNumber in someNumbers) 
{ 
    // Do Stuff 
} 

Это немного рубить, но он будет работать нормально, и если вы хотите сделать someNumbers общественности и положить его в каком-нибудь укромном пространстве в вашем коде, так это не забивает ваш код :).

+0

Это сработало бы, но foreach также является выражением цикла. :( – 00FF00FF

0

Я узнал, что это невозможно. Спасибо за ответы в любом случае!

+0

Да, это так. Посмотрите на мой ответ :) –

0

Если вы используете GCC, вы можете использовать функцию «label as value» (вы также можете сделать similar stuff in other compilers), как это:

#include <stdio.h> 

int main() { 
    int n, v, c; 

    static void* labels[] = {&&nope, &&again}; 

    n = 5; 
    again: 
     printf("stuff\n"); 
     n--; 
     goto *labels[__builtin_popcount(n&-n)];   
    nope: 
     printf("done!\n"); 
    return 0; 
} 

Этот код находит наименьшее множество бит в n (чтобы уменьшить его только один бит, если таковой имеется) и сделать на нем popcount. На практике это вернет 0, если n==0 или 1 в противном случае. Если вы не хотите, чтобы полагаться на __buitin_popcount, вы можете реализовать свой собственный, как это:

int popcount(int v) { 
    int c; 
    c = (v & 0x55555555) + ((v >> 1) & 0x55555555); 
    c = (c & 0x33333333) + ((c >> 2) & 0x33333333); 
    c = (c & 0x0F0F0F0F) + ((c >> 4) & 0x0F0F0F0F); 
    c = (c & 0x00FF00FF) + ((c >> 8) & 0x00FF00FF); 
    c = (c & 0x0000FFFF) + ((c >> 16)& 0x0000FFFF); 
    return c; 
} 
Смежные вопросы