#include <iostream>
#include<string>
using namespace std;
void converse(unsigned char*s) {
int len = strlen((char*)s);
unsigned char temp[1024] = { 0 };
unsigned char* p1 = s;
unsigned char* p2 = temp+len;
*p2-- = 0;
while (*p1) {
if (*p1 < 0x80) {
*p2-- = *p1++;
}
else {
*(p2-1) = *p1++;
*p2 = *p1++;
p2-=2;
}
if (*p1 == 0)break;
}
for (int i = 0; i < len; i++) {
s[i] = temp[i];
}
}
int main() {
unsigned char s[1024] = "我是小萌新";
converse(s);
cout << s;
}
题目详解
本题乍一看好像很简单,我们可以通过定义一个for循环,交换首尾元素实现逆序,这样对于元素是数字或者字母的字符串确实可以,但是要实现中文字符换的逆序的话则会出现很多问题,假如定义一个字符数组char str[ ]="abced";我们交换str[0]和str[ 4],str[1]str3]即可实现,因为字母的字节是1,所以str[0]=a,a[4]=d。但是如果我们定义一个元素为中文的字符数组,char str[ ]=“我是小萌新”。并且输出str[0],就会出现下面的情况.
所以要想实现中文字符串逆序,我们就必须两个字节两个字节的交换。那如何实现呢。
首先中文字符串们最好定义unsigned类型,0x80等于十进制的128,Turbo C中规定对ASCII码值大于0x80的字符将被认为是负数。例如ASCII 值为0x8c的字符, 定义成char时, 被转换成十六进的整数0xff8c 。 这是因当ASCII码值大于0x80时, 该字节的最高位为1, 计算机会认为该数为负数, 对于0x8c表示的数实际上是-74 因此只有定义为unsigned char 0x8c转换成整型数时才是8c。这一点在处理大于0x80的ASCII码字符时(例如汉字码)要特别注意。一般汉字均定义为unsigned char
我们定义两个指针p1,p2,p1指向数组s的首地址,p2指向temp中长度为temp+len的位置,这样p2的长度刚好和数组s相同,作为交换字符换的容器。
这时候我们把s中的我字传给temp,我有两个字节,我们假设为1和2,1和2连起来构成汉字我。所以我们要想实现逆序,就得把这两个字节按1和2的顺序传到temp的末尾,
*p2--=0这行代码是先把temp最后一个元素赋值为0,然后指针向前移动一个字节。
当进入while循环的时候,p2现在指向的是2。
然后我们判断*p1是中文还是英文,如果是因为直接按照一般的方法,将p1直接赋值给p2。
如果是中文,我们让p1赋值给p2-1的位置,然后p1向前移动一个字节,p2向前移动一个字节,将p1赋值给p2。然后p2 向前移动2个字节,重复上面的操作即可。
代码实现就是
while (1) {
if (*p1 < 0x80) {
*p2-- = *p1++;
}
else {
*(p2-1) = *p1++;
*p2 = *p1++;
p2 -=2;
}
if (*p1 == 0)break;
}