C语言字符串反转函数

http://www.cnblogs.com/pianoid/archive/2011/10/30/string_reverse_in_c_language.html

找工作前写了篇blog说要做些常见的笔试面试题,像单链表反转啊字符串反转啊之类的题目,但是只写了一篇单链表反转就没再继续写下去,因为觉得实在没什么好写的,不过都是一些简单的指针操作罢了,但是还是有很多新手问这个问题,而且我在腾讯二面的时候也被要求实现这个函数,那我也写一篇blog介绍一下字符串反转吧。

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

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

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

复制代码
char *revstr(char *str, size_t len)
{

char *start = str;
char *end = str + len - 1;
char ch;

if (str != NULL)
{
while (start < end)
{
ch = *start;
*start++ = *end;
*end-- = ch;
}
}
return str;
}
复制代码

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

复制代码
char * __cdecl _strrev (
char * string
)
{
char *start = string;
char *left = string;
char ch;

while (*string++) /* find end of string */
;
string -= 2;

while (left < string)
{
ch = *left;
*left++ = *string;
*string-- = ch;
}

return(start);
}
复制代码

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

 
 
标签: 程序设计
好文要顶 关注我 收藏该文  
3
1
 
 
 
« 上一篇:Windows核心编程读书笔记之chkstk函数(StackCheck函数)
» 下一篇:Windows 7下阻止系统关机
posted @ 2011-10-30 22:05 pianoid 阅读(49867) 评论(7) 编辑 收藏

 
 
#1楼 2011-12-28 15:14 future1023  
弱弱的问一句,如果revstr中的长度len大于str所指字符串长度,调用这个函数会出错吧?
#2楼[楼主] 2011-12-28 16:16 pianoid  
@ future1023
嗯,这样会导致字符串后面的内容被当作字符串反转到'\0'前面,而字符串被反转到'\0'的后面,如果想解决这个问题可以像微软的实现那样在内部通过while循环判断一次字符串长度,如果大于参数len就不进行任何操作返回原始指针,不过这样也不好,毕竟函数看起来是成功返回了,但是却没反转,如果返回NULL或许会更好一些。
#3楼 2013-09-21 21:49 玉皇大亮  
程序有问题啊,*start++ = *end;这步过不去啊
#4楼 2013-11-13 14:30 划根火柴点根烟  
@ 玉皇大亮
你调用错了
#5楼 2015-05-04 17:16 hi all  
@ 玉皇大亮
用数组调用,别用指针。
#6楼 2015-07-02 11:19 小侠女  
@ hi all
什么意思? 我这步也是过不去
#7楼 2016-08-05 18:09 walanwalan  

[/code]
你好,我这个反转为什么会出现乱码?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[code=cpp]
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include <ctype.h>
 
int inverse(char *str1, char *str2)
{
    int length = strlen(str1);
    char *tmp = str1;
    char *p1 = tmp;
    char *p2 = tmp + length - 1;
 
    while (p1 < p2)
    {
        char c = *p1;
        *p1 = *p2;
        *p2 = c;
        ++p1;
        --p2;
    }
    *str2 = tmp;
    return 0;
}
 
 
 
void main()
{
    char buf[] = "abcdefg";
    char buf2[] = { 0 };
    inverse(buf, buf2);
 
    printf("buf2:%s \n", buf2);
 
    printf("hello...\n");
    system("pause");
    return;
 
}

posted on 2017-10-21 15:34  小西红柿  阅读(6448)  评论(0)    收藏  举报

导航