前言:
接着奏乐接着舞,我们继续来看字符串函数和内存函数。今天要讲的是比较函数大合集,话不多说,开肝!!!
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函数:
代码自取:
#includeint 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辣,到这里比较函数大合集就结束了!
读到就是赚到!希望大家有所收获,我会很开心的(●ˇ∀ˇ●)
青山不改,绿水长流。我们下期再见!!!
还是那句老话:路漫漫其修远兮,吾将上下而求索!!!