首页 > 编程知识 正文

c语言中strcmp如何使用,c语言strcmp的使用方法

时间:2023-05-04 21:22:11 阅读:265424 作者:1684

1 引言

我发现在开发过程中或者面试过程中经常会遇到这些函数(strcpy,strncpy,strcat,strncat,strcmp,strncmp,strlen,strchrmemset,memcpy),从过往经验来看大部分面试都是不能调用库函数,需要实现函数原型。可见这些函数的底层原理其重要性和作用就不多说了。经过对这些函数的不断研究和验证,下面就一 一详谈这些函数的功能和特性以及函数实现。

2 函数功能及特性 1)strcpy函数

函数原型:char *strcpy(char *dest, const char *src);
函数功能:把从src地址开始且含有NULL结束符的字符串复制到dest开始的地址空间,并且返回指向dest的指针。
函数特性:
(1)、strcpy只能复制字符串,strcpy不需要指定长度,它遇到被复制字符串结束符’’才结束。很容易造成缓冲区溢出。
(2)、src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src所指向的字符串。
(3)、src所指向源字符串参数用const修饰,防止修改源字符串。

2)strncpy函数

函数原型:char *strncpy(char *dest, const char *src, size_t n);
函数功能:把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。
函数特性:
(1)、strncpy只能复制字符串,strncpy需要指定长度,它遇到被复制字符串结束符’’才结束。
(2)、如果n<src的长度,只是将src的前n个字符复制到dest的前n个字符,不自动添加’’,也就是结果dest不包括’’,需要再手动添加一个’’。如果n>src的长度,则以NULL填充dest直到复制完n个字节。
(3)、src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符长度+’’。(4)、src所指向源字符串参数用const修饰,也是防止修改源字符串。

3)strcat函数

函数原型:char *strcat(char *dest, const char *src);
函数功能:把src所指向的字符串复制到dest所指向的字符串后面。要保证dest所指向字符串空间足够长,以容纳被复制进来的src所指向的字符串。src所指向字符串中原有的字符不变。并且返回指向dest的指针。
函数特性:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src所指向的字符串。

4)strncat函数

函数原型:char *strncat(char *dest, const char *src, size_t n);
函数功能:把src所指字符串的前n个字符添加到dest所指字符串的结尾处,并覆盖dest所指字符串结尾的’’。
函数特性:src和dest所指内存区域不可以重叠,并且dest必须有足够的空间来容纳src的字符串。

5)strcmp函数

函数原型:int strcmp(const char *dest, const char *src);
函数功能:比较src和dest所指向的两个字符串并根据比较结果返回整数。
函数特性:
(1)、当dest<src时,返回为负数;当dest=src时,返回值= 0;当dest>src时,返回正数。
(2)、比较规则是两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇’’为止。
(3)、这里面只能比较字符串,即可用于比较两个字符串常量,或比较数组和字符串常量,不能比较数字等其他形式的参数。

6)strncmp函数

函数原型:int strncmp(const char *dest, const char *src, size_t n);
函数功能:把src所指向的前n个字节的字符串与dest所指向的字符串进行比较,若dest与src的前n个字符相同,则返回0;若dest大于src,则返回大于0的值;若dest小于src,则返回小于0的值。
函数特性:
(1)、函数strncmp与函数strcmp极为类似,但功能不完全相同。
(2)、两者不同之处是,strncmp函数是指定比较n个字符,strcmp函数比较整个字符,直到出现不同的字符或遇’’为止。

7)strlen函数

函数原型:size_t strlen(const char *src);
函数功能:计算src所指向字符串的(unsigned int型)长度,不包括’’在内,并且返回src所指向字符串的长度,不包括结束符NULL。
函数特性:
(1)、size_t代表的是unsigned int型。
(2)、该函数从内存的某个位置可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域开始扫描,直到遇到第一个字符串结束符’’为止。

8)strchr函数

函数原型:char *strchr(const char *src, int c);
函数功能:在str所指向的字符串中搜索第一次出现字符c的位置,并且返回一个指向该字符串中第一次出现的字符的指针,如果字符串中不包含该字符则返回NULL空指针。
函数特性:注意strchr函数是区分大小写的。

9)memset函数

函数原型:void* memset(void *src, int c, size_t n);
函数功能:将src中当前位置后面的n个字节用c替换并返回src。
函数特性:
(1)、该函数是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
(2)、memset函数参数中c实际范围应该在0~255,因为该函数只能取c的后八位赋值给你所输入的范围的每个字节。

10)memcpy函数

函数原型:void* memcpy(void *dest, const void *src, size_t n);
函数功能:从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中,src和dest所指内存区域不能重叠,函数返回指向一个目标存储区dest的指针。
函数特性:
(1)、memcpy可以复制任意内容,例如字符数组、整型、结构体、类等而strcpy只能复制字符串。
(2)、需要复制其他类型数据时则一般用memcpy函数,而复制字符串时则一般用strcpy函数。
(3)、strcpy不需要指定长度,它遇到被复制字符的串结束符’’才结束,所以容易溢出。memcpy则是根据第3个参数决定复制的长度。
(4)、src和dest所指的内存区域可能重叠,如果src和dest所指的内存区域重叠,那么memcpy函数并不能够确保src所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域。函数返回指向dest的指针。(memcpy函数在下面的功能实现中是考虑了内存覆盖情况的)

