C语言函数_string.h 之 内存comparison函数memcmp

本文详细介绍了memcmp函数的功能、原型、返回值和注意事项,并提供了C语言实现代码及使用示例,帮助开发者正确地使用memcmp函数进行内存比较。

memcmp

原型:

        int memcmp(const void *ptr1, const void*ptr2, unsigned int count);

功能:

        memcmp用于比较内存区域ptr1和ptr2的前count个字节,是按字节进行比较的。

头文件:

        string.h 或 memory.h

返回值:

        < 0 :ptr1和ptr2所指内存中第一个不相等的字节有*((char*)ptr1+x) < *((char*)ptr2+x)
        > 0 :ptr1和ptr2所指内存中第一个不相等的字节有*((char*)ptr1+x) > *((char*)ptr2+x)

        = 0 :ptr1和ptr2所指的内存块中前count个字节都相等

说明:

        1、函数的返回条件是:比较次数达count次或者*((char*)ptr1+x) - *((char*)ptr2+x)的值不为零(即两个块内存中第x字节不相等)。
        2、函数是按字节进行比较的,如果还没有达到上述返回条件,即使遇到'\0'也不会停止比较。而判断规则是按照ASCII码表中字母的顺序进行比较的,即'a'的值为97,'A'的值为65,因此'a'比'A'大。
        3、调用函数时如果参数为结构体,则需要确保结构体中的填充字节被清零。例子:
        typedef struct memcmp_test {
                short data1;
                int data2;
        } memcmp_test_t;
        int main()
        {
                memcmp_test_t test_1 = { 0, 0};
                memcmp_test_t test_2;
                memset( &test_2, 0, sizeof( test_2));
                int judge = memcmp( &test_1, &test_2, sizeof(memcmp_test_t));
                if( 0 == judge)
                        printf("they are equal\n");
                else
                        printf("they are not equal\n");
                return 0;
        }
        在平台windows7 x64上,gcc (GCC) 4.7.2编译后输出结果为: they are equal;
        在平台windows7 x64上,VC++6.0编译运行结果:they are not equal;
        在平台CentOS i386上,gcc(GCC)4.4.7 20120313编译后输出结果为they are not equal;
        解析:出现not equal这种情况,是因为memcmp_test->data1的类型是short而data2的类型是int,由结构体对齐规则知道memcpy_test的每个成员需要按4字节进行对齐,也就data1和data2之间还有两个字节的空间,其值理论上是随机数,因此test_1变量中的内存空间的每个字节不一定为0值,而test_2调用memset函数后确保了其填充字节已被清零,因为便会得到: they are not equal的结果。通过上面运行的结果,我的猜想是:不同的编译器及其版本,对结构体填充字节的赋值是不同的,不过把填充字节的值看作是随机值来处理总没坏处。
        因此,对结构体进行比较的时候,不建议使用字节比较函数如memcmp,如果一定要用,应该确定填充字节被清零,否则结果令你猜不到。

memcmp函数的C语言实现代码:

        /*返回值可能为正数,0,负数三种之一,下面实现采用1表示>, 0表示=, -1表示<*/
        int memcmp(const void *ptr1, const void *ptr2, unsigned int count)
        {
                const char *p1=(char*)ptr1, *p2=(char*)ptr2;
                for( /*NULL*/; 0 < count; count --)
                {
                        if( (*p1 - *p2) < 0)
                                return -1;
                        else if( (*p1 - *p2) > 0)
                                return 1;
                        (char*)p1 ++;
                        (char*)p2 ++;
                }
                return 0;
        }
        例程:
        char buffer1[] = "DWgaOtP12df0";
        char buffer2[] = "DWGAOTP12DF0";
        int res = memcmp(buffer1, buffer2, 16);
        printf("%d\n", res);
        输出结果是:1(因为第三个字母g的ASCII比G的要大)

相关函数:

        strcmp

                函数原型: int strcmp( const char *str1, const char *str2);
                功能:比较两个字符串的大小,str1>str2返回正数,str1=str2返回0,str1<str2返回-1

        strncmp

                函数原型:int strncmp( const char *str1, const char *str2, size_t len)
                功能:比较两个字符串的len个字节,返回值和strcmp一样。
帮我添加一个函数,用于对比与memcpy的时间效率: /* * @Description: Unit test for bulk memory copy. * @Author: liruibo.tp-link.com.hk * @Date: 2025-07-16 17:05:04 * @LastEditors: liruibo.tp-link.com.hk * @LastEditTime: 2025-07-31 15:57:35 */ #include "bulk_mem_copy.h" #include <assert.h> #include <stdlib.h> #include <string.h> void test_normal_copy() { const char src[] = "hello world"; char dest[50] = {0}; bulk_mem_copy((unsigned char*)dest, (unsigned char*)src, strlen(src) + 1); assert(0 == strcmp(dest, src)); printf("[PASS] normal copy test.\n"); } void test_zero_length_copy() { int dest = 42; int src = 0; bulk_mem_copy((unsigned char*)&dest, (unsigned char*)&src, 0); assert(42 == dest); printf("[PASS] zero length copy test.\n"); } void test_overlap_copy() { char data[15] = "AAAAABBBBBCCCCC"; bulk_mem_copy((unsigned char*)data + 5, (unsigned char*)data, 10); assert(0 == strcmp(data, "AAAAAAAAAABBBBB")); printf("[PASS] overlap copy test.\n"); } void test_large_block_copy() { const size_t size = 1024 * 1024 * 10; char* src = malloc(size); char* dest = malloc(size); if (NULL == src || NULL == dest) { printf("[ERROR] large block copy test malloc failed.\n"); exit(EXIT_FAILURE); } memset(src, 0xAA, size); bulk_mem_copy((unsigned char*)dest, (unsigned char*)src, size); assert(0 == memcmp(src, dest, size)); free(src); src = NULL; free(dest); dest = NULL; printf("[PASS] large block copy test.\n"); } int main() { printf("STARTING UNIT TESTS...\n"); test_normal_copy(); test_zero_length_copy(); test_overlap_copy(); test_large_block_copy(); printf("ALL TESTS PASSED!\n"); return 0; }
08-01
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值