b[i++]=a[i++]这形式的赋值可以吗?

whc12345whc 2012-05-06 02:08:51

#include<stdio.h>

void main()
{
int i=0;
char a[5]={'a','b','c','d','e'};
char b[5];

while(a[i]!='\0')
{
b[i++]=a[i++];
printf("%c\n",b[i]);
}
}


#include<stdio.h>

void main()
{
int i=0;
char *p="Hello woeld!";
char a[19];
char *q=a;

while(*p!='\0')
{
*q++=*p++;
};

while(a[i]!='\0')
{
printf("%c",a[i++]);
};

printf("\n");
}


#include<stdio.h>

void main()
{
int i=0;
char *p="Hello woeld!";
char a[19];
char *q=a,*p1=p;

while(*p!='\0')
{
*q++=*p1++;
};

while(a[i]!='\0')
{
printf("%c",a[i++]);
};

printf("\n");
}

1,2的结果是错的,3是对的,总的说来我就想用一种i++=j++的这种形式,觉得这样的连续赋值比较好。
想问一下 1,2这种形式错在什么地方,一般的像这种要把b数组的元素复制到a的形式都是用第三种方法的吗,
...全文
1035 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
yht8708 2012-05-07
  • 打赏
  • 举报
回复
++
[Quote=引用 3 楼 的回复:]
第一种方法中
b[i++]=a[i++];
一个表达式里面i变了两次,但c没有规定这两次变化的顺序,结果是未定义的。

第二种方法
while(*p!='\0')
{
*q++=*p++;
};
当p指向最后那个'\0'的时候,循环体没执行。也就是最后那个'\0'没有复制过去。可以在循环结束后再加一条
*q = '\0'。

或者用更简洁的方法
while(*……
[/Quote]
nice_cxf 2012-05-07
  • 打赏
  • 举报
回复
对初学者来说,最好把++,--单独一行写(for循环除外)
如果你觉得你已经清楚了前++后++的区别,可以不单独写,但要记住一个原则,i++的同一语句不能在出现变量i
zhangtieqiang 2012-05-07
  • 打赏
  • 举报
回复
三楼说的对。。。就是那样的
gongfudi50 2012-05-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

最好不用这种方法,这个会因编译器的不同,产生不同的结果
[/Quote]

同意
jiligululalala 2012-05-06
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 的回复:]

while(*p!='\0')
{
*q++=*p1++;
};

这是一个死循环,,因为p的值没有改变,,,无法跳出循环啊,,,3#回答一下
[/Quote]


之前只看到这是个死循环,也没在意。刚才调了一下,有了结果。

说的简单点,就是在死循环的时候,*q++=*p1++;这条语句改变了栈上的变量,结果是未知的。


首先,函数里面定义了好多变量,还有一个数组。
char *p="Hello woeld!";
char a[19];

数组a是在栈上的,而指针p指向的是字符串字面量,但是变量p却是保存在栈上的。在我的环境里面,栈上的变量是以这个顺序从低地址往高地址排列的
a[19] (需要19个字节的空间), p , i ,q , p1 。

while(*p!='\0')
{
*q++=*p1++;
};
p1本来也是指向字符串字面量"Hello world!"的。这个字符串,我这里看到的是保存在代码段后面的.rodata段中。这个段长25字节,当然了,它后面还有其他的段。我的意思是,p1指向了这个只读的地址,并且,在这段地址之后,还有许多其他的内容,这些内容对于我们来说没用,但它们却是存在的。

这是个死循环,当p1指向"Hello world!"最后那个'\0'之后,循环没有终止,继续下去。于是p1就指向了不属于我们控制的空间了,这里面存了什么我们并不知道,而且把那个空间中的东西复制到了q中。这里q初始化的时候指向的是数组a,随着拷贝的深入,q也在不断地增加,超过了原先栈上分配的19个字节后,q开始指向它的隔壁邻居,正好是p。

循环还在继续,拷贝也在继续,其中某一次的拷贝,把那个空间中未知的一个值拷贝到了p中。正是这一次的拷贝,改变了p,改变了循环条件,跳出了循环。运气不错,程序安全退出了,也能正常打印。

“未定义”是一个相当讨厌的行为啊。

Qiangeizhu 2012-05-06
  • 打赏
  • 举报
回复
while(*p!='\0')
{
*q++=*p1++;
};

这是一个死循环,,因为p的值没有改变,,,无法跳出循环啊,,,3#回答一下
一根烂笔头 2012-05-06
  • 打赏
  • 举报
