为什么原文说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;
}
...全文
687 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
愿你变作彩霞 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
  • 打赏
  • 举报
回复
因为自增++ 在这里面的优先级最高 加不加括号 都一样!
内容概要:本文提出了一种基于改进扩散模型的高海拔地区新能源高波动出力场景生成方法,并提供了完整的Python代码实现。该方法针对高海拔地区风能、光伏等新能源出力波动剧烈、不确定性高的特点,通过优化扩散模型的结构与训练策略,有效捕捉历史数据的概率分布特征与时序相关性,从而生成高质量、多样化的出力场景。文中详细阐述了模型的数学推导、网络架构设计、损失函数优化及采样算法改进,并通过实验证明其在拟合精度、场景多样性与稳定性方面优于传统生成模型,为电力系统在高比例新能源接入下的规划、调度与风险评估提供了可靠的场景输入支持。; 适合人群:具备一定Python编程能力和机器学习基础,从事新能源发电预测、电力系统分析、智能优化、场景生成等方向研究的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①用于高海拔地区风电、光伏出力的不确定性建模与多场景生成;②支撑含高渗透率新能源的电力系统随机优化调度、鲁棒决策与风险评估;③为相关学术研究、论文复现与算法改进提供可运行的技术方案与代码基础; 阅读建议:建议读者结合所提供的完整资源(代码、数据集、明文档)进行实践操作,重点关注扩散模型的前向加噪与反向去噪过程的设计细节,以及如何将其适配于新能源时序数据的生成任务,通过参数调优与对比实验深入理解模型的生成机制与性能边界。
内容概要:本文围绕基于静态约束法的配电网电动汽车接入容量评估展开研究,提出了一种在新型电力系统背景下评估主动配电网对电动汽车承载能力的方法。研究通过构建数学模型,结合潮流计算与关键约束条件(如电压越限、线路过载等),量化分析配电网可承受的最大电动汽车充电负荷容量,旨在识别规模化电动汽车接入带来的潜在运行风险,并为电网规划与运行提供科学依据。文中配套提供了完整的Matlab代码实现,便于仿真验证与结果复现。此外,该研究与分布式光伏承载力评估、电动汽车可调能力分析等方向形成技术联动,展现了多主题协同的研究体系。; 适合人群:具备电力系统分析基础理论知识及Matlab编程能力的高校研究生、科研机构研究人员,以及从事新能源并网、智能配电网规划与运行等相关领域的工程技术人员。; 使用场景及目标:①用于学术研究中的模型复现与论文撰写支撑;②评估实际配电网中电动汽车大规模接入的可行性与安全边界,指导充电基础设施布局;③作为高校教学案例,帮助学生深入理解电网承载力评估的核心原理、建模方法与仿真技术; 阅读建议:建议结合文中提及的相关研究方向(如二阶锥规划、多面体聚合方法等)进行对比学习,充分利用所提供的Matlab代码与网盘资料开展仿真实验,重点关注约束条件的设定逻辑与潮流计算模块的实现细节,以深化对评估模型机理与工程应用价值的理解。

70,038

社区成员

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

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