uint 대 int 사용 [닫기]


83

나는 C # 프로그래머가 어디에서나 int를 사용하는 경향이 있으며 거의 ​​uint에 의존하지 않는 경향이 있음을 잠시 관찰했습니다. 그러나 나는 그 이유에 대해 만족스러운 답을 찾지 못했습니다.

상호 운용성이 목표 인 경우 모든 CLI 언어가 부호없는 정수를 지원하는 것은 아니므로 uint가 공용 API에 나타나지 않아야합니다. 그러나 그것은 내부 클래스에서도 int가 왜 그렇게 널리 퍼져 있는지 설명하지 못합니다. 이것이 BCL에서 uint가 드물게 사용되는 이유라고 생각합니다.

C ++에서 음수 값이 의미가없는 정수가 있으면 부호없는 정수를 선택합니다.

이는 음수가 허용되지 않거나 예상되지 않음을 명확하게 나타내며 컴파일러가 일부 검사를 수행합니다. 또한 배열 인덱스의 경우 JIT가 하한 검사를 쉽게 삭제할 수 있다고 생각합니다.

그러나 int 및 unit 유형을 혼합 할 때 추가주의와 캐스트가 필요합니다.

uint를 더 사용해야합니까? 왜?



내가 데자뷰 : D를 가지고 있다는 것을 방금 들었습니다. 거의 똑같은 질문이 얼마 전에 요청되었습니다.
KroaX 2010-06-22

하한 검사에 관해서는 당신을 대체 할 수 있습니다 (경우에 당신은 당신의 자신의를 작성해야합니다) if (i < 0 || i >= length)와 함께 if (unchecked((uint)i) >= length). 결과 IL은 전체적으로 하나의 (분기) 명령어를 가지며 거의 동일한 성능을 제공합니다 (무한히 빠름). 개인적으로 나는 그것이 하한선을 확인하는 것에 대해 내 가려움증을 긁기 때문에 그것을 좋아합니다. 다른 사람들은 "확인되지 않음"으로 인해 그것에 대해 반대 할 가능성이 있지만, 이것이 목적이 무엇인지 문맥에서 즉시 명확하기 때문에 의미를 배우는 데 매우 좋은 라인이라고 주장합니다 = 독자가 배우는 데 도움이됩니다.
AnorZaken 2015

위의 내용은 64 비트와의 비교를 수행하므로 64 비트 빌드에서 최적이라는 것을 언급하는 것을 잊었습니다. 32 비트 빌드의 경우 if (unchecked((uint)i) >= unchecked((uint)length))더 나은 성능을 제공합니다. 그러나 이것은 매우 복잡해 보이며 64 비트 비교는 32 비트 빌드에서 표준 이중 분기 경계 검사보다 여전히 성능이 뛰어나므로 합리적인 상황에서 이것을 권장 할 수 없습니다. (대부분 64 비트 비교가 다른 방법으로 사용된다는 점을 지적하기 위해 언급하고 있습니다. 이는 일부에게 유용한 정보가 될 수 있습니다.)
AnorZaken

여러분, 저는 당신의 기본 의견 기반이 좋지 않다고 주장합니다. 가능한 객관적인 대답이 있다면 나는 그것을 듣고 싶습니다. 나는 이익을 위해 내 관행을 변경합니다.
Joshua

답변:


50

uintBCL에서 사용되지 않는 이유에 대한 귀하의 관찰이 주된 이유라고 생각합니다.

UInt32는 CLS 규격이 아니므로 공용 API에서 사용하기에 완전히 부적절합니다. 비공개 API에서 uint를 사용하려는 경우 이는 다른 유형으로 변환하는 것을 의미하며 일반적으로 유형을 동일하게 유지하는 것이 더 쉽고 안전합니다.

