Bỏ qua để đến nội dung

So sánh chuỗi C-style bằng == (sai!)

Với std::string, toán tử == so sánh nội dung của hai chuỗi - đúng như trực giác. Nhưng với chuỗi C-style (char*, const char*), == so sánh địa chỉ, không phải nội dung!

#include <cstring>
#include <iostream>
int main() {
const char* a = "Hello";
const char* b = "Hello";
std::cout << (a == b) << std::endl; // Kết quả KHÔNG XÁC ĐỊNH TRƯỚC - có thể true hoặc false!
return 0;
}

Kết quả phụ thuộc vào việc trình biên dịch có “gộp” hai chuỗi literal giống nhau vào cùng một vùng nhớ hay không (một tối ưu hóa gọi là string interning/pooling) - đây là hành vi do trình biên dịch quyết định, không được chuẩn C++ đảm bảo.

Trường hợp rõ ràng sai: chuỗi được tạo động

Phần tiêu đề “Trường hợp rõ ràng sai: chuỗi được tạo động”
#include <cstring>
#include <iostream>
#include <cstdlib>
int main() {
char* a = strdup("Hello"); // Cấp phát vùng nhớ MỚI, chứa "Hello"
char* b = strdup("Hello"); // Cấp phát vùng nhớ MỚI KHÁC, cũng chứa "Hello"
std::cout << (a == b) << std::endl; // 0 (false) - chắc chắn khác địa chỉ!
std::cout << (strcmp(a, b) == 0) << std::endl; // 1 (true) - nội dung giống nhau
free(a);
free(b);
return 0;
}
#include <cstring>
#include <iostream>
int main() {
const char* a = "Hello";
const char* b = "Hello";
if (strcmp(a, b) == 0) { // strcmp trả về 0 khi hai chuỗi CÓ NỘI DUNG giống nhau
std::cout << "Noi dung giong nhau" << std::endl;
}
return 0;
}

Giải pháp 2: dùng std::string (khuyến nghị)

Phần tiêu đề “Giải pháp 2: dùng std::string (khuyến nghị)”
#include <string>
#include <iostream>
int main() {
std::string a = "Hello";
std::string b = "Hello";
std::cout << (a == b) << std::endl; // 1 (true) - luôn đúng, so sánh theo NỘI DUNG
return 0;
}

Đây là một trong nhiều lý do std::string được khuyến khích dùng thay cho chuỗi C-style trong C++ hiện đại - hành vi của các toán tử luôn đúng như trực giác.

== trên char*/const char* so sánh địa chỉ, không phải nội dung - kết quả có thể không như mong đợi và phụ thuộc vào trình biên dịch.

  • Dùng strcmp(a, b) == 0 để so sánh nội dung chuỗi C-style
  • Dùng std::string để == hoạt động đúng theo nội dung một cách tự nhiên