728x90

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 에 자세히 나와있다.

 

List<T>.Find(Predicate<T>) 메서드 (System.Collections.Generic)

지정된 조건자에 정의된 조건과 일치하는 요소를 검색하고 전체 List<T>에서 처음으로 검색한 요소를 반환합니다.

docs.microsoft.com

아무튼 C#과 JAVA는 equals를 쓰도록 하자...

이외에도 더 찾아볼만한, 더 알아볼만한 키워드는

  • 박싱과 언박싱
  • Call by reference와 Call by value
  • 오버로딩

정도인 것 같다.

728x90