前言
上篇文章我们介绍了strlen、strcpy、stract这三个函数,接下来我们会学习新的函数,话不多说,让我们直接开始吧
strcmp
引入:
在进行字符串比较时,不可以直接使用==符号,
这是在比较二者的首字符地址是否相等,
介绍
函数定义:
int strcmp (const char* str1, const char* str2)
传入地址,进行比较
返回值
如果字符串1小于字符串2,返回值小于0
如果字符串1等于字符串2,返回值为0
如果字符串1大于字符串2,返回值大于0
那么比较的是什么呢?字符串长度吗?
我们写段代码来试一试
程序:
int main() { char* p1 = "abcdef"; char* p2 = "qazwsx"; int ret = strcmp(p1, p2); printf("%d\n", ret); return 0; }
输出结果:
很显然,不是长度
比较规则
这里比较的是字符串首字母的ASCII码值,str1的首字符大就返回一个大于0的数,
如果相等,则比较下一个字符,当两个字符串都读取到\0时,函数才返回0
提示
在不同的编译器下,返回值是不同的
在VS下,返回值是-1、1、0
在Linux gcc下,返回值是满足大于0、小于0、等于0
模拟实现
int my_strcmp(const char* s1, const char* s2) { assert(s1 && s2); while (*s1 == *s2) { if (*s1=='\0')//相等 { return 0; } s1++; s2++; } if (*s1 > *s2)//大于 { return 1; } else//小于 { return -1; } }
strncpy、strncat、strncmp
再来看一下文章开头的图片
strcpy、strcat、strcmp都是长度不受限制的函数,都是遇到\0才停止
而这三个函数strncpy、strncat、strncmp,则是长度受限的函数
他们都多了一个num参数,类型是size_t,单位是字节,因为字符串一个元素的大小是1字节,所以此处也可认为是操作元素个数
strncpy操作规则
一般情况
int main() { char arr1[10] = "abcdef"; char arr2[4] = "abq"; strncpy(arr1, arr2, 3); return 0; }
特殊情况
当num参数大于arr2的字节大小时,程序只拷贝过去\0之前的元素,然后多余的元素赋值成\0,如图
strncpy在编译器中的实现
strncat操作规则
特殊说明
下面这段代码,用来研究strncat函数在拷贝时,是否会将\0拷贝过去
int main() { char arr1[30] = "hello\0qqqqqqqqqq"; char arr2[] = "world"; strncat(arr1, arr2, 3); return 0; }
调试结果如下:
由上图可知,在拷贝时,会将\0拷贝在末尾
一般情况
int main() { char arr1[30] = "hello"; char arr2[] = "world"; strncat(arr1, arr2, 3); return 0; }
特殊情况
int main() { char arr1[30] = "hello"; char arr2[] = "world"; strncat(arr1, arr2, 8); return 0; }
调试结果如下:
当num大于arr2的字节大小时,只会拷贝已有的字符和补一个\0,剩下的不补齐
strncpy在编译器中的模拟实现
strncmp操作规则
num是需要比较的字符个数,大小也是字节
返回值类型与strcmp函数相同
一般情况
int main() { const char* p1 = "abcdef"; const char* p2 = "qwerty"; int ret = strncmp(p1, p2, 3); printf("%d\n", ret); return 0; }
strncmp在编译器中的实现
有点长,截图放不下,就贴上代码了
int __cdecl strncmp ( const char *first, const char *last, size_t count ) { size_t x = 0; if (!count) { return 0; } /* * This explicit guard needed to deal correctly with boundary * cases: strings shorter than 4 bytes and strings longer than * UINT_MAX-4 bytes . */ if( count >= 4 ) { /* unroll by four */ for (; x < count-4; x+=4) { first+=4; last +=4; if (*(first-4) == 0 || *(first-4) != *(last-4)) { return(*(unsigned char *)(first-4) - *(unsigned char *)(last-4)); } if (*(first-3) == 0 || *(first-3) != *(last-3)) { return(*(unsigned char *)(first-3) - *(unsigned char *)(last-3)); } if (*(first-2) == 0 || *(first-2) != *(last-2)) { return(*(unsigned char *)(first-2) - *(unsigned char *)(last-2)); } if (*(first-1) == 0 || *(first-1) != *(last-1)) { return(*(unsigned char *)(first-1) - *(unsigned char *)(last-1)); } } } /* residual loop */ for (; x < count; x++) { if (*first == 0 || *first != *last) { return(*(unsigned char *)first - *(unsigned char *)last); } first+=1; last+=1; } return 0; }
结语
目前来看,这个字符串函数得写三篇文章了,要不然就太长了
下一篇文章会介绍字符串查找函数和错误信息报告函数,我们明天见~