回复
个人认为这个表达式不会有未定义行为!很确定确定,而且可以移植!
它等价于
*q++ = *p++;
这样的指针操作!
pathuang68 2012-05-06
  • 打赏
  • 举报
回复
不要在同一个语句中写两次或以上的i++(或者++i或者i--或者--i),否则结果随编译器的不同而不同。
eulerkoko 2012-05-06
  • 打赏
  • 举报
回复
1、a是字符数组而不是字符串数组,所以不能用循环条件 a[i]!='\0'
b[i++]=a[i++]; 不同的机器执行这条语句的效果可能会不同的, 但无论如何b[i]都将会是打印第i+2个元素,将是不可预料的值
2、赋值循环实际上空字符并没赋值到数组中,所以打印循环条件a[i]!='\0'有误
3、实际上也是错的,while(*p!='\0') 理论上是无限循环,因为并没改变条件值的语句,实际运行可能会不可预料
duanpeijian 2012-05-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
最好不用这种方法,这个会因编译器的不同,产生不同的结果
[/Quote]
赞同!!
jiligululalala 2012-05-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

#include<stdio.h>

void main()
{
int i=0,j=0;
char a[5]={'a','b','c','d','e'};
char b[5];

while(a[i]!='\0')
{
b[i++]=a[j++];
printf("%c\n",b[i]);
……
[/Quote]

你定义的数组长度是5,只能存5个char类型的变量,而且已经存满了。也就是说a[0]到a[4],没有一个是'\0'。你的循环却是判断是否等于'\0'。

还有,
b[i++]=a[j++];
printf("%c\n",b[i]);
上面一条赋值语句结束后,你看下i和j是多少,这时候你printf出来的是哪个元素?

jiligululalala 2012-05-06
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

while(*q++=*p++)这个的返回值是什么,怎么才停止循环

[/Quote]


while(*q++=*p++)
;
下面的分号不能忘掉。


*q++=*p++ 的作用是把*p的内容复制到*q,之后p和q都加1。

说到底是一个表达式,当这个表达式的值为0时,也就是循环到了字符串结尾的'\0'处,循环结束。这样做,可以把最后那个0也拷贝过去。但是要注意此时指针的位置。
iamnobody 2012-05-06
  • 打赏
  • 举报
回复
百度: 未定义行为

表达式求值
jiligululalala 2012-05-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

3#楼,,问问你个问题。。。上面第三那种方法,,
while(*p!='\0')
{
*q++=*p1++;
};
这种情况下,,p1中的字母复制过来,,,同样q的结尾没有\0啊,,为什么能运行处正确的结果呢
[/Quote]

可以在循环体里面放一个计数用的变量。字符串的长度是13,但循环的次数会超过13,具体多少不确定。
whc12345whc 2012-05-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

你用的是什么书啊,楼主,不应该这样声明main函数的
[/Quote]
什么意思啊
Qiangeizhu 2012-05-06
  • 打赏
  • 举报
回复
3#楼,,问问你个问题。。。上面第三那种方法,,
while(*p!='\0')
{
*q++=*p1++;
};
这种情况下,,p1中的字母复制过来,,,同样q的结尾没有\0啊,,为什么能运行处正确的结果呢
empare 2012-05-06
  • 打赏
  • 举报
回复
你用的是什么书啊,楼主,不应该这样声明main函数的
whc12345whc 2012-05-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

第一种方法中
b[i++]=a[i++];
一个表达式里面i变了两次,但c没有规定这两次变化的顺序,结果是未定义的。

第二种方法
while(*p!='\0')
{
*q++=*p++;
};
当p指向最后那个'\0'的时候,循环体没执行。也就是最后那个'\0'没有复制过去。可以在循环结束后再加一条
*q = '\0'。

或者用更简洁的……
[/Quote]
while(*q++=*p++)这个的返回值是什么,怎么才停止循环
Qiangeizhu 2012-05-06
  • 打赏
  • 举报
回复
#include<stdio.h>

void main()
{
int i=0,j=0;
char a[5]={'a','b','c','d','e'};
char b[5];

while(a[i]!='\0')
{
b[i++]=a[j++];
printf("%c\n",b[i]);
}
}
3#楼,,这样修改怎么还不能输出结果啊,,
Corner 2012-05-06
  • 打赏
  • 举报
回复
不要写自己都搞不清楚的代码,有些即便你测试时正确的,但是可能仅仅是你当前编译器正确,应该保证自己所写的代码含义明确。
加载更多回复(3)

70,026

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