나는 또한 이것이 주로 BCL에서 일반적이지 않기 때문에 C #이 사용되는 유일한 언어 인 경우에도 C # 개발에서 일반적이지 않다고 생각합니다. 일반적으로 개발자는 빌드중인 프레임 워크의 스타일을 (고맙게도) 모방하려고합니다. C #의 경우 이는 API를 공용 및 내부 용으로 최대한 .NET Framework BCL과 비슷하게 보이게 만드는 것을 의미합니다. 이것은 uint를 아껴 사용함을 의미합니다.


1
stackoverflow.com/questions/2013116/...는 질문입니다 비슷한 주제를 다루고
스테판

77

int는보다 입력하기가 더 짧습니다 uint.


2
나는 이것이 진실에 매우 가깝다고 생각합니다. uint99 %의 시간 (내 경험상)으로 int충분할 때 왜 사용 합니까?
Matthew Jones

12
@Justin : -1과 같은 "매직 넘버"는 일반적으로 좋은 생각이 아닙니다. long으로 전환한다는 것은 이유없이 2x 메모리를 사용한다는 것을 의미합니다. 또한 다른 API와 상호 작용할 필요가 없다면 "단위"는 확실히 가치가 있습니다.
Reed Copsey

28
나는 int음수 인덱스를 가지지 않을 것이기 때문에 배열을 인덱싱 하는 데 사용하는 것이 결코 편하지 않습니다. uint이 경우에 a를 사용해야한다는 것이 맹목적으로 분명해 보입니다 .
Mark H

2
말할 것도없이 더 읽기 쉽습니다. 자신보다 경험이 적은 다른 사람이 읽을 수 있도록 코드 / 알고리즘을 전달한 경우, 많이 사용 uint하면 약간 중단 될 수 있습니다. int범위를 제어하는 ​​모든 상황에서 사용할 수 있습니다.
drharris 2010-06-22

3
@MarkH 완전히 동의했지만 역방향 반복을 수행 할 때 다음과 같은 형식으로 유용 할 수 있습니다 for (int i = arr.Length - 1; i >= 0; i--) { }. uint를 사용하면 오버플로 예외가 발생하거나 더 나쁜 경우 무한 루프가 발생합니다.
Aidiakapi

19

일반적으로 int충분합니다. 다음 조건을 모두 충족 할 수 있으면 다음을 사용할 수 있습니다 uint.

  • 공용 API uint용이 아닙니다 (CLS 규격이 아니기 때문에 ).
  • 음수가 필요하지 않습니다.
  • 추가 범위가 필요할 수도 있습니다.
  • 당신은되어 있지 과의 비교에서 사용 < 0이 결코 없기 때문에, true.
  • 당신은되어 있지 과의 비교에서 사용 >= 0이 결코 없기 때문에, false.

마지막 요구 사항은 종종 잊혀지고 버그가 발생합니다.

static void Main(string[] args)
{
    if (args.Length == 0) return;
    uint last = (uint)(args.Length - 1);

    // This will eventually throw an IndexOutOfRangeException:
    for (uint i = last; i >= 0; i--)
    {
        Console.WriteLine(args[i]);
    }
}

13

1) 나쁜 습관. 진지하게. C / C ++에서도.

일반적인 for패턴을 생각해보십시오 .

for( int i=0; i<3; i++ )
    foo(i);

거기에 정수를 사용할 이유가 전혀 없습니다. 음수 값은 없습니다. 그러나 거의 모든 사람들이 (적어도) 두 개의 다른 "스타일"오류가 포함되어 있더라도 간단한 루프를 수행합니다.

2) int기계의 기본 유형으로 인식됩니다.


4

I 선호 uintint음의 수가 허용 가능한 값의 범위 내에 실제로 아니라면. 특히, int매개 변수를 받아들이지 만 ArgumentException숫자가 0보다 작 으면 an을 던지는 것은 어리석은 일입니다 uint.!

나는 그것이 잘 사용되지 않는다는 데 동의하며 uint다른 모든 사람들이 더 많이 사용하도록 권장합니다.


7
단위 만 받아들이고 경계를 확인하지 않는 것은 매우 위험합니다. 누군가 음수 값을 전달하면 CLR은이를 큰 정수로 해석합니다. 즉, -1이면 uint.maxvalue를 얻게됩니다. 이것은 바람직한 행동이 아닙니다.
Henri

