program story

string :: compare가 int를 반환하는 이유는 무엇입니까?

inputbox 2020. 8. 16. 20:14
반응형

string :: compare가 int를 반환하는 이유는 무엇입니까?


또는 같은 더 작은 유형 대신 string::compare반환 합니까? 내 이해는이 메서드는 -1, 0 또는 1 만 반환한다는 것입니다.intshortchar

두 번째 부분, 유형의 두 개체를 비교하는 비교 메서드를 디자인하고 Foo-1, 0 또는 1 만 반환하려는 경우 사용 short하거나 char일반적으로 좋은 생각일까요?

편집 : 수정되었습니다. string::compare-1, 0 또는 1을 반환하지 않습니다. 실제로 값> 0, <0 또는 0을 반환합니다.

대답은 대략적인 것 같습니다. int반환 값이 "rvalue"이고 해당 "rvalue"가 int 유형 (4 바이트)보다 작다는 이점 없기 때문에 보다 작은 유형을 반환 할 이유가 없습니다 . 또한 많은 사람들은 대부분의 시스템의 레지스터가 int어쨌든 크기가 될 것이라고 지적했습니다. 이 레지스터는 1, 2 또는 4 바이트 값을 제공하든 채워질 것이기 때문에 a를 반환하는 실제 이점은 없습니다. 더 작은 값.

편집 2 : 실제로 정렬, 마스킹 등과 같은 더 작은 데이터 유형을 사용할 때 추가 처리 오버 헤드가있을 수 있습니다. 일반적인 합의는 다음과 같이 많은 데이터로 작업 할 때 메모리를 절약하기 위해 더 작은 데이터 유형이 존재한다는 것입니다. 배열의 경우.

오늘 뭔가를 배웠습니다. 다시 한 번 감사드립니다!


첫째, 사양은 0반드시 -1또는이 아닌 보다 작거나 같거나 큰 값을 반환한다는 것입니다 1. 둘째, 반환 값은 적분 승격이 적용되는 rvalue이므로 더 작은 값을 반환 할 필요가 없습니다.

C ++에서 (C에서와 같이) 모든 표현식은 rvalue 또는 lvalue입니다. 역사적으로 용어는 lvalue가 할당의 왼쪽에 나타나는 사실을 의미하며 rvalue는 오른쪽에만 나타날 수 있습니다. 오늘날, 비 클래스 유형에 대한 간단한 근사값은 lvalue는 메모리에 주소를 가지고 있지만 rvalue는 그렇지 않다는 것입니다. 따라서 rvalue의 주소를 사용할 수 없으며 cv 한정자 ( "액세스"조건)가 적용되지 않습니다. C ++ 용어로 클래스 유형이없는 rvalue는 객체가 아닌 순수한 값입니다. 함수의 반환 값은 참조 유형이없는 경우 rvalue입니다. (레지스터에 맞는 비 클래스 유형은 거의 항상 메모리가 아닌 레지스터에 반환됩니다.)

클래스 유형의 경우 rvalue에 대해 멤버 함수를 호출 있기 때문에 문제가 좀 더 복잡 합니다. 이것은 thiscv-qualification이 오버로드 해결에서 역할을하기 때문에 rvalue는 실제로 포인터에 대한 주소를 가져야 하며 cv-qualified가 될 수 있음을 의미합니다. 마지막으로 C ++ 11은 rvalue 참조를 지원하기 위해 몇 가지 새로운 구별을 도입했습니다. 이것들도 주로 클래스 유형에 적용됩니다.

적분 승격은 an보다 작은 정수 유형 int이 표현식에서 rvalue로 사용될 때 대부분의 컨텍스트에서로 승격 된다는 사실을 의미 합니다 int. 따라서 변수가 선언 된 경우에도 short a, b;표현식 a + b에서 a추가가 발생하기 전에 모두 b승격됩니다 int. 내가 쓰는 경우 마찬가지로 a < 0, 비교는 값에 수행 a로 변환 int. 실제로, 이것이 차이를 만드는 경우는 거의 없습니다. 적어도 정수 산술이 랩핑되는 2의 보수 시스템에서는 (즉, 오늘날 매우 소수의 외래종을 제외하고는 모두 Unisys 메인 프레임이 남은 유일한 예외라고 생각합니다). 여전히 더 일반적인 컴퓨터에서도 :

short a = 1;
std::cout << sizeof( a ) << std::endl;
std::cout << sizeof( a + 0 ) << std::endl;

다른 결과를 제공해야합니다. 첫 번째는에 해당 sizeof( short )하고 두 번째 sizeof( int )는 통합 승격으로 인해 동일 합니다.

