UFO ET IT

부호없는 인덱스로 역방향 'for'루프를 수행하는 가장 좋은 방법은 무엇입니까?

ufoet 2020. 12. 28. 21:44
반응형

부호없는 인덱스로 역방향 'for'루프를 수행하는 가장 좋은 방법은 무엇입니까?


n 번 무언가를 수행하는 역 for 루프 의 첫 번째 시도 는 다음과 같습니다.

for ( unsigned int i = n-1; i >= 0; i-- ) {
    ...     
}

이것은 실패 로 인해 부호 산술 i 따라서 루프 조건이 항상 참이어야한다 항상 크도록 보장 제로 같. 다행히 gcc 컴파일러는 루프가 무한히 실행되는 이유를 궁금해하기 전에 '무의미한 비교'에 대해 경고했습니다.


이 문제를 해결하는 우아한 방법을 찾고 있습니다.

  1. 역방향 for 루프 여야합니다.
  2. 루프 인덱스는 서명되지 않아야합니다.
  3. n은 부호없는 상수입니다.
  4. 부호없는 정수의 '모호한'링 산술을 기반으로해서는 안됩니다.

어떤 아이디어? 감사 :)


어때 :

for (unsigned i = n ; i-- > 0 ; )
{
  // do stuff with i
}

for ( unsigned int loopIndex = n; loopIndex > 0; --loopIndex ) {
    unsigned int i = loopIndex - 1;
    ...
} 

또는

for ( unsigned int loopIndex = 0; loopIndex < n; ++loopIndex ) {
    unsigned int i = n - loopIndex - 1;
    ...
} 

for ( unsigned int i = n; i != 0; i-- ) {
    // do something with i - 1
    ...     
}

C뿐만 아니라 C ++를 사용하는 경우,! =를 사용하는 것은 반복기를 사용하도록 전환 할 때 좋은 습관입니다. 여기서 <= 등을 사용할 수 없습니다.


왜 단순히 :

unsigned int i = n;
while(i--)
{ 
    // use i
}

이것은 질문 본문에 열거 된 모든 요구 사항을 충족합니다. 코드 검토에 실패하거나 코딩 표준을 위반할 가능성이있는 것은 사용하지 않습니다. 내가 볼 수있는 유일한 이의는 OP가 fori = (n-1) .. 0을 생성하는 간단한 방법이 아닌 루프를 고집하는 경우 입니다.


for ( unsigned int i = n; i > 0; i-- ) {
    ...  
    i-1 //wherever you've been using i   
}

나는 사용하는 경향이 있습니다

 for ( unsigned int i = n; i > 0; )  {
    --i;
    ...     
 }

그것은 skizz의 대답과 거의 동일하며 (불필요한 최종 감소를 놓쳤지만 컴파일러는이를 최적화해야합니다) 실제로 코드 검토를 통과합니다. 내가 작업해야했던 모든 코딩 표준에는 조건부 규칙에 돌연변이가 없습니다.


이쪽일까요? IMHO는 명확하고 읽기 쉽습니다. 암시 적으로 알려진 경우 if (n> = 1)을 생략 할 수 있습니다.

if(n>=1) {
    // Start the loop at last index
    unsigned int i = n-1;
    do {
       // a plus: you can use i, not i-1 here
    } while( i-- != 0 );
}

다른 버전 :

if(n>=1) {
    unsigned int i = n;
    do {
       i--;

    } while( i != 0 );
}

if 문이없는 첫 번째 코드는 다음과 같습니다.

unsigned int i = n-1;
do {

} while( i-- != 0 );

for (unsigned int i = n-1; i<(unsigned int)-1; i--)

네, "모호한 링 산술"입니다.


또는 unsigned intn-1에서 0까지 인덱싱이 필요한 경우 래핑 동작에 의존 할 수 있습니다.

for(unsigned int i = n-1; i < n; i--) {
    ...
}

for ( unsigned int i = n; i > 0; i-- ) {
    unsigned int x = i - 1;
    // do whatever you want with x    
}

확실히 우아하지는 않지만 작동합니다.


이 옵션을 언급 한 유일한 이유는 목록에 표시되지 않았기 때문입니다.

for ( unsigned int i = n-1; i < n; i-- ) {
... 
}

완전히 직관에 반하지만 작동합니다. 작동하는 이유는 0에서 1을 빼면 부호없는 정수로 나타낼 수있는 가장 큰 숫자가 생성되기 때문입니다.

일반적으로 나는 특히 빼기를 할 때 부호없는 정수와 아티 메트로 작업하는 것은 좋은 생각이 아니라고 생각합니다.


간단합니다. -1에서 멈추십시오.

for( unsigned int i = n; i != -1; --i )
{
 /* do stuff with i */
}

edit: not sure why this is getting downvoted. it works and it's simpler and more obvious than any of the above.


for ( unsigned int i = n; i > 0; i-- ) {
    ...     
}

Should work fine. If you need to use the i variable as an index into an array do it like this:

array[i-1];

Hm. Here are your options:

  1. Use i=0 as your break condition - Loop will not execute when i reaches 0, so execute 1 iteration of the loop contents for i=0 after the loop has exited.
for ( unsigned int i = n-1; i > 0; i-- ) {
    doStuff(i);
}
doStuff(0);
  1. In the loop, test for i=0 and break out. Not recommended because now you're testing the value of i twice in the loop. Also using break within a loop is generally regarding as bad practice.
for ( unsigned int i = n-1; i >= 0; i-- ) {
    doStuff(i);
    if (i=0) break;
}

unsigned index;
for (unsigned i=0; i<n; i++)
{
    index = n-1 - i; // {i == 0..n-1} => {index == n-1..0}
}

This is untested, but could you do the following:

for (unsigned int i, j = 0; j < n; i = (n - ++j)) {
    /* do stuff with i */
}

Use two variables, one to count up, and the other for the array index:

unsigned int Index = MAX - 1;
unsigned int Counter;
for(Counter = 0; Counter < MAX; Counter++)
{
    // Use Index
    Index--;
}

Since this is not a standard for loop I would probably use a while loop instead, e.g.:

unsigned int i = n - 1;
while (1)
{
    /* do stuff  with i */

     if (i == 0)
    {
        break;
    }
    i--;
}

for ( unsigned int i = n-1; (n-i) >= 0; i-- ) {
    // n-i will be negative when the loop should stop.
    ...     
}

e.z:

#define unsigned signed

for ( unsigned int i = n-1; i >= 0; i-- ) { ... 
}

ReferenceURL : https://stackoverflow.com/questions/665745/whats-the-best-way-to-do-a-reverse-for-loop-with-an-unsigned-index

반응형