一、纯字母数字的字符串逆转
这个练习题已经在最早的练习题里面实现过了,前文参考:链接,我们再来复习一下。
这次通过函数来实现:
void change(char test[]){
int len,i;
char tmp; //定义一个缓存
len = strlen(test); //计算出传递过来的字符串数组的长度
for(i = 0; i < len/2; i++){
tmp = test[i];
test[i] = test[len - 1 - i];
test[len - 1 - i] = tmp; //前后互换
}
}
int main(){
char test[] = "i am eet";
change(test);
printf("%s",test);
return 0;
}
运行结果:
上面是传统的方式,下面我们用指针的方式来实现:
void change(char *s){
int len;
len = strlen(s);
char *p1 = s;
char tmp[len + 1]; //定义一个缓存字符串 +1 是存结束符的
char *p2 = tmp + len; //定义一个指针指向 最后一个位置
*p2 = 0; //结束符0赋值给最后一位
p2 = p2 -1; //指针回退一位,可以合并成 *p2-- = 0;
while(*p1){ //碰到结束符0 ,循环结束
*p2 = *p1; //test的第一个字符赋值给tmp最后一个字符
p1++;
p2--; //可以合并成 *p2 -- = *p1--;
}
strcpy(s,tmp);
}
int main(){
char test[] = "i am eet";
change(test);
printf("%s",test);
return 0;
}
代码实现的结果是一样的。
但是如果字符串是中文的话,上面2个方法都失败,因为一个中文是由2个字节组成,这2个字节是不能对调位置的。
一、中文字符的字符串逆转
修改好代码如下:
void change(unsigned char *s){
int len = strlen(s);
unsigned char *p1 = s;
unsigned char tmp[len + 1]; //定义一个缓存字符串 +1 是存结束符的
unsigned char *p2 = tmp + len; //定义一个指针指向 最后一个位置
*p2-- = 0; //结束符0赋值给最后一位
while(*p1){
if(*p1 <= 127){
*p2-- = *p1++; //++ -- 是后运算
}else{ //超过ASCKii码的值,就是中文了
*(p2 - 1) = *p1++;
*p2 = *p1++;
p2 -= 2; //移动2个位置
}
}
strcpy(s,tmp);
}
int main(){
unsigned char test[] = "我是天才!"; //要用无符号字符
change(test);
printf("%s",test);
return 0;
}
关键要点:
1、关于中文字符,要用无符号字符类型定义,否则会带负数,还是有乱码
2、中文的话,2个字符是一个整体,不能交换,要用点小技巧来实现: *(p2 - 1) = *p1++; *p2 = *p1++; 每次结束后指针移动2个位置: p2 -= 2;