std::string::compare 함수
// string
int compare (const string& str) const noexcept;
// substrings
int compare (size_t pos, size_t len, const string& str) const;
int compare (size_t pos, size_t len, const string& str,
size_t subpos, size_t sublen = npos) const;
// c-string
int compare (const char* s) const;
int compare (size_t pos, size_t len, const char* s) const;
// buffer
int compare (size_t pos, size_t len, const char* s, size_t n) const;
string, substring, c-string, buffer에 사용할 수 있는 함수들이 오버로딩되어 있다.
파라미터는 비교할 문자열인 str, 비교될 문자열의 첫번째 문자 pos, 길이 len 등등이 있다.
Return value는 다음과 같다.
Value | 비교 관계 |
0 | 두 문자열이 같다. |
<0 | 일치하지 않는 첫 번째 문자의 값이 비교할 문자열의 값보다 더 낮다. 또는 모든 문자가 일치하지만 비교할 문자열이 더 짧다. |
>0 | 일치하지 않는 첫 번째 문자의 값이 비교할 문자열의 값보다 더 크다. 또는 모든 문자가 일치하지만 비교할 문자열이 더 길다. |
==operator는 단순히 같음만 비교하고 bool값을 반환하는 것에 비해 compare함수는 substring비교도 가능하고 반환값도 경우에 따라 나눠져있는 것을 알 수 있다. 사실 두 문자열을 비교하는 경우만 봤을때는 거의 같다고 볼 수 있다.
스택오버플로우의 어떤 글에 의하면 디버그 빌드에서 compare함수가 어셈블리어 코드 수가 더 적다곤 하는데 릴리즈 빌드에선 별 차이 없으니 성능도 동일하다고 볼 수 있다.
결론은 단순히 두 문자열을 비교할땐 동일하다. 대신 compare는 경우에 따라 반환 값을 사용할 수 있다는 점, substr 비교에 사용할 수 있다는 점 정도?
이외에도 strcmp가 있긴하다.
번외: C#과 JAVA에서
사실 이 글을 쓴 것은 이것때문이다.
JAVA에서는 문자열 비교시 ==를 쓰지 않고 equals를 쓰라고 한다. 왜일까?
String a = "A";
String b = "A";
String c = new String("A");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // true
System.out.println(a == c); // false
System.out.println(a.equals(c)); // true
왜냐하면 ==는 동일한 주소를 참조하고 있는지 비교하기 때문이다. 반면 equals는 값을 비교한다. a와 b는 리터럴 A를 동일하게 가리키고 있고 c는 새롭게 생성된 문자열을 가리키고 있기 때문에 이런 결과값이 나온 것이다.
C#의 경우는 어떨까? C#은 다행히도 연산자 오버로딩을 통해서 ==로 문자열 값을 비교하게 되어있다. 즉 ==를 해도 equals연산을 수행하는 것과 같다.
하지만 이 경우에도 주의해야할 점이 있는데, 먼저 알아야둬야 할 것은... C#에서는 모든 객체의 상위 클래스가 object라는 클래스이다. 쉽게 말해 어떤 클래스를 만들어도 암시적으로 object의 상속을 받는다. object의 ==는 참조값을 비교하기 때문에 string의 ==와는 다르다. 따라서 string을 object로 형 변환(박싱)하게되면 문자열 비교 시 ==가 아닌 equals를 사용해야한다.
사실 이런 경우가 거의 없겠지만... 한번 그런적이 있다. LinQ를 사용해서 List에서 특정 문자열을 멤버로 가진 객체가 있는지 찾는 경우였다. ==로 비교하면 당연히 주소값은 다 다르니 false를 반환하는데, 그것도 모르고 왜 문자열값은 다 같은데 자꾸 false인가 싶어 한참 헤맸던 적이 있다.
관련 예제는 https://docs.microsoft.com/ko-kr/dotnet/api/system.collections.generic.list-1.find?view=net-6.0 에 자세히 나와있다.
아무튼 C#과 JAVA는 equals를 쓰도록 하자...
이외에도 더 찾아볼만한, 더 알아볼만한 키워드는
- 박싱과 언박싱
- Call by reference와 Call by value
- 오버로딩
정도인 것 같다.