programing

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

prostudy 2022. 8. 27. 08:58
반응형

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

루프를 n번 반복하는 역방향의 첫 번째 시도는 다음과 같습니다.

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

이것은 부호 없는 산술에서 실패한다. i는 항상 0보다 크거나 같음을 보증하기 때문에 루프 조건은 항상 true가 됩니다.다행히 gcc 컴파일러는 왜 루프가 무한히 실행되고 있는지 궁금하기 전에 '무익한 비교'에 대해 경고해 주었습니다.


다음 사항을 염두에 두고 이 문제를 해결할 수 있는 우아한 방법을 찾고 있습니다.

  1. 루프에 대해서는 거꾸로 해야 합니다.
  2. 루프 인덱스는 서명 해제해야 합니다.
  3. n은 부호 없는 상수입니다.
  4. 부호 없는 정수의 'obscure' 링 산술에 기초해서는 안 됩니다.

좋은 생각 있어요?감사합니다:)

그럼 어떻게 해?

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

단순하지 않은 이유:

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

이는 질문 본문에 열거된 모든 요건을 충족합니다.코드 검토에 실패하거나 코드 표준을 위반할 가능성이 있는 것은 사용하지 않습니다.내가 볼 수 있는 유일한 반대는 작전본부가 정말로 그 계획을 고집했느냐는 것이다fori = (n-1)를 생성하는 간단한 방법이 아니라 루프입니다.0.

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;
    ...     
 }

skizz의 답변과 거의 비슷합니다(마지막 불필요한 감소는 누락되지만 컴파일러는 이를 최적화해야 합니다). 실제로 코드 리뷰를 통과합니다.내가 작업해야 했던 모든 코딩 기준은 조건부로 정평이 나있지 않다.

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

네, '오목 링 산술'입니다.

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

C뿐만 아니라 C++를 사용하는 경우, <=> 등을 사용할 수 없는 반복기 사용으로 전환할 때 !=를 사용하는 것이 좋습니다.

천천히 -1에서 멈추세요.

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

edit: 다운 투표의 원인을 알 수 없습니다.위의 어떤 것보다도 간단하고 명확합니다.

e.z:

#define unsigned signed

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

이쪽일까요?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 );

또는 다음 포장의 동작에 의존할 수 있습니다.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을 빼면 부호 없는 정수로 표현될 수 있는 가장 큰 숫자가 생성되기 때문입니다.

일반적으로 부호 없는 정수와 절식을 사용하는 것은 좋지 않다고 생각합니다. 특히 빼기를 할 때 그렇습니다.

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

잘 될 거야.를 사용할 필요가 있는 경우i변수를 배열의 인덱스로서 다음과 같이 수행합니다.

array[i-1];

Hm. 옵션은 다음과 같습니다.

  1. i=0으로서 - 루프는 0이 되지 않으므로 조건의 루프 합니다.i=0루프가 종료된 후.
for ( unsigned int i = n-1; i > 0; i-- ) {
    doStuff(i);
}
doStuff(0);
  1. ""를합니다.i=0 ★★★★★★★★★★★★★★★★★」break이제 루프에서 i의 값을 두 번 테스트하기 때문에 권장하지 않습니다.악습
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}
}

이것은 테스트되지 않았습니다만, 다음의 작업을 실시해 주세요.

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

카운트업 변수와 어레이 인덱스에 변수 두 개를 사용합니다.

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

이것은 루프의 표준이 아니기 때문에 다음과 같이 while loop을 대신 사용할 수 있습니다.

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

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

반응형