C语言字符串反转函数

  C语言中所谓的字符串不过是字符数组,后跟一个0x00字符标识结尾,所以反转起来很容易,只要一个循环依次将第一个字符和最后一个字符交换,第二个字符和倒数第二个字符交换……如果最中间有两个字符(即需要反转的字符串长度为偶数),那就交换,如果最中间有一个字符(即需要反转的字符串长度为奇数),那就不需要碰它。还有就是最后一个用来标识字符串结尾的0x00字符不用动它。

  这道题目通常是考察三个方面,一是对指针和字符串的理解,二是是否进行合法性检查,例如输入参数为空指针时是否进行检查,三是返回值是否是恰当,即使你通过参数返回了反转后的字符串指针,也建议在返回值里再返回一下,就像strcpy函数实现的那样。其实还有第四点往往是大家都忽略了的,那就是Unicode问题,如果传入的字符串指针指向的是Unicode字符串,那么反转的时候就不能一个字符一个字符的处理了,不过似乎大多数面试官都没对这一点有过要求,如果你在笔试或面试中遇到这个问题,我建议你想监考或面试官询问一下是否需要考虑Unicode。我面试的时候因为被面试官弄的很紧张,也忘记了这点,写完后检查代码准备交过去时才想起来,索性就当不知道这回事……呵呵。

  有了上面这几点,我们就可以很容易地用C语言写出这个函数了。

 1 char *revstr(char *str, size_t len)
 2 {
 3 
 4     char    *start = str;
 5     char    *end = str + len - 1;
 6     char    ch;
 7 
 8     if (str != NULL)
 9     {
10         while (start < end)
11         {
12             ch = *start;
13             *start++ = *end;
14             *end-- = ch;
15         }
16     }
17     return str;
18 }

代码很简单,就不多介绍了,只是为什么我给这个函数叫revstr而不是strrev呢?我开始时也是给它叫strrev,只是链接时却出错了,这时我才发现VS2005的C++编译器已经在string.h中中提供了一个strrev函数(这看起来并不是C标准库函数,我不知道还有哪些编译器提供了这个函数),如果你安装了crt代码包的话可以找到这个函数的实现。我们来看一下它是如何实现的吧。

 1 char * __cdecl _strrev (
 2         char * string
 3         )
 4 {
 5         char *start = string;
 6         char *left = string;
 7         char ch;
 8 
 9         while (*string++)                 /* find end of string */
10                 ;
11         string -= 2;
12 
13         while (left < string)
14         {
15                 ch = *left;
16                 *left++ = *string;
17                 *string-- = ch;
18         }
19 
20         return(start);
21 }

  这与我上面给出的函数并没有什么本质的不同,只是只传入了一个参数,并没有传入字符串长度,但是我觉得还是传入这个长度比较好,因为有可能我们并不想反转整个字符串,如果采用我给出的那种实现,一个长度为10的字符串,我们只想反转前7个字符也是可以的。还有就是微软给出的这个实现并没有判断是否传入空指针,不过我觉得这并不是个大问题,这要取决于你的具体期望,就像我在启明星辰的笔试中遇到了一道题目,要求我实现一个函数将传入的字符串中的小写字母转换成大写字母,那么如果传入的字符串是小写字母和数字混合的呢?函数应该出错还是应该跳过数字继续处理?两种方式都没错,怎么选择要取决于你或者阅卷人对这个函数的期望,在笔试或面试中你可以询问监考活面试官,如果没有得到准确的描述,你怎么实现都是正确的。

posted @ 2015-03-27 15:47  momo_Unique  阅读(6171)  评论(0编辑  收藏  举报