C语言2级难题 求解惑

#inchude<sttdio.h>#inchude<STRING.H>fun(char*w,intn){chart,*s1,*s2;s1=w:s2=w+n-1;whil...  #inchude<sttdio.h>
  #inchude <STRING.H >
  fun(char *w, int n )
  { char t, *s1,*s2;
  s1=w: s2=w+n-1;
  while(s1<S2)
  { t=*s1++;
  *s1=*s2--;
  *s2=t;
  }

}
  main( )
  { char *p;
  p="1234567";
  fun(p,strlen(p));
  puts(p);
  }
答案为什么是
1711717
始终不明白 求解惑
展开
 我来答
百度网友01136f8
2012-11-30 · TA获得超过906个赞
知道小有建树答主
回答量:177
采纳率:0%
帮助的人:185万
展开全部
楼主你好~

首先声明一点,楼主你这个程序运行时是会出错的。原因在最后面说。

然后根据楼主给的代码的期望目的,来分析下:
核心部分就是fun()中的
while(s1<S2)
{
t=*s1++; //(1)

*s1=*s2--; //(2)

*s2=t; // (3)

}
当s1指向的地址小于s2指向的地址时,进行了一次替换操作。
循环1,1234567

进行到(1)时,s1指向'1',t='1',s1自加1,指向'2'(第2位)。此时原始数据1234567。
进行到(2)时,s2指向'7',*s1='7',s2自减1,指向‘6’(第6位)。此时原始数据1734567。
进行到(3)时,s2指向'6',*s2='1'。此时原始数据1734517。
循环2,1734517

进行到(1)时,s1指向'7',t='7',s1自加1,指向'3'(第3位)。此时原始数据1734517。
进行到(2)时,s2指向'1',*s1='1',s2自减1,指向‘5’(第5位)。此时原始数据1714517。
进行到(3)时,s2指向'5',*s2='7'。此时原始数据1714717。
循环3,1714717

进行到(1)时,s1指向'1',t='1',s1自加1,指向'4'(第4位)。此时原始数据1714717。
进行到(2)时,s2指向'7',*s1='7',s2自减1,指向‘7’(第4位)。此时原始数据1717717。
进行到(3)时,s2指向'7',*s2='1'。此时原始数据1711717。
循环4,判断失败,跳出。

最终得到结果1711717

这是这个程序想做到的状态。

但是,这个程序会出错的!
原因在于程序运行到(2)时,试图修改一个常量字符型指针的内容,会报错。
理由在于传入的char* p="123456",这个字符型指针在声明时声称成了字符串,在内存中分配在常量数据区,不能通过*(p+1) = 'a'这样的方式进行修改内容,它是只读的。
注意''单引号表示一个字符,而""双引号表示字符串,'a'与"a"是不同的。
所以当程序想在"1234567"中把第二位的2赋值成第7位的7时,试图修改了常量字符型指针的内容,这就报错了。

而改进方法就是使用字符串的另一种表达,就是将char *p变为char p[7],这样p指向的是这个字符型数组的头元素,而数组声明在内存的栈空间上,是可以改变的:
比如
char p[]="1234567";
p[1] = '7';
第一句声明的时候,事实上右边的"1234567"任然是常量,但是声明是p数组创建了"1234567"的副本,也就是说p实际上是{'1','2','3','4','5','6','7'},当然是可以被改变的。

请追问~
追问
我看懂了 。。。。。可是这是2级题目 应该不会错吧 就是最后一点还是不怎么明白。
追答
肯定是错的咯,2级题错的很多的,楼主你在电脑上实际运行一遍就明白了~
语法上没错,编译也会通过,但是实际运行时就会产生错误的,因为char *隐式声明成的是const,而编译器认为它的是一个字符型指针,赋值号两边类型相同,逻辑上没错。但是事实上字符串是被开辟在内存常量数据区,这里的数据都是不能被改变的,是只读的,只能通过string.h之中声明的函数,或者自己编写的使用构造新字符串+改变指针的方式来变相改变指针指向的字符串。
cqpcy
2012-11-30 · TA获得超过658个赞
知道小有建树答主
回答量:746
采纳率:66%
帮助的人:359万
展开全部
#inchude<sttdio.h>
  #inchude <STRING.H >
  fun(char *w, int n )
  { char t, *s1,*s2;
  s1=w: s2=w+n-1;
  while(s1<S2)
  { t=*s1++; //t=1 s1++
  *s1=*s2--; //s1已经加1了 执行完这句p=17.....
  *s2=t;//s2已经-1了 执行完这句 p = 17....17
  }

}
  main( )
  { char *p;
  p="1234567";
  fun(p,strlen(p));
  puts(p);
  }

同理推出其他错误 是你逻辑有问题
fun(char *w, int n )
  { char t, *s1,*s2;
  s1=w: s2=w+n-1;
  while(s1<S2)
  { t=*s1;
  *s1++ = *s2;
  *s2-- = t;
  }
更多追问追答
追问
2级考试的原题啊。。。。。
追答
那输出1711717 那个就是答案呗,我以为你想把1234567前后交换呢。
现在的2级越来越没营养了,出这种题误导学生有意思么,能不能考点有含量的
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式