19
@Henri : C #은 int에서 uint 로의 암시 적 변환이 없으므로 "누군가가 음수 값을 전달하는 경우"가 없습니다. 물론 상한선에 대한 경계 검사는 여전히 적절합니다 (그러나 이제 두 개가 아닌 하나의 검사 만 필요합니다).
Ben Voigt

1

나는 int가 거의 100을 넘지 않는 낮은 수준의 응용 프로그램 계층에서 프로그래밍하므로 음수 값은 문제가되지 않습니다 (예 : i <myname.length () 유형 항목의 경우). 단지 오래된 C 습관 일 뿐이며 위에서 언급 한대로 입력하는 것이 더 짧습니다. 그러나 어떤 경우에는 장치의 이벤트 플래그를 처리하는 하드웨어에 인터페이스 할 때 플래그가 가장 왼쪽 (가장 높은) 비트를 사용할 수있는 경우 uint가 중요합니다.

솔직히, 내 작업의 99.9 %에 대해 ushort를 쉽게 사용할 수 있었지만 int는 ushort보다 훨씬 더 좋은 소리를냅니다.


1

C #에서 Direct3D 10 래퍼를 만들었으며 매우 큰 정점 버퍼를 만들려면 uint를 사용해야합니다. 비디오 카드의 큰 버퍼는 부호있는 정수로 나타낼 수 없습니다.

UINT는 매우 유용하며 달리 말하는 것은 어리 석습니다. 누군가가 uint를 사용할 필요가 없다고 생각하면 다른 사람이 그렇게 생각하지 않습니다.


더 넓은 범위를 활용할 수있는 좋은 경우입니다.
Leo Gurdian 2017 년

0

그냥 게으름이라고 생각합니다. C #은 본질적으로 리소스가 상대적으로 많은 데스크톱 및 기타 컴퓨터에서 개발하기위한 선택입니다.

그러나 C와 C ++는 메모리가 부족한 오래된 시스템과 임베디드 시스템에 깊은 뿌리를두고 있으므로 프로그래머는 사용할 데이터 유형을 신중하게 생각하는 데 사용됩니다. C # 프로그래머는 게으르고 일반적으로 충분한 리소스가 있기 때문에 아무도 실제로 메모리 사용을 최적화하지 않습니다 (일반적으로 항상 그런 것은 아닙니다). 바이트가 충분하다면 저를 포함한 많은 C # 프로그래머는 단순성을 위해 int를 사용합니다. 또한 많은 API 함수가 int를 허용하므로 캐스팅을 방지합니다.

올바른 데이터 유형을 선택하는 것이 좋은 관행이라는 데 동의하지만 주된 동기는 게으름이라고 생각합니다.

마지막으로 정수를 선택하는 것이 수학적으로 더 정확합니다. 부호없는 정수는 수학에 존재하지 않습니다 (자연수 만). 그리고 대부분의 프로그래머는 수학적 배경을 가지고 있기 때문에 정수를 사용하는 것이 더 자연 스럽습니다.


게으름은 장점이 있지만 게으름이라고 말하지는 않겠습니다. 대부분의 경우, 나는 int / uint에 대해 충분히 신경 쓰지 않고 그러한 결정에 내 두뇌 사이클을 낭비하고 int를 사용합니다. 하드웨어는 삐걱 거리고 프로그래머는 비쌀 수 있습니다.
SWeko 2010-06-22

프로그래머는 게으르다. 그것은 나쁜 일입니다. Raymond는 프로그래머가 세금을내는 것을 싫어한다고 말할 것입니다!
lornova

나는 우리 C # 프로그래머가 게으르다는 것을 처음으로 관리자가 될 것이지만 반드시 나쁜 것은 아닙니다.
ChaosPandion

@Lorenzo, 나는 게으른 프로그래머가 좋은 프로그래머라는 기사를 대학에서 썼다. 대부분 기계 시간 대신 프로그래머 시간을 최적화하는 것이 었습니다.
Eloff

