2010-06-22 3 views
75

C# 프로그래머는 어디에서나 int를 사용하는 경향이 있으며 드물게 uint에 의지하는 경향이 있습니다. 그러나 저는 왜 그런지에 대한 만족스러운 대답을 결코 발견하지 못했습니다.uint vs int를 사용하여

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

음수 값이 의미가없는 정수가있는 경우 부호없는 정수를 선택합니다.

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

그러나 int 및 unit 유형을 혼합 할 때는 특별한주의와 캐스트가 필요할 것입니다.

더 많은 것을 사용해야합니까? 왜?

+0

http://stackoverflow.com/questions/6301/why-is-array-length-an-int-and-not-an-uint – drharris

+0

나는 단지 deja vu : D, 거의 똑같은 질문을 가졌습니다. 짧은 시간 전에 물었다. – KroaX

+0

하한 검사 (직접 작성해야하는 경우)는 if (i < 0 || i > = length)를 if (unchecked ((uint) i)> length)로 바꿀 수 있습니다. 결과로 나온 일리노이는 한 가지 (지사) 명령을 더 적게 가지며 거의 동일한 성능을 제공합니다 (훨씬 빨라짐). 개인적으로 나는 그것을 좋아한다. 왜냐하면 하한을 점검하는 것에 대한 나의 가려움증을 긁기 때문이다. 다른 사람들은 "확인되지 않음"으로 인해 그것을 반대 할 것 같지만, 나는 이것이 의미를 학습하기에 아주 좋은 선이라고 주장한다. 그 이유는 목적이 무엇인지 간단하고 즉각적으로 분명하므로 독자가 배우는 데 도움이된다. – AnorZaken

답변

47

uint이 BCL에서 사용되지 않는지에 대한 귀하의 관찰은 주된 이유입니다.

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

또한 C#이 사용되는 유일한 언어 일지라도 이것이 C# 개발에서 일반적이지 않은 것으로 의심됩니다. 이는 주로 BCL에서 일반적이지 않기 때문입니다. 개발자는 일반적으로 자신이 구축하고있는 프레임 워크의 스타일을 모방하려고합니다. C#의 경우 공개 및 내부 API를 가능한 한 .NET Framework BCL과 비슷하게 만듭니다. 이것은 uint를 아껴서 사용하는 것을 의미합니다.

+0

http://stackoverflow.com/questions/2013116/should-i-use-uint-in-c-for-values-that-cant-be-negative는 비슷한 주제를 다루는 질문입니다. – Stephan

71

intuint보다 짧습니다.

+2

이것이 진실에 가깝다고 생각합니다. 시간의 99 % (내 경험으로)'int'가 충분할 때'uint'를 사용하는 이유는 무엇입니까? –

+0

그래, 나는'uint '를 사용할 이유가 없었어. 그리고 더 큰 숫자를 저장할 필요가 있다면 나는 단지 'long'을 사용합니다. -1을 오류 또는 기본값으로 사용할 수 있다는 것이 좋습니다. – jjnguy

+12

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

4

나는 음수가 실제로 허용 가능한 값의 범위에 있지 않는 한, uint에서 int까지 선호합니다. 특히 int 매개 변수를 수락하지만 숫자가 0보다 작은 경우 ArgumentException을 던지는 것은 바보입니다. uint을 사용하십시오!

나는 uint이 불충분하다는 데 동의하며 다른 모든 사람들이이를 더 많이 사용하도록 권장합니다.

+7

매우 위험합니다. uints 만 수락하고 범위를 확인하지 않습니다. 누군가가 음수 값을 전달하면 CLR은이 값을 큰 int로 해석합니다. 즉 -1이면 uint.maxvalue가됩니다. 이것은 바람직한 행동이 아닙니다. – Henri

+18

@Henri : C#에서는 int에서 uint 로의 암시 적 변환이 없으므로 "누군가가 음수 값을 전달한 경우"가 없습니다. 물론 상한값에 대한 범위 검사가 여전히 적절합니다 (하지만 이제는 두 가지 대신 하나의 검사 만 필요합니다). –

0

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

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

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

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

+0

