当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 11 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 12:02 
头像

注册: 2008-12-06 10:38
帖子: 4566
送出感谢: 23
接收感谢: 31
先来段代码:
代码:
void strcpy(char *s,char *t)
{
    while (*s++ = *t++)
        ;
}


啥时候我也写的出这么漂亮的代码额 :em03

我看到的关于while (*s++ = *t++)一句大家比较认可的解释是:
引用:
(1)*t 的赋值给 *s
(2)判断 *s 是否为真。如果为假,则跳出循环;否则继续执行第(3)步。因为字符串是以\0结尾的,遇到\0的时候,也就是*s为假,就跳出了字符串拷贝。
(3)s 和 t 加 1,指向下一个地址,准备拷贝下一个字符。


我扩充一下,不知道对不对:
引用:
(1) 取t和s的值t'和s'到内存的某个位置;
(2) 取出*t' 和*s';
(3) *t' 的赋值给 *s';
(4) 判断 *s' 是否为真。如果为假,则跳出循环,否则继续执行(5)步;
(5) s 和 t 加 1。


我的问题是:
引用:
1. 根据运算符优先级,后自增运算符的优先级比赋值高,所以顺序是(1)(2)(5)(3)(4);
2. 根据运算符优先级,后自增运算符的优先级比提领(*)高,所以取出t' 和s' 后应该先对t和s进行自增,然后在取*t' 和*s',
所以正确的顺序应该是(1)(5)(2)(3)(4)。


是这样的吗?如果不是,为什么?

最后弱弱地说一句:我是小菜…… :em03


页首
 用户资料  
 
2 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 14:58 
头像

注册: 2009-07-07 19:52
帖子: 240
送出感谢: 0 次
接收感谢: 0 次
这段代码也算漂亮?

要是谁在工作中这么写,那他离被开除不远了。


_________________
阿呆 : 天下第一呆!


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 15:51 
头像

注册: 2008-12-06 10:38
帖子: 4566
送出感谢: 23
接收感谢: 31
额……看来还没工作就要面临被开出了……


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 17:12 
头像

注册: 2006-07-02 11:16
帖子: 12522
地址: 廣州
送出感谢: 0 次
接收感谢: 8
linjiework 写道:
这段代码也算漂亮?

要是谁在工作中这么写,那他离被开除不远了。


其实从可读性来说没什么问题

C的惯用法吧 ..


_________________
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 19:54 
头像

注册: 2008-12-06 10:38
帖子: 4566
送出感谢: 23
接收感谢: 31
事实证明我的想法是错误的,这是一个简单的测试程序:
代码:
#include <stdio.h>

void copy(char *, char *);

int main()
{
   char t[] = "Hello world!";
   char s[] = "";
   copy(s, t);
   printf("%s\n", s);
}

void copy(char *s,char *t)
{
   while (*s++ = *t++)
      ;
}


这是它的汇编代码:
代码:
   .file   "strcopy.c"
   .section   .rodata
.LC0:
   .string   ""
   .text
.globl main
   .type   main, @function
main:
   pushl   %ebp
   movl   %esp, %ebp
   andl   $-16, %esp
   subl   $48, %esp
   movl   %gs:20, %eax
   movl   %eax, 44(%esp)
   xorl   %eax, %eax
   movl   $1819043144, 31(%esp)
   movl   $1870078063, 35(%esp)
   movl   $560229490, 39(%esp)
   movb   $0, 43(%esp)
   movzbl   .LC0, %eax
   movb   %al, 30(%esp)
   leal   31(%esp), %eax
   movl   %eax, 4(%esp)
   leal   30(%esp), %eax
   movl   %eax, (%esp)
   call   copy
   leal   30(%esp), %eax
   movl   %eax, (%esp)
   call   puts
   movl   44(%esp), %edx
   xorl   %gs:20, %edx
   je   .L3
   call   __stack_chk_fail
.L3:
   leave
   ret
   .size   main, .-main
.globl copy
   .type   copy, @function
copy:
   pushl   %ebp
   movl   %esp, %ebp
.L5:
   movl   12(%ebp), %eax
   movzbl   (%eax), %edx
   movl   8(%ebp), %eax
   movb   %dl, (%eax)
   movl   8(%ebp), %eax
   movzbl   (%eax), %eax
   testb   %al, %al
   setne   %al
   addl   $1, 8(%ebp)
   addl   $1, 12(%ebp)
   testb   %al, %al
   jne   .L5
   popl   %ebp
   ret
   .size   copy, .-copy
   .ident   "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
   .section   .note.GNU-stack,"",@progbits


那么现在的问题就是:后自增比赋值的优先级要高,而表面上看上去自增却发生在赋值之后,我认为我的说法可以解释这个问题(赋值掉取的是原变量在内存中的一个副本,而变量本身已经增加了),但从汇编的代码不支持这个说法,那么怎么解释这里的优先级问题呢?哪位高手能不能举个例子展示一下后自增比赋值的优先级要高呢?


