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
始终不明白 求解惑 展开
#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
始终不明白 求解惑 展开
展开全部
楼主你好~
首先声明一点,楼主你这个程序运行时是会出错的。原因在最后面说。
然后根据楼主给的代码的期望目的,来分析下:
核心部分就是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'},当然是可以被改变的。
请追问~
首先声明一点,楼主你这个程序运行时是会出错的。原因在最后面说。
然后根据楼主给的代码的期望目的,来分析下:
核心部分就是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之中声明的函数,或者自己编写的使用构造新字符串+改变指针的方式来变相改变指针指向的字符串。
展开全部
#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;
}
#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级越来越没营养了,出这种题误导学生有意思么,能不能考点有含量的
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |