前言
上篇文章我们介绍了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;
}
结语
目前来看,这个字符串函数得写三篇文章了,要不然就太长了
下一篇文章会介绍字符串查找函数和错误信息报告函数,我们明天见~