最近在研究C语言,C语言本身的语法规则,加上它的C89,C99等标准,还是挺复杂的。除了C语言本身外,它的库函数也是必要的组成部分,本文先简单的分析一下string.h中的函数,参考了C99标准。有些函数(比如strtok)我很少用到,后面用到了再填充吧。
1. memcpy:将源buffer内容的开始n个字节复制到目标buffer中,不检查buffer重叠。
2. memmove:和memcpy功能一样,不同的是,要考虑buffer重叠的情况。C99规范中对memmove的解释是,先将源buffer拷贝到一个临时的数组中,然后再从临时数组拷贝到目标buffer中(Copying takes place as if the n characters from the object pointed to by s2 are first copied into a temporary array of n characters that does not overlap the objects pointed to by s1 and s2, and then the n characters from the temporary array are copied into the object pointed to by s1.)。VC中对重叠部分进行了优化,具体参见如下算法:
void * memmove(void * dst, void * src, size_t count) { void * ret = dst; if (dst <= src || dst >= (src + count)) { // 此if分支实际上就是memcpy的算法 /* * Non-Overlapping Buffers * copy from lower addresses to higher addresses */ while (count--) *dst++ = *src++; } else { // 此if分支考虑的是buffer重叠 /* * Overlapping Buffers * copy from higher addresses to lower addresses */ dst += count - 1; src += count - 1; while (count--) *dst-- = *src--; } return ret; }
3. strcpy:以'/0'为结束标志,复制源字符串到目标buffer,不考虑buffer重叠。由于不用考虑重叠,strcpy的算法还是简单的:
char * strcpy (char * dst, char * src) { char * cp = dst; while( *cp++ = *src++ ) ; /* Copy src over dst */ return dst; }
4. strncpy:只拷贝n个字符到目标buffer,如果n小于实际的源字符串长度,不会自动加‘/0’,否则效果同strcpy。strncpy同样不考虑buffer重叠,具体的算法如下:
char * strncpy (char * dest, const char * source, unsigned count) { char *start = dest; while (count && (*dest++ = *source++)) count--; if (count) while (--count) *dest++ = '/0'; return start; }
参考用法:
strncpy(dst, src, MAX_SIZE - 1);
5. strcat:将源字符串连接到目的字符串的后面,不考虑重叠。大致算法如下:
char * mystrcat(char * dest, const char * src) { char * start = dest; while (*dest++) ; dest--; while (*dest++ = *src++) ; return start; }
6. strncat:该函数同strcat,只是限制了最多拷贝n个字符串,若源字符串的实际长度小于等于n,则效果同strcat。该函数的算法如下:
char * strncat (char * front, const char * back, unsigned count) { char *start = front; while (*front++) ; front--; while (count--) if (!(*front++ = *back++)) return(start); *front = '/0'; return start; }
7. memcmp:比较两个字符串的前n个字符,memcmp函数的算法和strcmp差不多。
8. strcmp:比较两个字符串。算法有一点点复杂,具体如下:
int strcmp (char * src, char * dst) { int ret = 0 ; while( ! (ret = *src - *dst) && *dst) ++src, ++dst; if ( ret < 0 ) ret = -1; else if ( ret > 0 ) ret = 1; return ret; }
9. strcoll:该函数可以用来比较本地语言相关的字符,比如按汉字的拼音比较。C99上并未对该部分作深入的介绍。
10. strncmp :比较两个字符串的前n个字符,中间加n的函数和上面的差不多。
11. strxfrm: 和本地语言相关的一个字符串拷贝,类似于strncpy,但是返回的是拷贝的字符个数(不包括'/0')。
12. memchr, strchr : 在内存块或者字符串中定位字符,返回第一个所在的字符的地址。
13. strcspn: 以str1为参照,比较字符串str2中的字符是否与str中某个字符相等(也就是检索str2中的字符是否在str1中存在),如果第一次发现相等,则停止并返回在str1中这个匹配相等的字符的索引值,失败则返回str1的长度。具体用法参见1,就是不知道它用在什么场合下。
14. strpbrk: 比较字符串str1和str2中是否有相同的字符,如果有,则返回该字符在str1中的位置的指针。
15. strrchr:和strchr相同,只是从字符串的末端开始比较。此函数在比较时,包含对‘/0’的比较;
16. strspn: 统计s1中从头开始直到第一个“不来自s2中的字符”出现的长度,返回这个字符的索引。
17. strstr: 和strchr类似,只不过查找的是字符串。
18. strtok: 连续调用,以获得用指定字符隔开的子字符串。
19. memset: 将内存块设置为某个值。
20. strerror: 通过错误号获取错误提示字符串的首地址。
21. strlen: 计算字符串的长度,不包含'/0'。
参考资料:
1. strcspn函数,http://blog.csdn.net/sky2098/archive/2007/03/15/1530607.aspx
2. C99标准