Thư viện string.h
cung cấp nhiều hàm hữu ích xử các thao tác xử lý chuỗi và cho nhị phân, tiết kiệm thời gian và tối ưu khi cần xử lý 2 loại dữ liệu này. Bài viết cung cấp cách hiện thực và cách xử dụng các hàm memcmp
, memcpy
và memset
.
void*
Hàm trả về kiểu void
là một hàm không cần trả về giá trị.
Nếu hàm trả về kiểu void*
có nghĩa là hàm có thể thể nhận được giá trị của pointer thuộc bất cứ kiểu dữ liệu nào và sau đó gán ngược lại cho một pointer có kiểu dữ liệu khác, rất tiện lợi khi cần trừu tượng hóa kiểu dữ liệu.
memcmp - memcpy - memset
Hàm memcmp()
Hàm memcmp
so sánh 2 mảng với nhau bằng các byte có cùng vị trí của 2 mảng.
Chỉ cần 1 byte của mảng ptr1[]
lớn hơn byte của mảng pt2[]
có cùng vị trí thì mảng ptr1[]
sẽ được xem là có giá trị lớn hơn mảng ptr2[]
.
Cách so sánh và giá trị trả về.
- Nếu
ptr1[] > ptr2[]
, kết quả trả về là1
- Nếu
ptr1[] < ptr2[]
, kết quả trả về là-1
- Nếu
ptr1[] == ptr2[]
, kết quả trả về là0
int memcmp(const void* ptr1, const void* ptr2, int n) { for (int i = 0; i < n; i++) if (((char*)ptr1)[i] > ((char*)ptr2)[i]) return 1; else if (((char*)ptr1)[i] < ((char*)ptr2)[i]) return -1; return 0; } int main() { char A[] = "StdiO"; char B[] = "StdIo"; int result, n = 5; result = memcmp(A, B, n); return 0; }
Trong hàm này số lượng byte so sánh là tham số n
- Nếu
n = 3
thìresult == 0
vì"Std" = "Std"
. - Nếu
n = 5
thìresult == 1
vì'i' > 'I'
.
Hàm thao tác trên byte nên không có giới hạn về số lượng, nếu n
lớn hơn số byte có trong mảng thì kết quả sẽ bị ảnh hưởng bởi hiệu ứng phụ (không như mong đợi).
Hàm memcpy()
Hàm memcpy
dùng để sao chép n
byte của mảng src[]
qua mảng des[]
.
void memcpy(void* des, const void* src, int n) { for (int i = 0; i < n; i++) ((char*)des)[i] = ((char*)src)[i]; } int main() { char A[10]; char B[] = "Stdio"; int n = 5; memcpy(A, B, n); return 0; }
Hàm memcpy
không quản lí được số lượng byte, nếu mảng des[]
nhỏ hơn mảng src[]
và n
lớn hơn tổng số byte của mảng des[]
thì mảng des[]
sẽ bị tràn dữ liệu.
Nếu n
lớn hơn tổng số byte của mảng src[]
thì mảng des[]
sẽ tạo ra hiệu ứng phụ:
des[]
nhận thêm những giá trị không xác định được.- Crash chương trình.
Hàm memset()
Hàm memset
gán 1 giá trị cho n
byte trong mảng.
void* memset(void *ptr, int value, int n) { for (int i = 0; i < n; i++) ((char*)ptr)[i] = value; } int main() { char A[10]; int val = 1; int n = 10; memcpy(A, val, n); return 0; }
Giá trị của mảng A[]
có giá trị là 1111111111
.
Cho các kiểu khai báo sau:
// VÍ DỤ 1 int main() { short x[2]; int val = 1; x[0] = val; x[1] = val; return 0; } // VÍ DỤ 2 int main() { short x[2]; int val = 1; int n = 2; memset(x, val, n); printf("%d", x[0]); return 0; }
Cách gán biến của VÍ DỤ 1 và VÍ DỤ 2 hoàn toàn khác nhau:
- VÍ DỤ 1:
x[0] == x[1] == 1
- VÍ DỤ 2: hàm
memset
cho từng byte mà kiểushort
gồm có 2 byte nênx[0] == 257
và 2 byte củax[1]
chưa được gán nên không xác định được giá trị.
Vì thế để gán hết byte của mảng thì n == 4
, và khi đó thì x[0] == x[1] == 257
.