먼저 "C Expert 프로그래밍"에서 발췌한 다음 프로그램을 살펴보세요.
#include <stdio.h> int array[] = {23,34,12,17,204,99,16}; #define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0])) int main(void) { int d=-1,x; /*........*/ if(d <= TOTALTOTAL_ELEMENTS - 2) x = array[d+1]; /*........*/ return 0; }
그런 프로그램이 있다면 x의 값이 무엇인지 절대 알 수 없습니다. 문장 할당문 x=array[d+1]; 은 전혀 실행되지 않습니다. 이유는 무엇입니까? 디버깅 후, 프로그램이 판단을 위해 if 문을 실행한 후 바로 다음 문의 실행을 건너뛰는 것으로 나타났습니다. 이유를 아래에서 분석해보자. 타입 크기를 계산할 때 sizeof의 반환 값은 unsigned int 타입이고 d는 signed int이기 때문이다. 문에서 두 가지 크기를 모두 테스트하면 d는 자동으로 unsigned int로 업그레이드되고 -1은 변환된다. unsigned int. 큰 양의 정수이므로 표현식의 값은 항상 false이므로 후속 할당문은 실행되지 않습니다. 이는 유형 변환으로 인해 발생하는 버그입니다. 주의하지 않으면 전체 프로젝트 또는 프로젝트에 예측할 수 없는 결과가 발생할 수 있습니다. 이 버그는 직접 디버깅하기 어렵습니다.
식에서의 유형 변환
유형 변환에는 강제 유형 변환과 암시적 변환이 포함됩니다. 먼저 기존 C(K&R C)의 암시적 유형 변환 규칙을 이해해 보겠습니다.
우선 모든 char 또는 short int 유형 피연산자는 int 유형으로 변환되고 모든 float 유형은 double로 변환됩니다. 유형. . 한 피연산자가 double 유형이면 다른 피연산자도 double로 변환되고 계산 결과도 double입니다. 한 피연산자가 long 유형이면 다른 피연산자도 long 유형으로 변환되며 계산 결과는 다음과 같습니다. also long; 한 피연산자가 부호가 없으면 다른 피연산자도 부호가 없는 것으로 변환되고 계산 결과는 부호가 없습니다.
그러나 새 표준에서는 일부 수정이 이루어졌습니다.
1. 정수 업그레이드: 모든 char, short int 및 bit 필드가 먼저 자동으로 int 또는 unsigned int로 변환됩니다. int가 소스 유형의 모든 값을 나타낼 수 있으면 int로 변환되고, 그렇지 않으면 unsigned int로 변환됩니다.
2. 표현식의 값을 계산할 때 일반적으로 low 유형(표현할 수 있는 데이터의 범위가 작은 데이터 유형)을 먼저 high 유형으로 변환한 후 계산에 참여합니다. 다만 여기서 주의할 점은 표현식에 float 유형이 있다고 해서 계산 전에 반드시 double 유형으로 변환되는 것은 아니라는 점입니다. 다음 코드가 있는 경우:
float f1,f2; double d; f1 = d*f2;
단정밀도를 사용하여 계산하는 경우 최종 결과는 배정밀도 계산과 동일하므로 f2가 변환되지 않을 수 있습니다. 이는 기존 C와 다르지만 현재 이를 지원하는 컴파일러는 거의 없습니다(VC에서는 지원하지 않음).
식에 부호 없는 피연산자와 부호 있는 피연산자가 있는 경우 한 피연산자가 unsigned long int이면 다른 피연산자도 unsigned long int로 변환됩니다. 한 피연산자가 long int이면 다른 피연산자는 unsigned int입니다. . long int가 unsigned int의 표현 범위를 표현할 수 있으면 다른 피연산자는 long int로 변환되고, 그렇지 않으면 두 피연산자는 모두 unsigned long int로 변환됩니다. 서명되지 않은 정수로.
예를 살펴보겠습니다.
int가 16비트이고 long int가 32비트라고 가정합니다.
따라서 -1L
-1L>1UL의 경우 -1L은 signed long int 유형이고 1UL은 unsigned long int 유형이므로 -1L은 unsigned long int로 변환됩니다.