免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3642 | 回复: 8
打印 上一主题 下一主题

[C] 关于 while(*p1++ == *p2 ++) 的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-10 13:05 |只看该作者 |倒序浏览
最近在写一个程序,其中用到了
while(*p1++ == *p2 ++)
      ;
这样的语句。(其中 p1和p2都为指向char型的指针)

问题是:
编译的时候没有错误,但运行时出现错误。VC6.0和Borland的BCC55都是如此。
但如果改成下面的形式就没有任何问题:
                     while(*p1== *p2)
                {
                        p1++;
                        p2++;
                }

望高手给解释一下,谢谢了。

论坛徽章:
0
2 [报告]
发表于 2008-12-10 13:21 |只看该作者
你觉得两者是一样的?
如果你while后要用p1,p2,前者比后者多执行了一遍++.

论坛徽章:
1
2017金鸡报晓
日期:2017-01-10 15:19:56
3 [报告]
发表于 2008-12-10 13:21 |只看该作者
你确认你改成:

但如果改成下面的形式就没有任何问题:
                     while(*p1== *p2)
                {
                        p1++;
                        p2++;
                }


就没有问题吗?

好像是访问越界吧

论坛徽章:
0
4 [报告]
发表于 2008-12-10 13:24 |只看该作者
原帖由 wzw19191 于 2008-12-10 13:05 发表
最近在写一个程序,其中用到了
while(*p1++ == *p2 ++)
      ;
这样的语句。(其中 p1和p2都为指向char型的指针)

问题是:
编译的时候没有错误,但运行时出现错误。VC6.0和Borland的BCC55都是如此。 ...

我的没有问题啊。
运行环境WindowsServer2003SP1+VC6.0
#include <iostream>
using namespace std;
int main()
{
&nbsp;&nbsp;char *p1 = "ABCD";
&nbsp;&nbsp;char *p2 = "ABC";
&nbsp;&nbsp;while(*p1++ == *p2++)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;  cout<<"good"<<endl;
&nbsp;&nbsp;&nbsp;&nbsp;  //p1++;

&nbsp;&nbsp;&nbsp;&nbsp;  //p2++;

&nbsp;&nbsp;}

&nbsp;&nbsp;return 0;
}

论坛徽章:
0
5 [报告]
发表于 2008-12-10 13:29 |只看该作者
原帖由 wzw19191 于 2008-12-10 13:05 发表
最近在写一个程序,其中用到了
while(*p1++ == *p2 ++)
      ;
这样的语句。(其中 p1和p2都为指向char型的指针)

问题是:
编译的时候没有错误,但运行时出现错误。VC6.0和Borland的BCC55都是如此。 ...

你能说说你两个指针都指向的是什么吗?

论坛徽章:
1
2017金鸡报晓
日期:2017-01-10 15:19:56
6 [报告]
发表于 2008-12-10 13:32 |只看该作者
两个指针指向同一块内存地址应该会有问题!

论坛徽章:
0
7 [报告]
发表于 2008-12-10 13:54 |只看该作者
原帖由 xujg 于 2008-12-10 13:21 发表
你觉得两者是一样的?
如果你while后要用p1,p2,前者比后者多执行了一遍++.


同上
我觉得是没问题,至少问题不是出在++的写法上,应该是越界
char s1[]="abcdefghi",s2[]="abcdefghi";
char *p1,*p2;
int i=0;
p1=&s1;
p2=&s2;
while((*p1++==*p2++)&(i<5))   i++;
printf("p1=%s,p2=%s;\n",p1,p2);

p1=ghi,p2=ghi


char s1[]="abcdefghi",s2[]="abcdefghi";
char *p1,*p2;
int i=0;
p1=&s1;
p2=&s2;
while((*p1==*p2)&(i<5))  {p1++;p2++; i++;}
printf("p1=%s,p2=%s;\n",p1,p2);

p1=fghi,p2=fghi

前者在判断循环条件时,还要走一遍。

论坛徽章:
0
8 [报告]
发表于 2008-12-10 14:28 |只看该作者
谢谢各位的回复了。
问题搞清楚了。

原程序是这样的,是一个将字符串反转,但给定的子串部分不反转。
例如:给定字符串为 "This is a test",子串为 "This",那么反转后
应该是 "tset a si This"。

源程序如下:
#include <stdio.h>

void ReverseStr(char *str, char *substr)
{
        char *p1 = str, *start = str, *end, *p2 = substr;
        char temp;
       
        while(*start != '\0')
        {
                while(*p1 == *p2)
                {
                        p1++;
                        p2++;
                }

                if(*p2 == '\0')
                {
                        end = p1 - 1;
                        while(start < end)
                        {
                                temp = (*start);
                                *start++ = (*end);
                                *end-- = temp;
                        }
                       
                        start = p1;
                        p2 = substr;
                }
                else
                {
                        p2 = substr;
                        p1 = ++start;
                }
        }
       
        end = start - 1;
        while(str < end)
        {
                temp = *str;
                *str++ = *end;
                *end-- = temp;
        }
}

int main(void)
{
        char a[] = "This is a test";
        char b[] = "This";
       
        ReverseStr(a, b);
       
        printf("%s\n", a);
        return 0;
}

代码的主要思想先遍历主字符串,遇到子串是反转子串,然后再次遍历主字符串,
反转整个主字符串。上面的代码是没有问题的,可以输出最后的结果"tset a si This"。
但是其中的
                     while(*p1 == *p2)
                {
                        p1++;
                        p2++;
                }
如果改为
                      while(*p1++ == *p2 ++)
                                      ;
输出结果就会变为 "tset a si sihT", 也就是说子串也被反转了。

原因是这样的,就像各位所说的那样,相对于正确的代码,错误的代码中,
p1 和 p2 会多一次自加。也就是当 p2 指向 "This" 中最后的 '\0' 时,还会向后
移动一个位置,从而造成越界。

论坛徽章:
0
9 [报告]
发表于 2008-12-10 14:33 |只看该作者
在我发贴的时候没有看到 waternie 兄弟的帖子,不过问题还是很清楚了,
看来还是自己不够细心。xujg 和 waternie 厉害啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP