Nice programing

-1에서 시작하는 루프는 아무것도 인쇄하지 않습니다.

nicepro 2020. 12. 31. 23:28
반응형

-1에서 시작하는 루프는 아무것도 인쇄하지 않습니다.


이 프로그램은의 요소를 인쇄하도록되어 array있지만 실행시 출력이 표시되지 않습니다.

#include <stdio.h>

#define TOTAL_ELEMENTS  (sizeof(array) / sizeof(array[0]))

int array[] = { 23, 34, 12, 17, 204, 99, 16 };

int main() {
    int d;
    for (d = -1; d <= (TOTAL_ELEMENTS - 2); d++) 
        printf("%d\n", array[d + 1]);
    return 0;
}

이 프로그램이 출력을 표시하지 않는 이유는 무엇입니까?


sizeof부호없는 정수를 반환하므로 부호없는 정수도 반환 TOTAL_ELEMENTS됩니다.

d서명되었습니다. 처음에는 d입니다 -1. 비교를 수행 할 때 그러나, d더 이상 그래서, 암시 적 부호에 형태 캐스트 없다 -1에 비교되는 경우 TOTAL_ELEMENTS가 실제로, UINT_MAX(어떤 4294967295내 컴퓨터에 있지만, 다른 사람과 다를 수 있습니다).

또한,

이 문제를 해결 TOTAL_ELEMENTS하려면 int다음 을 입력하십시오 .

for(d = -1; d <= (int)(TOTAL_ELEMENTS - 2); d++) 

다음과 같이 인쇄됩니다.

23
34
12
17
204
99
16

예상대로. 부호없는 비교 항목에 대한 자세한 내용은 부호없는 정수와 부호있는 정수에 대한 비교 연산 을 참조 할 수도 있습니다 .

컴파일러 경고를 켜면 무슨 일이 일어나고 있는지 파악하는 데 도움이되었을 것입니다 (hyde의 의견 에서 관찰 됨 ).

$ gcc -Wall -Wextra test.c
test.c:7:17: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
      for(d = 0; d < TOTAL_ELEMENTS; d++) 
              ~ ^ ~~~~~~~~~~~~~~
1 warning generated.

또는 시작 d하고 대신 0실행 하지 않는 이유는 TOTAL_ELEMENTS - 1무엇입니까? 의 코너 케이스에만 필요한 typecast를 삭제할 수도 있습니다 d = -1.

for(d = 0; d < TOTAL_ELEMENTS; d++) 
    printf("%d\n", array[d]);

다음은 관련 C99 표준 발췌 부분입니다.

  1. 6.3.1.8p2 는 부호있는 유형에서 부호없는 유형으로의 변환을 정의합니다.

    부호없는 정수 유형을 가진 피연산자가 다른 피연산자의 유형 순위보다 크거나 같은 순위를 갖는 경우 부호있는 정수 유형을 가진 피연산자는 부호없는 정수 유형을 가진 피연산자의 유형으로 변환됩니다.

  2. 6.3.1.3p2 는 변환이 수행되는 방법을 정의합니다 UINT_MAX + 1. 서명 된 표현에 추가 합니다.

    새 유형이 부호없는 경우 값이 새 유형의 범위에있을 때까지 새 유형에서 나타낼 수있는 최대 값보다 하나 더 많은 값을 반복적으로 더하거나 빼서 값을 변환합니다.

    그래서 -1=> -1 + (UINT_MAX + 1)= UINT_MAX,이 시나리오.


내 gcc는 다음 경고를 출력합니다.

warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
      for(d = 0; d < TOTAL_ELEMENTS; d++) 

해당하는 수단 (TOTAL_ELEMENTS-2)unsigned int상태 d이다 signed int. 이것은 , 이후 false의 초기 값에 대한 표현식을 항상 만듭니다 .d(unsigned int)(-1) > (TOTAL_ELEMENTS-2)


서로 다른 정수 유형 간의 이진 연산은 소위 일반적인 산술 변환으로 정의 된 "공통"유형 내에서 수행됩니다. 따라서 int d는 값 -1로 초기화 된 singed 유형입니다. unsigned int로 변환하면 TOTAL_ELEMENTS가 반환 한 값보다 훨씬 큰 unsigned int의 최대 값이 반환됩니다.

ReferenceURL : https://stackoverflow.com/questions/45657517/loop-starting-at-1-doesnt-print-anything

반응형