programing

"int"와 "unsigned int"의 진정한 차이

prostudy 2022. 6. 6. 10:35
반응형

"int"와 "unsigned int"의 진정한 차이

int:

32비트 int 데이터 유형에는 -2,147,483,648 ~2,147,483,647 범위의 정수 값을 유지할 수 있습니다.이 데이터 타입을 signed int 또는 signed라고 부를 수도 있습니다.

서명되지 않은 int:

32비트 부호 없는 int 데이터 유형은 0 ~4,294,967,295 범위의 정수 값을 유지할 수 있습니다.이 데이터 유형은 단순히 부호 없음이라고 할 수도 있습니다.

좋아, 하지만 실제로는:

int x = 0xFFFFFFFF;
unsigned int y = 0xFFFFFFFF;
printf("%d, %d, %u, %u", x, y, x, y);
// -1, -1, 4294967295, 4294967295

차이가 없어, 오오 좀 헷갈리네

헤헤. 넌 여기에 암묵적인 캐스팅이 있어. 왜냐면 넌 지금 이 순간을printf어떤 타입을 예상할 수 있는지.

대신 사이즈를 시험해 보십시오.

unsigned int x = 0xFFFFFFFF;
int y = 0xFFFFFFFF;

if (x < 0)
    printf("one\n");
else
    printf("two\n");
if (y < 0)
    printf("three\n");
else
    printf("four\n");

네, 당신의 경우, 그들은 같은 표현을 사용하기 때문입니다.

비트 패턴0xFFFFFFFF는 32b 부호 있는 정수로 해석될 경우 -1로, 32b 부호 없는 정수로 해석될 경우 4294967295로 표시됩니다.

와 같다.char c = 65부호 있는 정수로 해석하면 65입니다.캐릭터로 해석하면a.


R 및 pmg가 지적한 바와 같이 형식 지정자와 일치하지 않는 인수를 전달하는 것은 기술적으로 정의되지 않은 동작입니다.따라서 프로그램은 임의의 값 인쇄부터 크래시, "올바른" 인쇄 등 모든 작업을 수행할 수 있습니다.

표준에서 그것을 지적하고 있다.7.19.6.1-9

변환 지정이 유효하지 않은 경우 동작은 정의되지 않습니다.어떤 인수가 대응하는 변환 사양에 대해 올바른 유형이 아닌 경우, 동작은 정의되지 않습니다.

메모리 및 레지스터에 저장되는 방법에는 차이가 없습니다.int 레지스터에는 서명된 버전과 서명되지 않은 버전이 없습니다.int에 저장된 서명된 정보는 없습니다.이 차이는 연산 실행 시에만 관련이 있습니다.CPU에 내장된 서명된 버전과 서명되지 않은 버전의 연산자가 있습니다.ess는 컴파일러에 사용할 버전을 지정합니다.

문제는 정의되지 않은 동작을 호출했다는 것입니다.


UB를 호출하면 어떤 일이든 발생할 수 있습니다.

할당이 정상입니다. 첫 번째 줄에 암묵적인 변환이 있습니다.

int x = 0xFFFFFFFF;
unsigned int y = 0xFFFFFFFF;

다만, 에의 문의는printf, 이상합니다.

printf("%d, %d, %u, %u", x, y, x, y);

UB는 UB와 일치하지 않습니다.%인수 유형 및 지정자.
이 경우 2를 지정합니다.int및 2unsigned ints는 이 순서로 1을 제공합니다.int1, 1unsigned int1, 1int및 1, 1 1unsigned int.


UB 하지 마!

「 」의 내부 .int ★★★★★★★★★★★★★★★★★」unsigned int똑같아요.

형식의 을 「」에 .printf동일하게 인쇄됩니다.

하지만 비교해보면 차이가 있습니다.고려사항:

int x = 0x7FFFFFFF;
int y = 0xFFFFFFFF;
x < y // false
x > y // true
(unsigned int) x < (unsigned int y) // true
(unsigned int) x > (unsigned int y) // false

부호 있는 정수와 부호 없는 정수를 비교할 때 그 중 하나가 암묵적으로 유형과 일치하도록 캐스트되기 때문에 이는 경고일 수도 있습니다.

는 진짜 차이에 대해 묻고 있다.정의되지 않은 행동에 대해 말할 때 언어 사양이 제공하는 보증 수준입니다. 현실과는 거리가 먼 것입니다.실제의 차이를 이해하려면 , 다음의 스니펫을 확인해 주세요(물론 이것은 UB이지만, 마음에 드는 컴파일러에 완전하게 정의되어 있습니다).

#include <stdio.h>

int main()
{
    int i1 = ~0;
    int i2 = i1 >> 1;
    unsigned u1 = ~0;
    unsigned u2 = u1 >> 1;
    printf("int         : %X -> %X\n", i1, i2);
    printf("unsigned int: %X -> %X\n", u1, u2);
}

이 유형은 비트 패턴이 무엇을 나타내는지 알려 줍니다.그 조각들은 당신이 생각하는 것 뿐이죠.같은 시퀀스를 다른 방법으로 해석할 수 있습니다.

printf함수는 일치하는 위치에서 형식 지정자에 따라 전달한 값을 해석합니다.당신이 말한다면printfint단, , 패스unsigned ★★★★★★★★★★★★★★★★.printf를 다른 것으로 재인쇄하고, 표시되는 결과를 인쇄합니다.

바이너리 표현이 핵심입니다.예:16진수로 부호 없는 int

 0XFFFFFFF = translates to = 1111 1111 1111 1111 1111 1111 1111 1111 

은 ,를 나타냅니다.4,294,967,295열 살하지만 우리는 또한 음수를 나타내는 방법이 필요합니다.2번으로 나누다 맨 11로 이 되면 했습니다.그리고 맨 왼쪽 비트는 0으로 설정되며 숫자는 양수입니다.에는 어떤 이 일어나는지 볼까요?

0000 0000 0000 0000 0000 0000 0000 0011 = 3

우리가 마침내 도달한 숫자에 더해.

0111 1111 1111 1111 1111 1111 1111 1111 = 2,147,483,645

부호 있는 정수를 가진 가장 높은 양의 숫자입니다.1비트를 더합시다(2진수 덧셈은 오버플로를 왼쪽으로 전송합니다.이 경우 모든 비트는 1로 설정되어 있기 때문에 맨 왼쪽 비트에 착지합니다).

1111 1111 1111 1111 1111 1111 1111 1111 = -1

즉, 음수가 허락되지 않는 것이 다른 쪽과 다른 쪽이라고 할 수 있을 것 같습니다.부호 비트 또는 왼쪽 끝 비트 또는 최상위 비트 때문입니다.

언급URL : https://stackoverflow.com/questions/9045436/the-real-difference-between-int-and-unsigned-int

반응형