3 函数功能实现 #include <stdio.h>#include <stdlib.h>#include <assert.h>typedef struct _OP{char* (*p_strcpy)(char*, const char*);char* (*p_strncpy)(char*, const char*, size_t);char* (*p_strcat)(char*, const char*);char* (*p_strncat)(char*, const char*, size_t);int (*p_strcmp)(const char*, const char*);int (*p_strncmp)(const char*, const char*, size_t);size_t (*p_strlen)(const char *);char* (*p_strchr)(const char *, int);void* (*p_memset)(void *, int, size_t);void* (*p_memcpy)(void *, const void *, size_t);}OP;char *my_strcpy(char *dest, const char *src){assert((dest != NULL) && (src != NULL));char *temp = dest;while((*dest++ = *src++) != '');return temp;}char *my_strncpy(char *dest, const char *src, size_t n){assert((dest != NULL) && (src != NULL));/*不考虑内存重叠情况*/char *pdest = dest;while(*src != '' && n > 0 ){*dest++ = *src++;--n;}if (n > 0){*pdest = '';}return pdest;}char *my_strcat(char *dest, const char *src){assert((dest != NULL) && (src != NULL));char *pdest = dest;while(*dest != ''){++dest;}while(*src != ''){*dest++ = *src++;}return pdest;}char *my_strncat(char *dest, const char *src, size_t n){assert((dest != NULL) && (src != NULL));char *pdest = dest;while(*dest != ''){++dest;}while(*src != '' && n--){*dest++ = *src++;}*dest = '';return pdest;}int my_strcmp(const char *dest, const char *src){assert((dest != NULL) && (src != NULL));while(*dest && *src && (*dest++ == *src++));return (*dest - *src);}int my_strncmp(const char *dest, const char *src, size_t n){assert((dest != NULL) && (src != NULL));if (!n){return 0;}while(n--){if (*dest == '' || *dest != *src){return *dest - *src;}dest++;src++;}return 0;}size_t my_strlen(const char *src){#if 1/* 非递归 */int len = 0;assert(src != NULL);while(*src++ != ''){++len;}return len;#else/* 递归 */if (src == NULL || *src == ''){return 0;}return my_strlen(src + 1) + 1;#endif}char *my_strchr(const char *src, int c){assert(src != NULL);while(*src != '' && *src != c){++src;}if (*src == c){return (char *)src;}else{return NULL;}}void* my_memset(void *src, int c, size_t n){assert(src != NULL);char *psrc = (char *)src;while((n--) > 0){*psrc++ = n;}return psrc;}void* my_memcpy(void *dest, const void *src, size_t n){assert(dest != NULL && src != NULL);#if 0/* 不考虑内存重叠情况 */char *pdest = dest;const char *psrc = src;if (0 == n){return dest;}while((n--) > 0){*pdest++ = *psrc++;}*(pdest + n) = '';return dest;#else/* 考虑内存重叠情况 */#if 0char *pdest;const char *psrc;if (0 == n){return dest;}if (dest >= (src+n) || dest <= src){pdest = dest;psrc = src;while(n--){*pdest++ = *psrc++;}}else{pdest = (char *)(dest + n - 1);psrc = (char *)(src + n - 1);while(n--){*pdest-- = *psrc--;}}return dest;#elsechar *pdest;const char *psrc;if (0 == n){return dest;}if (dest > src){pdest = (char *)(dest+n-1);psrc = (char *)(src+n-1);while(n >= 4){*pdest-- = *psrc--;*pdest-- = *psrc--;*pdest-- = *psrc--;*pdest-- = *psrc--;n -= 4;}while(n--){*pdest-- = *psrc--;}}else if (dest <= src){pdest = (char *)dest;psrc = (char *)src;while(n >= 4){*pdest++ = *psrc++;*pdest++ = *psrc++;*pdest++ = *psrc++;*pdest++ = *psrc++;n -= 4;}while(n--){*pdest++ = *psrc++;}}return dest;#endif#endif}void init_op(OP *op){op->p_strcpy = my_strcpy;op->p_strncpy = my_strncpy;op->p_strcat = my_strcat;op->p_strncat = my_strncat;op->p_strcmp = my_strcmp;op->p_strncmp = my_strncmp;op->p_strlen = my_strlen;op->p_strchr = my_strchr;op->p_memset = my_memset;op->p_memcpy = my_memcpy;}void my_test(void){char *src = "9876543210";char pdest[11] = {0};char dest[7] = {"abcdef"};char qdest[10] = {0};char *cat = "asdfg";char pcat[20] = {"10010110"};char *ncat = "00111100";char pncat[25] = {"abcdefg"};char *str1 = "ABCDEF G";char *str2 = "ABCDHK L";const char *str = "This is a sample string!";char mset[] = {"01011100 ABCDEF"};char mmcpy[] = {"hello,world!"};OP *op = (OP *)malloc(sizeof(OP));init_op(op);(char *)op->p_memcpy(mmcpy+1, mmcpy, my_strlen(mmcpy)+1);printf("my_strcpy:%stnmy_strncpy:%stn rmy_strcat:%stnmy_strncat:%stn rmy_strcmp:%dtnmy_strncmp:%dtn rmy_strlen:%ldtnmy_strchr:%stn rmy_memset:%stnmy_memcpy:%stn", op->p_strcpy(pdest, src),op->p_strncpy(qdest, dest, 3),op->p_strcat(pcat, cat),op->p_strncat(pncat, ncat, 6),op->p_strcmp(str1, str2),op->p_strncmp(str1, str2, 5),op->p_strlen(str1),op->p_strchr(str, 'a'),(char *)op->p_memset(mset, 0, 3),mmcpy);free(op);op = NULL;}int main(int argc, char const *argv[]){my_test();return 0;} 4 编译

最后在Ubuntu上进行编译,编译结果如下所示:

5 总结

其实这些比较常见常用的函数原理需要我们逐个去理解,多思考,多写程序,多实验,才能在以后的工作或者学习中运用自如,达到事倍功半的效果,如果有需要的朋友可以进行参考。有不足之处还望指出。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。