이 두 문제는 공식적으로 직교합니다. rvalue와 lvalue는 적분 승격과 관련이 없습니다. 제외 ... 적분 승격은 rvalue에만 적용되며 rvalue를 사용하는 경우 대부분 (전부는 아님)이 적분 승격으로 이어집니다. 따라서보다 작은 값으로 숫자 값을 반환 할 이유가 없습니다 int. 문자 유형으로 반환하지 않는 아주 좋은 이유도 있습니다. 과 같이 오버로드 된 연산자는 <<종종 문자 유형에 대해 다르게 동작하므로 문자를 문자 유형으로 만 반환하려고합니다. (차이점을 비교할 수 있습니다.

char f() { return 'a'; }
std::cout << f() << std::endl;      //  displays "a"
std::cout << f() + 0 << std::endl;  //  displays "97" on my machine

차이점은 두 번째 경우에는 추가로 인해 적분 승격이 발생하여의 다른 과부하 <<가 선택된다는 것입니다.


의도적으로 -1, 0 또는 1을 반환하지 않습니다.

허용합니다 (문자열이 아니라 문자열에도 동일하게 적용됨)

int compare(int *a, int *b)
{
   return *a - *b;
}

다음보다 훨씬 덜 번거 롭습니다.

int compare(int *a, int *b)
{
   if (*a == *b) return 0;
   if (*a > *b) return 1;
   return -1;
}

-1, 0 또는 1을 반환해야한다면 [또는 그 라인을 따라 뭔가]해야 할 일입니다.

또한 더 복잡한 유형에서도 작동합니다.

class Date
{
    int year;
    int month;
    int day;
}

int compare(const Date &a, const Date &b)
{
   if (a.year != b.year) return a.year - b.year;
   if (a.month != b.month) return a.month - b.month;
   return a.day - b.day;
}

문자열의 경우 다음과 같이 할 수 있습니다.

int compare(const std::string& a, const std::string& b)
{
   int len = min(a.length(), b.length());

   for(int i = 0; i < len; i++)
   {
      if (a[i] != b[i]) return a[i] - b[i];
   }
   // We only get here if the string is equal all the way to one of them
   // ends. If the length isn't equal, "longest" wins. 
   return a.length() - b.length();
}

int는 일반적으로 (대부분의 최신 하드웨어에서 의미하는) 시스템 버스 및 / 또는 CPU 레지스터와 같은 크기의 정수이며,이를 기계어라고합니다. 따라서 int는 정렬, 마스킹 및 기타 작업이 필요하지 않기 때문에 일반적으로 더 작은 유형보다 빠르게 전달됩니다.

The smaller types exist mainly to allow RAM usage optimization for arrays and structs. In most cases they trade a few CPU cycles (in the form of aligment operations) for a better RAM usage.

Unless you need to enforce your return value to be a signed or unsigned number of a centain size (char, short…) your are better off using int, which is why the standard library does it.


It's a C-ism.

When C required compare-type functions, they always returned an int. C++ just carried that forward (unfortunately).

However, returning an int is realistically probably the fastest way, as it's generally the size of the registers of the system in use. (Deliberately vague.)


The method doesn't actually return an integer in the set { -1, 0, 1 }; it can actually be any integral value.

Why? The main reason I can think of is that int is supposed to be the "natural size" value for the architecture; operations on values of this size are typically at least as fast (and in many cases faster) than operations on smaller or larger values. So this is a case of allowing the implementation enough slack to use whatever is fastest.


if I was to design a compare method that compares two objects of type Foo and I only wanted to return -1, 0 or 1, would using short or char generally be a good idea?

It would be ok idea. A better way would be to return a bool (if only want to compare if equal), or enum (for more information) :

enum class MyResult
{
  EQUAL,
  LESS,
  GREATER
};

MyResult AreEqual( const Foo &foo1, const Foo & foo2 )
{
  // calculate and return result
}

Suppose some people are changing a code from C to C++. They decided to replace strcmp to string::compare.

Since strcmp returns int, it's easier to string::compare return int, as a gift.


Probably to make it work more like strcmp which also has this set of return values. If you wanted to port code it would probably be more intuitive to have replacements that cleave as close as possible.

Also, the return value is not just -1, 0 or 1 but <0, 0 or >0.

Also, as was mentioned since the return is subject to integral promotion it does not make sense to make it smaller.


because a boolean return value can only be two possible values (true, false), and a compare function can return three possible values (less than, equal, greater than).

Update

While certainly possible to return a signed short, if you really wanted to implement your own compare function, you could return a nibble or struct value with two booleans.

참고URL : https://stackoverflow.com/questions/15338526/why-does-stringcompare-return-an-int

반응형