任务:
将字符串反转,如“1234567890”,反转成“0987654321”
分析:
反转实际上是第一位和最后一位交换:
a[0]=a[9];
a[1]=a[8];
a[2]=a[7];
......
a[5]=a[6];交换完毕,即到中间结束
已知长度len是10
因为第一位i=0与倒数第一位交换,倒数第一位i=9 = 长度len-1
第二位i=1和倒数第二位交换,倒数第二位i=8 = (长度len-1)-1
第三位i=2和倒数第三位交换,倒数第三位i=7 = (长度len-1)-2
也就是从倒数第一位的基础上往前推i位,就是所要交换的位置
推广:a[i]=a[len-1-i]
解答:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char a[] = "1234567890";
int length = 0;
length = strlen(a);
int i = 0;
char temp; //设置中间变量
for (i = 0; i < length/2; i++) //注意循环条件是长度的一半,奇偶数都适用
{
temp = a[i];
a[i] = a[length - 1 - i];
a[length - 1 - i] = temp;
}
printf("%s", a);
return 0;
}
拓展:用指针来解决问题
int main()
{
char a[] = "1234567890";
int len = 0;
char* p = a; // 指针p初始指向字符串首地址(a[0]的位置)/*通过遍历*/
while (*p != '\0')
{
len++;
p++;/*
细节:因为指针 p 在初始化时已经指向了字符串的第一个有效字符(a[0]),所以需要先统计当前指向的字符(len++),再移动指针(p++),才能确保每个字符都被正确计入长度。*/
}
p = a; //将指针p
重新指向字符串首地址/*
为什么不是*p=a,因为*p存的是首地址的值,如果*p=a就是对首地址重新赋值,我们要的是重新指向首地址,因为上面在字符串长度的时候已经偏移了,要重新指向首地址的位置
*/
int i = 0;
char temp;
for (i = 0; i < len/2; i++)
{
temp = *(p+i);
*(p + i) = *(p +len-1- i);
*(p + len - 1 - i) = temp;/*
上面已经提到,可以粗略地理解*p就是首地址,因此:
第一位i=0(也就是*p本身)与倒数第一位交换,倒数第一位i=9 = *p+(长度len-1)
(为什么是*p加,可以理解为从首地址开始往后走,走到倒数第一位停下来)
第二位i=1和倒数第二位交换,倒数第二位i=8 = *p+(长度len-1)-1
(可以理解为从首地址开始往后走,走到倒数第一位停下来,再往前走1位,就是倒数第二位)
第三位i=2和倒数第三位交换,倒数第三位i=7 = *p+(长度len-1)-2
(可以理解为从首地址开始往后走,走到倒数第一位停下来,再往前走2位,就是倒数第三位)
也就是从倒数第一位的基础上走到最后一位再往前走i位,就是所要交换的位置
推广:*(p + i) = *(p +len-1- i)
*/
}
printf("%s", a);
return 0;
}
总结:
着重理解前后交换的原理。