부호있는 값보다 부호없는 값을 사용하는 경우


81

부호있는 변수보다 부호없는 변수를 사용하는 것이 적절한 때는 언제입니까? 무엇에 대한 for루프?

이에 대해 많은 의견을 듣고 합의와 비슷한 것이 있는지보고 싶었습니다.

for (unsigned int i = 0; i < someThing.length(); i++) {  
    SomeThing var = someThing.at(i);  
    // You get the idea.  
}

저는 Java에 부호없는 값이 없다는 것을 알고 있으며 이는 Sun Microsystems 의 부분 에서 의식적인 결정 이었음에 틀림 없습니다 .


1
나는 이것이 도움이된다는 것을 발견했다 : codemines.blogspot.ca/2007/10/…
mk12

이 질문은 의견에 근거한 것 같습니다. 제시된 코드는 두 경우 모두 잘 실행되므로 둘 다 사용할 수 있습니다. 성능상의 이유를 제외하고 (지금까지 성능과 관련된 대답은 없음) 그것은 단지 개인적인 취향 일뿐입니다.
Trilarion 2014 년

답변:


69

이 주제에 대한 좋은 대화 를 찾게 되어 기뻤습니다 . 전에는 많이 생각하지 않았기 때문입니다.

요약하면 부호는 좋은 일반적인 선택입니다. 모든 숫자가 양수라고 확신 할 때에도 변수에 대해 산술을 수행하려는 경우 (일반적인 for 루프의 경우처럼).

마스크와 같은 비트 단위를 수행하려는 경우 unsigned가 더 의미가 있습니다. 또는 부호 비트를 활용하여 추가 양의 범위를 얻기 위해 필사적 인 경우.

개인적으로 나는 일관성을 유지하고 두 가지 유형을 혼합하는 것을 피할 것이라고 믿지 않기 때문에 서명하는 것을 좋아합니다 (기사에서 경고하는 것처럼).


3
나중에 해당 스레드 unsigned에서 신뢰할 수없는 입력에서 오버플로를 감지 하는 데 훨씬 우수한 것으로 나타났습니다 . 안타깝게도 퍼즐에 대해 제안 된 "답변"은 그다지 훌륭하지 않습니다. 내 것은 template<size_t limit> bool range_check_sum( unsigned a, unsigned b ) { return (a < limit) && (b < limit - a); } 서명 된 유형을 사용하여 비슷하게 간단하고 직접적인 대답이있는 사람 이 있다면보고 싶습니다.
Ben Voigt

10

위의 예에서 'i'가 항상 양수이고 더 높은 범위가 도움이 될 때 unsigned가 유용합니다. 다음과 같이 'declare'문을 사용하는 경우와 같습니다.

#declare BIT1 (unsigned int 1)
#declare BIT32 (unsigned int reallybignumber)

특히 이러한 값이 변경되지 않을 때.

그러나 사람들이 돈에 대해 무책임하고 지속적으로 적자가있는 회계 프로그램을하고 있다면 '서명 됨'을 사용하고 싶을 것입니다.

나는 saint와 동의하지만, 좋은 경험 법칙은 서명을 사용하는 것인데, 실제로 C가 기본값으로 사용하므로 당신은 커버됩니다.


9

비즈니스 사례에서 음수가 유효하지 않다고 명시 하면 오류를 표시하거나 던지고 싶을 것 입니다.

이를 염두에두고 저는 최근에야 바이너리 파일의 데이터를 처리하고 데이터를 데이터베이스에 저장하는 프로젝트에서 작업하는 동안 부호없는 정수에 대해 알게되었습니다. 나는 의도적으로 이진 데이터를 "손상"시켰고 결국 예상 된 오류 대신 음수 값을 얻었습니다. 값이 변환 되었음에도 불구하고 그 값이 내 비즈니스 사례에 유효하지 않음을 발견했습니다.
내 프로그램은 오류가 발생하지 않았고 결국 데이터베이스에 잘못된 데이터를 가져 왔습니다. 내가 사용 uint하고 프로그램이 실패 했다면 더 좋았을 것 입니다.


8

C 및 C ++ 컴파일러는 부호있는 유형과 서명되지 않은 유형을 비교할 때 경고를 생성합니다. 예제 코드에서 루프 변수를 unsigned로 만들 수 없으며 컴파일러가 경고없이 코드를 생성하도록 할 수 없습니다 (경고가 켜져 있다고 가정).

당연히 경고를 끝까지 올린 채 컴파일하고 있지 않습니까?

그리고 한 단계 더 나아 가기 위해 "경고를 오류로 처리"로 컴파일하는 것을 고려해 보셨습니까?

부호있는 숫자를 사용하는 경우의 단점은 예를 들어 0-> n 값이 메뉴 선택이고 -1은 아무것도 선택되지 않았 음을 의미하도록 오버로드하려는 유혹이 있다는 것입니다. 어떤 것이 선택되었는지를 나타내고 다른 것은 그 선택이 무엇인지를 저장합니다. 당신이 알기 전에, 당신은 모든 곳에서 부정적인 것을 테스트하고 있고 컴파일러는 당신이 메뉴 선택의 수와 메뉴 선택을 어떻게 비교하고 싶어하는지에 대해 불평하고 있습니다.하지만 그것은 다른 유형이기 때문에 위험합니다. . 그러지 마십시오.


6

size_t이 경우 또는 size_typeSTL 클래스를 사용하는 경우 종종 좋은 선택입니다 .


바이트 단위의 크기를 다룰 때만.
mk12

@ mk12 표준 라이브러리 컨테이너 size_type는 바이트뿐만 아니라 요소 수에 대한 멤버를 노출합니다 . std::size_t가능한 경우 대신 사용해야 하지만로 시작하는 것이 size_t바이트 만 의미 할 수 있다는 것을 암시하는 것은 정확하지 않습니다 .
underscore_d
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.