Search…

Hiện Thực và Sử Dụng Hàm memcmp - memcpy - memset Trong C/C++

Shiro NguyễnShiro Nguyễn
04/09/20203 min read
Hướng dẫn hiện thực hàm memcpy, memcpy, memset và sử dụng các hàm trong thư viện C string.h.

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, memcpymemset.

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"Std" = "Std".
  • Nếu n = 5 thì result == 1'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[]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ểu short gồm có 2 byte nên x[0] == 257 và 2 byte của x[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.

IO Stream

IO Stream Co., Ltd

developer@iostream.co
383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024