为什么原文说total+=*start++和total+=*(start++)是等价的?

R2Freedom 2015-03-20 02:22:52
《C primer plus》中的一道题目,文中说total+=*start++和total+=*(start++)是一样的,这里我想不通,加了括号后不是应该先算括号里的内容么?怎么会是一样的呢。请高手解答!

#include <stdio.h>
#define SIZE 10
int sump(int *start,int *end);

int main()
{
int marbles[SIZE]={20,10,5,39,4,16,19,26,31,20};
long answer;

answer=sump(marbles,marbles+SIZE);
printf("%ld.\n",answer);
return 0;
}

int sump(int *start,int *end)
{
int total=0;
while(start<end)
total+=*(start++);
return total;
}
...全文
524 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
blue小青年 2016-05-16
  • 打赏
  • 举报
回复
引用 6 楼 my_live_123 的回复:
C99


想知道这张图的出处,顺便primary-expression应该是前++,postfix-expression应该是后++吧


飞行1-5 2015-03-23
  • 打赏
  • 举报
回复
start++这句还没结束时,start指针地址不变,所以取*不变
fly_dragon_fly 2015-03-23
  • 打赏
  • 举报
回复
把start++这个表达式看成一个函数,看看它的返回值 , 它是这样的 tmp=start, ++start, return tmp; 而(start++) 是这样的 ( tmp=start, ++start,return tmp) 比较一下,显然是一样的
一根烂笔头 2015-03-23
  • 打赏
  • 举报
回复
引用 11 楼 cfvmario 的回复:
就算编译角度有差别,现代计算机需要在乎这点? 我强烈建议一律加括号,可读性才是第一位的
鱼和熊掌不可兼得,看个人选择! 爱速度的人,还是喜欢压榨时间的,无论编译还是运行!
cfvmario 2015-03-23
  • 打赏
  • 举报
回复
就算编译角度有差别,现代计算机需要在乎这点? 我强烈建议一律加括号,可读性才是第一位的
左眼看到鬼 2015-03-21
  • 打赏
  • 举报
回复
引用 8 楼 luckyaslan 的回复:
根据运算符优先级来看: total+=*start++ 的执行顺序是这样的:total += (*start)++ 所以等同于下面两个表达式: total+=(*start)++ total+=*(start++) 在这里把++的作用理解了,这个问题就看明白了。 例如:i++ i++的实现如下:

{
int temp;
temp = i;
i = i+1;
return temp;
}
可以看出来i++;执行后,得到的值,是一个临时变量,这个值和i之前的值是相同的。
写错了。 二楼说的对。
左眼看到鬼 2015-03-21
  • 打赏
  • 举报
回复
根据运算符优先级来看: total+=*start++ 的执行顺序是这样的:total += (*start)++ 所以等同于下面两个表达式: total+=(*start)++ total+=*(start++) 在这里把++的作用理解了,这个问题就看明白了。 例如:i++ i++的实现如下:

{
int temp;
temp = i;
i = i+1;
return temp;
}
可以看出来i++;执行后,得到的值,是一个临时变量,这个值和i之前的值是相同的。
一根烂笔头 2015-03-20
  • 打赏
  • 举报
回复
解释一下: total+=*start++和total+=*(start++)从结果上讲是一样的,从编译角度讲不太一样 *属于unary-operator ++放在表达式之后,构成:postfix-expression ++ total+=*start++ 从语法分析上要先分析postfix-expression ++,然后转到unary-expression,过度到cast-expression,整合 * 的unary-operator组合成unary-operator cast-expression,最后转一圈回到赋值表达式 因此先执行++,再执行* total+=*(start++) 要比上面不加括号的情况下,多一圈语法分析;即start++自身走一圈回到exp,然后再转一圈把*整合进去。 因此从编译角度讲,如果想让代码编译更快点,在知道优先级的情况下,优先选择total+=*start++,因为每加一个括号,就要从上面12点钟方向重新开始一遍语法分析。 不过,编译出来的指令都是一样的,因此运算结果也都是一样的。
一根烂笔头 2015-03-20
  • 打赏
  • 举报
回复
C99
dooX8086 2015-03-20
  • 打赏
  • 举报
回复

//只要了解后缀 ++ 就很清楚了
// 后缀 ++ 其实就是豆号表达式组
// 如: 把 start++ 展开就是
int *tmp;   //编译器创建的临时变量
(tmp = start, start = start + 1, tmp);

//那么: total+=*(start++);  就是 
int *tmp;   
total += *( (tmp = start, start = start + 1, tmp) );   // 所以外面这对 () 添加以否都是一样的

// 一目了然了.....
//
赵4老师 2015-03-20
  • 打赏
  • 举报
