前言:

接着奏乐接着舞,我们继续来看字符串函数和内存函数。今天要讲的是比较函数大合集,话不多说,开肝!!!

strcmp函数:

什么是strcmp函数?

strcmp即string compare,翻译过来就是字符串比较。顾名思义就是用来比较字符串大小的函数。

它的返回类型是int,当前者大于后者返回1,前者等于后者返回0,前者小于后者返回-1.参数有2个,一个源头字符串,一个目标字符串。因为仅仅对二者进行比较并不对其进行修改,所以用const修饰防止其被更改。它的头文件是string.h。

strcmp函数如何使用?

看实操:

strcmp的进阶知识:

1.关于字符串的比较

在C语言中,两个字符串是没办法直接进行比较的。就比如上面就是个错误示范,字符串"abcdefg"或者arr1/arr2都等于字符串首元素地址,那显然两个地址不相同,所以输出不等于。在这种情况下就得使用strcmp函数进行比较。

而在这个例子中,却相等了。原因是因为p,q两个都是常量字符串,p,q都指向同一块内存(abcdefg的地址),地址自然相同。所以等于。

2.strcmp的返回值

通过上面的例子我们知道两个字符串相等时,返回值是0.那么如果不相等,返回值是什么呢?

谁长谁就大吗?

通过以上例子,我们可以发现strcmp的比较并非是谁长谁就大那么简单。而是取决于第一个不同的字符的大小。

结论strcmp本质上比较的是第一位不同位的ASCII码值大小。

例如两个字符串A,B。若所有对应字符都相同,则strcmp(A,B)=0,若第一位不同位的ASCII码值,A大于B,那么无论B后面多长,都返回1。反之返回-1.

就像上面最后一个例子,虽然arr2仅仅是c\0,但strcmp(arr1,arr2)=-1。

自定义strcmp函数:

代码自取:

int my_strcmp(const char* str1,const char* str2)
{
    assert(str1 && str2);//防止str1和str2存在空指针的情况
    while (*str1 == *str2)
    {
        if (*str1 == '\0')//两个指针都遇到\0了还没跳出循环,说明两个字符串都相等
        {
            return 0;
        }
        str1++;
        str2++;
    }
    if (*str1 > *str2)//在遇到第一位不同位时跳出循环,所以可以直接比较*str1和*str2
    {
        return 1;
    }
    else
    {
        return -1;
    }
}

strncmp函数:

什么是strncmp函数?

strncmp的返回值和strcmp一样,但参数多了个n。它与strcmp的关系就像strncpy和strcpy函数之间的关系一样,都是多了个n来控制字节数。自然而然,strncmp是用来比较两个字符串前n个字节(前n个字符,因为字符类型大小是1个字节在32位编译器中)的大小。头文件同样是string.h

strncmp函数如何使用?

看实例:

特殊情况:

如果要比较的字节数超出了其中一个字符串长度呢?

当要比较的字节数超出了字符串长度时,在一个字节一个字节比较过程中遇到\0(无论是谁的),就会停止比较。在上面两个例子中第一个为1是因为0的ASCII码值大于\0的ASCII码值。

自定义strncmp函数:

代码自取:

int my_strncmp(const char* str1, const char* str2, size_t num)
{
    int n = 1;
    while (*str1 == *str2)
    {
        if (*str1 == 0 || n == num)
        {
            return 0;
        }
        str1++;
        str2++;
        n++;
    }
    if (*str1 > *str2)
    {
        return 1;
    }
    else
    {
        return -1;
    }
}

其中原理和strcmp函数的自定义很像,无非就加了个n控制比较的次数。

memcmp函数:

什么是memcmp函数?

strcmp只能比较字符串数据,局限性比较大。所以在比较其他数据时,我们使用memcmp函数。

memcmp,即memory compare,翻译过来就是内存比较。他的返回类型时int,有3个参数,buf1,buf2为void*类型是因为定义函数的人并不知道使用者用它来比较什么样的数据,所以定义为void*来接受。memcmp函数同样采用了count来控制比较的字节数。头文件是memory.h或者string.h

memcmp函数如何使用?

老样子,纸上谈兵是不行的,看实操:

memcmp进阶知识:

1.memcmp的比较方式和strcmp一样吗?

明显不一样,例一中看起来好像和strcmp一样,第一位不同位刚好2<1输出-1,但在例二中第一位不同位即1048592明显大于4112,理论上应该输出1但是却输出了-1,这是为什么呢?

解析:

结论:

memcmp和strcmp比较的内核都是第一位不同位(按一个字节一个字节比较),而非第一位不同元素。

2.如果比较整形数据时,比较的字节不是数据的整形倍呢?

在此程序中我们比较arr1,arr2的21个字节,但仍然输出了1,这是为什么?

解析:

结论:所以在使用memcmp函数对于超过一个字节的数据比较时,要格外注意小端存储模式还是大端存储模式。

3.memcmp在比较时的字节数超过了某一个内存块时会怎样?

因为arr2只有4个字节的大小,让它和arr1比较20字节显然不够,所以系统会报警告。虽然比较出来也是-1,但是这样做十分不安全。

结论:

在使用memcmp函数时,要注意比较的字节数不可超出比较内存的大小。

自定义memcmp函数:

代码自取:

#include<assert.h>
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
    assert(ptr1 && ptr2);
    //强制类型转化
    char* ptr11 = (char*)ptr1;
    char* ptr22 = (char*)ptr2;
    while (*ptr11 == *ptr22 && num--) 
    {
        ptr11++;
        ptr22++;
    }
    if (*ptr11 > *ptr22)
    {
        return 1;
    }
    else if (*ptr11 < *ptr22)
    {
        return -1;
    }
    return 0;
}

既然要一个字节一个字节比较,那么我们直接给他强制类型转换成char*类型的,从而实现一个字节一个字节比较。

结语:

总结:对于字符数据比较时,用strcmp和strncmp,专业对口。其他用memcmp。

ok辣,到这里比较函数大合集就结束了!

读到就是赚到!希望大家有所收获,我会很开心的(●ˇ∀ˇ●)

青山不改,绿水长流。我们下期再见!!!

还是那句老话:路漫漫其修远兮,吾将上下而求索!!!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