1
흠, 내가 본 (또는 완료) 한 프로그래머 - imputable 버그의 대부분은 ... 게으름에 의해 발생
lornova

0

그 이유의 큰 부분은 C가 처음 나왔을 때 int간결성을 위해 사용 된 대부분의 예제가 나왔기 때문이라고 생각합니다 . 우리는 integerFortran과 Pascal에서했던 것처럼 쓸 필요가 없다는 사실에 기뻐했고 , 그 당시에는 배열 인덱스와 루프 카운터와 같은 일상적인 일에 일상적으로 사용했습니다. 부호없는 정수는 마지막 추가 비트가 필요한 큰 숫자의 특수한 경우였습니다. 나는 C 습관이 C # 및 Python과 같은 다른 새로운 언어로 계속되는 것은 자연스러운 진보라고 생각합니다.


0

일부 언어 (예 : 여러 버전의 Pascal)는 부호없는 유형을 숫자 수량을 나타내는 것으로 간주합니다. 서명되지 않은 유형과 동일한 크기의 서명 된 유형 간의 연산은 일반적으로 피연산자가 다음으로 큰 유형으로 승격 된 것처럼 수행됩니다 (일부 언어에서는 가장 큰 유형에 부호없는 해당 유형이 없으므로 이러한 승격은 항상 가능합니다.) ).

다른 언어 (예 : C)는 N 비트 unsigned 유형을 모듈로 2 ^ N을 감싸는 그룹으로 간주합니다. 그러한 그룹의 구성원에서 N을 빼는 것은 숫자 빼기를 나타내는 것이 아니라 N이 추가 될 때 원본을 산출하는 그룹 구성원을 산출합니다. 틀림없이, 부호있는 값과 부호없는 값의 혼합을 포함하는 특정 작업은 실제로 의미가 없으며 금지되어야 할 수도 있지만 숫자 리터럴과 같은 사양이 엉성한 코드도 일반적으로 작동하며 부호가 혼합 된 코드가 작성되었습니다. 및 서명되지 않은 유형 및 조잡함에도 불구하고 사양이 조만간 변경되지는 않습니다.

서명 된 유형과 서명되지 않은 유형 간의 모든 복잡한 상호 작용을 해결하는 것보다 서명 된 유형으로 독점적으로 작업하는 것이 훨씬 쉽습니다. 부호없는 유형은 작은 조각 (예 : 직렬화)에서 큰 숫자를 분해하거나 이러한 숫자를 재구성 할 때 유용하지만 일반적으로 실제로 수량을 나타내는 항목에는 부호있는 숫자를 사용하는 것이 좋습니다.


0

나는 이것이 아마도 오래된 스레드라는 것을 알고 있지만 약간의 설명을 제공하고 싶었습니다.

-128에서 127까지 저장할 수있는 int8을 가져 와서 총 127 개의 양수인 1 바이트를 사용합니다.
int8을 사용하면 비트 중 하나가 음수 -128에 사용됩니다.
Uint8을 사용할 때 양수에 음수를 부여하여 동일한 양의 저장 공간 1 바이트에 255 개의 양수를 사용할 수 있습니다.
유일한 단점은 이제 음수 값을 사용할 수있는 기능을 상실했다는 것입니다.
이것의 또 다른 문제는 모든 프로그래밍 언어와 데이터베이스가 이것을 지원하는 것은 아닙니다.
제 생각에 이것을 사용하는 유일한 이유는 게임 프로그래밍과 같이 효율적이고 음수가 아닌 큰 숫자를 저장해야 할 때입니다. 이것이 많은 프로그램이 이것을 사용하지 않는 이유입니다.

주된 이유는 스토리지가 문제가 아니며 다른 소프트웨어, 플러그인, 데이터베이스 또는 API와 함께 유연하게 사용할 수 없기 때문입니다. 또한 예를 들어 은행은 돈 등을 저장하기 위해 음수가 필요합니다.

나는 이것이 누군가를 도울 수 있기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.