source

L 또는 UL을 긴 값으로 명시적으로 선언하는 이유는 무엇입니까?

factcode 2022. 8. 14. 11:54
반응형

L 또는 UL을 긴 값으로 명시적으로 선언하는 이유는 무엇입니까?

예로부터

unsigned long x = 12345678UL

위의 예에서 컴파일러는 4바이트(32비트)의 메모리를 설정하기 위해 "긴" 메모리만 표시하면 된다는 것을 항상 알고 있습니다.문제는 L/UL이 길다고 선언한 후에도 긴 상수에 L/UL을 사용해야 하는 이유입니다.

「」의 .L ★★★★★★★★★★★★★★★★★」UL을 사용하다컴파일러는 목록의 상수를 포함할 수 있는 첫 번째 유형을 사용합니다(C99 표준, 절 6.4.4:5 참조).는 is소음음음음음음음음음음음음이다.int,long int,long long int를 참조해 주세요.

따라서 대부분의 경우 접미사를 사용할 필요가 없습니다.프로그램의 의미는 바뀌지 않습니다. 예에서는 '의 않습니다.x에서는 「」, 「」, 「」, 「」, 「」로 수 없는 라도,long long해 주세요.U이치노


프로그래머가 상수의 유형을 명시적으로 설정하고 싶은 몇 가지 상황이 있습니다.예를 들어, 바리어스 함수를 사용하는 경우가 있습니다.

printf("%lld", 1LL); // correct, because 1LL has type long long
printf("%lld", 1);   // undefined behavior, because 1 has type int

접미사를 사용하는 일반적인 이유는 계산 결과가 오버플로하지 않도록 하기 위해서입니다.다음 두 가지 예가 있습니다.

long x = 10000L * 4096L;
unsigned long long y = 1ULL << 36;

예에서이다.int그리고 계산계산은 다음과같이 이루어집니다로 만들어질 것입니다.int. 각 예제에서 이overflow.의 위험이 발생한다.각 예에서 이는 오버플로우의 위험을 초래합니다.그 접미사를 사용하면 계산 이것은 결과에 대한 충분한 항속 거리가 더 큰 형식 대신에 해야 한다는 것을 의미한다.접미사를 사용하는 것은 대신 결과에 충분한 범위가 있는 더 큰 유형으로 계산된다는 것을 의미합니다.

오비트의 라이트니스 레이스(Lightness Races in Orbit)가 말하듯이, 이 리터럴의 접미사는 과제 앞에 있습니다.위의 두 가지 예에서는 단순히 선언을 합니다.x~하듯이로long ★★★★★★★★★★★★★★★★★」y~하듯이로unsigned long long표현 그들에게 할당된 계산에 솟아오르는 만들기에 충분하지 않은가.할당된 식의 계산에서 오버플로를 방지하기에는 충분하지 않습니다.


또 다른 예는 비교 다른예는다음과 같은 비교입니다 또.x < 12U어디 가변 여기서 변수xtype 타입있다 있다int. 없이는 미포함U접미사, 컴파일러가 끊임 없는 접미사,컴파일러는 상수를 입력합니다뿐.12한 로서로int인트츠

int x = -3;
printf("%d\n", x < 12); // prints 1 because it's true that -3 < 12

U에서는, 없는.s, ints, ints, unsigned의 비교가 .인 산술 큰int:" -3 int"로되는 것을 의미합니다.

printf("%d\n", x < 12U); // prints 0 because (unsigned int)-3 is large

사실, 상수의 유형은 "일반적인 산술 변환"이 작동하는 방식 때문에 산술 계산의 결과를 바꿀 수도 있습니다.


10진수의 경우 C99에 의해 제안된 유형 목록은 다음을 포함하지 않습니다.unsigned long longC90에서는 리스트는 당시 가장 큰 표준화된 부호 없는 정수 타입으로 종료되었습니다.unsigned long그 결과 일부 프로그램의 의미가 표준형을 추가함으로써 변경되었다.long longC99에 입력된 것과 동일한 상수unsigned longC90은 이제 서명된 것으로 입력할 수 있습니다.long long대신.나는 이것이 C99에서, 그것이 결정되지 않은 이유라고 믿는다.unsigned long long10진수 유형 목록에 있습니다.예에 대해서는, 이 블로그의 투고를 참조해 주세요.

왜냐하면 숫자 리터럴은 int형이기 때문이다.UL/L은 컴파일러에 int 타입이 아님(예를 들어 32비트 int, 64비트 길이)을 알립니다.

long i = 0xffff;
long j = 0xffffUL;

여기서 오른쪽 값은 부호 있는 긴 길이(32비트 -> 64비트)로 변환해야 합니다.

  1. int인 "0xffffff"는 부호 확장을 사용하여 long으로 변환되어 음수 값(0xffffffff)이 됩니다.
  2. 부호 없는 long인 "0xffffUL"은 long으로 변환되어 양의 값(0x0000fff)이 됩니다.

문제는 L/UL이 길다고 선언한 후에도 긴 상수에 L/UL을 사용해야 하는 이유입니다.

왜냐하면 "after"가 아니라 "before"이기 때문입니다.

먼저 리터럴을 취득한 리터럴을 압축하려는 변수의 유형이 무엇이든 간에 변환됩니다.

그것들은 두 가지 물건이다.타겟의 타입은, 에 의해 지정됩니다.unsigned long워워키이 접미사는 리터럴의 유형을 지정할 수 있는 유일한 방법이기 때문에 소스 유형을 지정합니다.

은, 「 」가 「 」u.

u다음보다 큰 정수 상수를 허용하는 것입니다.LLONG_MAX십진법으로

// Likely to generate a warning.
unsigned long long limit63bit = 18446744073709551615`; // 2^64 - 1

// OK
unsigned long long limit63bit = 18446744073709551615u`;

언급URL : https://stackoverflow.com/questions/13134956/what-is-the-reason-for-explicitly-declaring-l-or-ul-for-long-values

반응형