页首
 用户资料  
 
6 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 20:30 
头像

注册: 2007-09-29 3:09
帖子: 5777
送出感谢: 0 次
接收感谢: 5
后缀运算的表达式值是不变的...


_________________
HUNT Unfortunately No Talent...


页首
 用户资料  
 
7 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 20:46 
头像

注册: 2008-12-06 10:38
帖子: 4566
送出感谢: 23
接收感谢: 31
HuntXu 写道:
后缀运算的表达式值是不变的...

额……不明白 :em06


页首
 用户资料  
 
8 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 20:49 
头像

注册: 2006-07-02 11:16
帖子: 12522
地址: 廣州
送出感谢: 0 次
接收感谢: 8
灰色小狼 写道:
事实证明我的想法是错误的,这是一个简单的测试程序:
代码:
#include <stdio.h>

void copy(char *, char *);

int main()
{
   char t[] = "Hello world!";
   char s[] = "";
   copy(s, t);
   printf("%s\n", s);
}

void copy(char *s,char *t)
{
   while (*s++ = *t++)
      ;
}


这是它的汇编代码:
代码:
   .file   "strcopy.c"
   .section   .rodata
.LC0:
   .string   ""
   .text
.globl main
   .type   main, @function
main:
   pushl   %ebp
   movl   %esp, %ebp
   andl   $-16, %esp
   subl   $48, %esp
   movl   %gs:20, %eax
   movl   %eax, 44(%esp)
   xorl   %eax, %eax
   movl   $1819043144, 31(%esp)
   movl   $1870078063, 35(%esp)
   movl   $560229490, 39(%esp)
   movb   $0, 43(%esp)
   movzbl   .LC0, %eax
   movb   %al, 30(%esp)
   leal   31(%esp), %eax
   movl   %eax, 4(%esp)
   leal   30(%esp), %eax
   movl   %eax, (%esp)
   call   copy
   leal   30(%esp), %eax
   movl   %eax, (%esp)
   call   puts
   movl   44(%esp), %edx
   xorl   %gs:20, %edx
   je   .L3
   call   __stack_chk_fail
.L3:
   leave
   ret
   .size   main, .-main
.globl copy
   .type   copy, @function
copy:
   pushl   %ebp
   movl   %esp, %ebp
.L5:
   movl   12(%ebp), %eax
   movzbl   (%eax), %edx
   movl   8(%ebp), %eax
   movb   %dl, (%eax)
   movl   8(%ebp), %eax
   movzbl   (%eax), %eax
   testb   %al, %al
   setne   %al
   addl   $1, 8(%ebp)
   addl   $1, 12(%ebp)
   testb   %al, %al
   jne   .L5
   popl   %ebp
   ret
   .size   copy, .-copy
   .ident   "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
   .section   .note.GNU-stack,"",@progbits


那么现在的问题就是:后自增比赋值的优先级要高,而表面上看上去自增却发生在赋值之后,我认为我的说法可以解释这个问题(赋值掉取的是原变量在内存中的一个副本,而变量本身已经增加了),但从汇编的代码不支持这个说法,那么怎么解释这里的优先级问题呢?哪位高手能不能举个例子展示一下后自增比赋值的优先级要高呢?


这样说吧
1. 两个 * 所解引用的都是 ++ 前的指针
2. 所以那个赋值相当于 *s = *t
3. 其他的顺序未定义, 但是所有副作用(++, 赋值) 都在那个分号之前完成
4. 所谓的优先级不是指运算顺序,是指结合性 例如 a = b++ 是理解成 a = (b++) 而不是 (a = b) ++, 那个 b 的自增不保证在赋值之后执行, 但是赋值给 a 的一定是 b 自增之前的值


_________________
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。


页首
 用户资料  
 
9 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 20:52 
头像

注册: 2006-07-02 11:16
帖子: 12522
地址: 廣州
送出感谢: 0 次
接收感谢: 8
补充语句, 如果是
* s = * s++;
那就是脑残代码了,因为你不知道那个 ++ 在什么时候发生,所以不知道左边取出来的 s 是自增前还是自增后


_________________
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。


页首
 用户资料  
 
10 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 21:13 
头像

注册: 2008-12-06 10:38
帖子: 4566
送出感谢: 23
接收感谢: 31
BigSnake.NET 写道:
4. 所谓的优先级不是指运算顺序,是指结合性 例如 a = b++ 是理解成 a = (b++) 而不是 (a = b) ++, 那个 b 的自增不保证在赋值之后执行, 但是赋值给 a 的一定是 b 自增之前的值

醍醐灌顶 :em11 多谢


页首
 用户资料  
 
11 楼 
 文章标题 : Re: 问个自增/自减与赋值运算符优先级关系的问题
帖子发表于 : 2010-11-05 21:24 
头像

注册: 2008-12-06 10:38
帖子: 4566
送出感谢: 23
接收感谢: 31
看来果然还是我太菜了……基本的概念都没搞懂 :em19


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 11 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 3 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译