2009-06-04 1 views
3

가능한 중복 : 출력 여기C 매크로 확장 및 정수 연산에 대한 혼란

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

:
A riddle (in C)

나는 다음 코드에 대한 몇 가지 질문을 코드의 배열 요소를 예상대로 인쇄하지 않습니다. 하지만 (int) 요소의 매크로 정의를

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

으로 추가하면 모든 배열 요소가 예상대로 표시됩니다.

  • 이 형식 변환은 어떻게 작동합니까? 이를 바탕으로

나는 몇 가지 질문이있다 : 나는 몇 가지 매크로 정의가있는 경우

  • 그것이 뜻으로 모든 C에서 기본적으로

    #define AA (-64)

, 매크로로 정의 된 상수는 인 경우 부호가있는입니다.

  • 다음, 그래하지만 나는 (내가 UL, UD도 일을 시도 사용할 수있는 것보다 어떤 일정 접미사가 강제로 서명되지 않은 int로서 매크로없이 행동에서 정의 된 일부 일정을해야하는 경우)?

  • 매크로 정의에서 unsigned int로 동작하도록 상수를 정의하려면 어떻게해야합니까?

답변

7

sizeof은 부호없는 형식의 바이트 수를 반환합니다. 그래서 캐스팅이 필요합니다.

더보기 here을 참조하십시오. 이 라인에서

+0

@Skurmedel : 좋습니다. 하지만 만약 내가 매크로를 #define bb (-64 * (sizeof (int)/sizeof (int)) 으로 정의한 다음 bb를 사용하면 부호있는 int로 동작하고, unsigned int로 동작해야한다고 생각합니다. 왜냐하면 bb의 매크로 정의에는 부호있는 int와 부호없는 int의 곱셈이 있으므로 결과는 부호없는 int 여야합니다 (C promotion rules). 내가 잘못되었거나 누락 되었습니까? – goldenmean

+1

C99 표준 (6.3.1.8)에 따라 : 그렇지 않으면 부호있는 정수 유형의 피연산자 유형이 부호가없는 정수 유형을 갖는 피연산자 유형의 모든 값 을 나타낼 수있는 경우 부호없는 정수 유형의 피연산자 부호있는 정수 유형을 갖는 피연산자의 유형으로 변환됩니다. sizeof가 부호있는 int로 표현할 수있는 값으로 부호없는 long을 반환하고 따라서 결과 유형이 서명 된 것 같습니다. – Skurmedel

+0

위 섹션에서는 서명되지 않은 형식의 순위가 서명 된 형식보다 크거나 같은 경우 서명 된 형식이 서명되지 않은 형식으로 변환 될 것이라고 설명합니다. 즉, sizeof가 unsigned int를 반환하는 경우입니다. 그러나 컴파일러는 sizeof return unsigned long을 가질 수 있습니다. – Skurmedel

12

봐 : 첫 번째 반복에서

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

, 당신은 확인된다

-1 <= (TOTAL_ELEMENTS-2) 

(서명되지 않은 값을 반환하고 검사가 실패 size_of 운영자 -1 서명 = 0xFFFFFFFF를가 서명되지 32 비트 머신).

루프의 간단한 변화는 문제를 해결

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

은 다른 질문에 대답하려면 C 매크로 텍스트 현명한 확장된다, 유형의 어떤 개념이 없습니다.C 컴파일러는이 같은 루프를 본다 :

for(d=-1;d <= ((sizeof(array)/sizeof(array[0]))-2);d++) 

매크로에 서명되지 않은 상수를 정의하려면

이 ( unsigned, unsigned long에 대한 ul에 대한 u) 일반적인 접미사를 사용합니다. 귀하의 질문에 대한

#define AA (-64) 

C preprocessorMacro definition and expansion를 참조에 관한

+0

@Miroslav : 매크로에서 부호없는 상수를 정의하는 데 사용 된 접미사는 무엇입니까? – goldenmean

+3

fyi, 반복 및 배열을위한 C 관용구는 다음과 같습니다. int i; for (int i = 0; i plinth

3

:

객체와 같은 매크로는 종래 예를 들어, 상수에 대한 상징적 인 이름을 만들 좋은 프로그래밍 연습의 일환으로 사용되었다

#define PI 3.14159

는 ... 대신에 하나의 코드를 통해 그 숫자를 하드 코딩. 그러나 C와 C++ 모두 const 지시문을 제공합니다. const 지시문은 코드 전체에서 상수를 하드 코딩하지 않기위한 또 다른 방법을 제공합니다.

매크로로 정의 된 상수에는 관련 유형이 없습니다. 가능한 경우 const을 사용하십시오.

1

귀하의 하위 질문 한 응답 :

은 "매크로의 상수를 정의"하기를 (이것은 당신이 단지 일부 텍스트 교체 속임수를 수행하는 "상수"를 정의하지 않는, 약간의 실수입니다 당신이 UNSIGNED_FORTYTWO을 입력 곳

#define UNSIGNED_FORTYTWO 42u 

이는 unsigned int 문자를 삽입합니다 :) 부호입니다, 당신은 'U'접미사를 사용합니다. 이것은 float (즉, "단일 정밀도") 부동를 삽입

#define FLOAT_PI 3.14f 

:

마찬가지로, 당신은 자주 (< math.h 예를 들어 >에서) 정확한 부동 소수점 유형을 설정하는 데 충분 참조 코드에 FLOAT_PI을 입력하면 어디에서나 점으로 구분됩니다.