回复
//C++ Operators
//  Operators specify an evaluation to be performed on one of the following:
//    One operand (unary operator)
//    Two operands (binary operator)
//    Three operands (ternary operator)
//  The C++ language includes all C operators and adds several new operators.
//  Table 1.1 lists the operators available in Microsoft C++.
//  Operators follow a strict precedence which defines the evaluation order of
//expressions containing these operators.  Operators associate with either the
//expression on their left or the expression on their right;    this is called
//“associativity.” Operators in the same group have equal precedence and are
//evaluated left to right in an expression unless explicitly forced by a pair of
//parentheses, ( ).
//  Table 1.1 shows the precedence and associativity of C++ operators
//  (from highest to lowest precedence).
//
//Table 1.1   C++ Operator Precedence and Associativity
// The highest precedence level is at the top of the table.
//+------------------+-----------------------------------------+---------------+
//| Operator         | Name or Meaning                         | Associativity |
//+------------------+-----------------------------------------+---------------+
//| ::               | Scope resolution                        | None          |
//| ::               | Global                                  | None          |
//| [ ]              | Array subscript                         | Left to right |
//| ( )              | Function call                           | Left to right |
//| ( )              | Conversion                              | None          |
//| .                | Member selection (object)               | Left to right |
//| ->               | Member selection (pointer)              | Left to right |
//| ++               | Postfix increment                       | None          |
//| --               | Postfix decrement                       | None          |
//| new              | Allocate object                         | None          |
//| delete           | Deallocate object                       | None          |
//| delete[ ]        | Deallocate object                       | None          |
//| ++               | Prefix increment                        | None          |
//| --               | Prefix decrement                        | None          |
//| *                | Dereference                             | None          |
//| &                | Address-of                              | None          |
//| +                | Unary plus                              | None          |
//| -                | Arithmetic negation (unary)             | None          |
//| !                | Logical NOT                             | None          |
//| ~                | Bitwise complement                      | None          |
//| sizeof           | Size of object                          | None          |
//| sizeof ( )       | Size of type                            | None          |
//| typeid( )        | type name                               | None          |
//| (type)           | Type cast (conversion)                  | Right to left |
//| const_cast       | Type cast (conversion)                  | None          |
//| dynamic_cast     | Type cast (conversion)                  | None          |
//| reinterpret_cast | Type cast (conversion)                  | None          |
//| static_cast      | Type cast (conversion)                  | None          |
//| .*               | Apply pointer to class member (objects) | Left to right |
//| ->*              | Dereference pointer to class member     | Left to right |
//| *                | Multiplication                          | Left to right |
//| /                | Division                                | Left to right |
//| %                | Remainder (modulus)                     | Left to right |
//| +                | Addition                                | Left to right |
//| -                | Subtraction                             | Left to right |
//| <<               | Left shift                              | Left to right |
//| >>               | Right shift                             | Left to right |
//| <                | Less than                               | Left to right |
//| >                | Greater than                            | Left to right |
//| <=               | Less than or equal to                   | Left to right |
//| >=               | Greater than or equal to                | Left to right |
//| ==               | Equality                                | Left to right |
//| !=               | Inequality                              | Left to right |
//| &                | Bitwise AND                             | Left to right |
//| ^                | Bitwise exclusive OR                    | Left to right |
//| |                | Bitwise OR                              | Left to right |
//| &&               | Logical AND                             | Left to right |
//| ||               | Logical OR                              | Left to right |
//| e1?e2:e3         | Conditional                             | Right to left |
//| =                | Assignment                              | Right to left |
//| *=               | Multiplication assignment               | Right to left |
//| /=               | Division assignment                     | Right to left |
//| %=               | Modulus assignment                      | Right to left |
//| +=               | Addition assignment                     | Right to left |
//| -=               | Subtraction assignment                  | Right to left |
//| <<=              | Left-shift assignment                   | Right to left |
//| >>=              | Right-shift assignment                  | Right to left |
//| &=               | Bitwise AND assignment                  | Right to left |
//| |=               | Bitwise inclusive OR assignment         | Right to left |
//| ^=               | Bitwise exclusive OR assignment         | Right to left |
//| ,                | Comma                                   | Left to right |
//+------------------+-----------------------------------------+---------------+
晓石头 2015-03-20
  • 打赏
  • 举报
回复
total+=*start++和total+=*(start++)
因为不管是那种情况都是先执行*start,再赋值运算,最后start+1,
除非是*(++start)才先执行start+1,再*start,再赋值运算,
我理解形如i++的操作,是等赋值运算完后再执行的操作
zuxi 2015-03-20
  • 打赏
  • 举报
回复
这里是优先级表: http://www.slyar.com/blog/c-operator-priority.html 虽然*和++优先级一样,但是结合性是从右到左,也就是说它们在一起时右边的优先级高。
只此冒泡君 2015-03-20
  • 打赏
  • 举报
回复
因为自增++ 在这里面的优先级最高 加不加括号 都一样!

69,382

社区成员

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

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