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个字符也是可以的。还有就是微软给出的这个实现并没有判断是否传入空指针,不过我觉得这并不是个大问题,这要取决于你的具体期望,就像我在启明星辰的笔试中遇到了一道题目,要求我实现一个函数将传入的字符串中的小写字母转换成大写字母,那么如果传入的字符串是小写字母和数字混合的呢?函数应该出错还是应该跳过数字继续处理?两种方式都没错,怎么选择要取决于你或者阅卷人对这个函数的期望,在笔试或面试中你可以询问监考活面试官,如果没有得到准确的描述,你怎么实现都是正确的。
一、字符串中没有中文时。
char *consver(char *str)
{
if(*str!=‘\0’)
{
char temp;
char *s1 = str;
char *s2 = str+strlen(str)-1;
for(;s1 < s2;s1++,s2--)
{
temp = *s1;
*s1 = *s2;
*s2 = temp;
}
}
return str;
}
测试上面的程序:
int main(int argc,char *argv[])
{
char *str = "abcdefg"; //这里有问题哈,应该改为 char str[ ] ="abcdefg";
char *sdest;
sdest = reconsver(str);
printf("sdest is [%s]\n",sdest);
getch();
return 0;
}
原因就在于 char *str = "abcdefg";这样定义的话,会使得str默认转换为const型,即不允许被修改,故而有错!
改成,char str[] = "abcdefg";就OK了!
方法一样的
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);
}
二、全是中文字符串时
本文
#include<iostream>
using namespace std;
int main()
{
char s[20]="游戏开发";
int i=0,j=strlen(s)-1;
while(i<j)
{
swap(s[i],s[j-1]);
swap(s[i+1],s[j]);
i+=2;
j-=2;
}
cout<<s;
return 0;
}
三、有中文又有英文的字符串
#include <iostream.h>
/* 逆序输出字符串(带中文),递归方式 */
void reverse(char *str)
{
if ( *str == '\0' ) return;
if ( *str < 0 )
{
reverse( str + 2 );
cout<<*str<<(*(str+1));
}
else
{
reverse( str + 1 );
cout << *str;
}
}
void main()
{
char str[] = "AZaz冬天";
reverse(str);
}
来自CSDN博客,转载请标明出处:http://blog.csdn.net/NowDoIT/archive/2011/01/11/6128524.aspx