게으름에도 불구하고 그것이 게으름이라고 나는 말하지 않을 것입니다. 대부분의 경우, int/uint에 대해 충분히 신경 쓰지 않고, 그러한 결정에 뇌의 순환을 낭비하고, 단지 int로갑니다. 하드웨어가 깔끔하고 프로그래머가 비쌀 수 있습니다. – SWeko

+0

프로그래머가 게으르다. 그것은 나쁜 것입니다. Raymond는 프로그래머가 세금을 싫어한다고 말합니다. – Wizard79

+0

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

12

1) 습관이 잘못되었습니다. 진지하게. C/C++에서도. 일반적인 for 패턴의

생각해은 :

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

절대적이 정수를 사용할 필요가 없습니다. 당신은 결코 음수 값을 갖지 않을 것입니다. 그러나 거의 모든 사람들이 (최소한) 두 가지 다른 "스타일"오류가 있어도 그렇게하는 방식으로 간단한 루프를 수행합니다.

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

0

나는 C가 처음 나왔을 때 대부분의 예제가 간결함을 위해 int을 사용했다고 생각합니다. 우리는 Fortran과 Pascal에서했던 것처럼 integer을 쓰지 않아도 좋았으며, 그 당시 우리는 일상적으로 배열 인덱스와 루프 카운터와 같은 평범한 것들에 대해 일상적으로 사용했습니다. 부호없는 정수는 마지막 여분 비트가 필요한 많은 수의 특수한 경우입니다. C 습관이 C#과 Python과 같은 다른 새로운 언어로 이어지는 것은 자연스러운 진행이라고 생각합니다.

1

int가 거의 100을 넘지 않는 하위 수준의 응용 프로그램 계층에서 프로그램하므로 음수 값이 문제가되지 않습니다 (예 : < myname.length() 유형의 내용). 단지 오래된 C 습관입니다. 상술 한 바와 같이. 그러나 장치에서 이벤트 플래그를 다루는 하드웨어와 인터페이스 할 때 플래그가 가장 왼쪽 비트 (가장 높은 비트)를 사용하는 경우에는 uint가 중요합니다.

정직하게 말하자면, 내 작업의 99.9 %에 대해 쉽게 ushort를 사용할 수 있지만 int는 소리보다 훨씬 좋은 소리입니다.

1

C에서 Direct3D 10 래퍼를 만들었습니다. & 매우 큰 버텍스 버퍼를 만들고 싶다면 uint를 사용해야합니다. 비디오 카드의 큰 버퍼는 부호있는 int로 표현할 수 없습니다.

UINT는 매우 유용합니다. & 다른 말은 바보입니다. 아무도 생각하지 않는다면 아무도 다른 사람을 사용할 필요가 전혀 없기 때문에 아무 것도 생각하지 않을 것입니다.

+0

더 넓은 범위를 활용할 수있는 좋은 사례입니다. –

16

일반적으로 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]); 
    } 
} 
0

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

다른 언어 (예 : C)는 N 비트의 부호없는 유형을 모듈로 2^N을 둘러싼 그룹으로 간주합니다. 그러한 그룹의 구성원에서 N을 빼는 것은 수치 빼기를 나타내지 않고 N이 추가 될 때 원본을 산출하는 그룹 구성원을 산출합니다. 아마도 서명 된 값과 부호없는 값의 혼합을 포함하는 특정 연산은 실제로는 이해할 수 없으며 아마도 금지되어야합니다. 그러나 숫자 리터럴과 같은 사양의 코드는 일반적으로 작동하며 서명 된 코드는 작성되었습니다. 그리고 서명이없는 타입들도 있고, 엉성함에도 불구하고 곧 작동 할 것이고, 스펙은 언제든지 바뀌기 쉽지 않다.

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

0

나는 이것이 아마도 오래된 것임을 알고 있습니다. 스레드를 사용했지만 몇 가지 명확한 설명을 원했습니다.

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

주된 이유는 저장소가 문제가 아니며 다른 소프트웨어, 플러그인, 데이터베이스 또는 Api에서 유연하게 사용할 수 없다는 것입니다. 또한 은행 예를 들어 돈을 저축하기 위해 음수가 필요합니다.

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