鱼C论坛

 找回密码
 立即注册
查看: 2123|回复: 5

[已解决]到底是从左向右读取还是从右向左

[复制链接]
发表于 2019-5-10 15:51:09 | 显示全部楼层 |阅读模式
3鱼币
到底是从左向右读取还是从右向左
#include<stdio.h>
int fun(int x[], int n){
    static int sum =0,i;
    for(i = 0;i<n;i++){
        sum += x[i];
    }
    return sum;
}

main(){
    int a[]={1,2,3,4,5}, b[]={6,7,8,9},s;
    s = fun(a,5) + fun(b,4);
}
一般来说不是从右向左读的吗?但是这道题答案却是60(从左向右);
难道是和编译器有关吗。。。。
最佳答案
2019-5-10 15:51:10
本帖最后由 Croper 于 2019-5-11 10:36 编辑

首先说答案:确实是编辑器相关的

楼上几位@HUMMER军,@我叫MD没有意识到问题的关键。这道题的问题在于求值顺序,static什么的只是个表现形式而已。
而关于求值顺序,《c++ Primer》上已经有很明确的说明了:
有四种运算符明确规定了运算对象的求值顺序。第一种是3.2.3节(第85页)提到的逻辑与(&&)运算符,它规定先求左侧运算对象的值,只有当坐车运算对象的值为真时才继续求右侧运算对象的值。另外三种分别是逻辑或(||)运算符、条件(?:)运算符和逗号(,)运算符。
...
运算对象的求值顺序与优先级和结合律无关,在一条形如f()+g()*h()+j()的表达式中:
    优先级规定,g()的返回值和h()的返回值相乘
    结合律规定,f()的返回值先与g()和h()的乘积相加,所得结果再与j()的返回值相。
    对于这些函数的调用顺序没有明确规定

(c++ Primer 第五版,p139)

因此,楼主的这种写法,属于未定义的行为,建议不要这么使用。

另外,楼主说的从右至左,是指在默认调用方式下,函数参数的入栈顺序是从右至左,不要搞混了。

最佳答案

查看完整内容

首先说答案:确实是编辑器相关的 楼上几位@HUMMER军,@我叫MD没有意识到问题的关键。这道题的问题在于求值顺序,static什么的只是个表现形式而已。 而关于求值顺序,《c++ Primer》上已经有很明确的说明了: (c++ Primer 第五版,p139) 因此,楼主的这种写法,属于未定义的行为,建议不要这么使用。 另外,楼主说的从右至左,是指在默认调用方式下,函数参数的入栈顺序是从右至左,不要搞混了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-5-10 15:51:10 | 显示全部楼层    本楼为最佳答案   
本帖最后由 Croper 于 2019-5-11 10:36 编辑

首先说答案:确实是编辑器相关的

楼上几位@HUMMER军,@我叫MD没有意识到问题的关键。这道题的问题在于求值顺序,static什么的只是个表现形式而已。
而关于求值顺序,《c++ Primer》上已经有很明确的说明了:
有四种运算符明确规定了运算对象的求值顺序。第一种是3.2.3节(第85页)提到的逻辑与(&&)运算符,它规定先求左侧运算对象的值,只有当坐车运算对象的值为真时才继续求右侧运算对象的值。另外三种分别是逻辑或(||)运算符、条件(?:)运算符和逗号(,)运算符。
...
运算对象的求值顺序与优先级和结合律无关,在一条形如f()+g()*h()+j()的表达式中:
    优先级规定,g()的返回值和h()的返回值相乘
    结合律规定,f()的返回值先与g()和h()的乘积相加,所得结果再与j()的返回值相。
    对于这些函数的调用顺序没有明确规定

(c++ Primer 第五版,p139)

因此,楼主的这种写法,属于未定义的行为,建议不要这么使用。

另外,楼主说的从右至左,是指在默认调用方式下,函数参数的入栈顺序是从右至左,不要搞混了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-5-10 16:40:59 | 显示全部楼层
不知道你说的从左向右读还是从右向左读是什么意思!
我这里只给你分析下答案,为什么是 60

首先fun函数是一个计算数组元素之和的函数,所以这行代码    s = fun(a,5) + fun(b,4)   计算的是两个数组元素的和

先看 fun(a, 5)    调用fun函数返回sum值是 15(数组a元素之和)
再看 fun(b, 4)    调用fun函数返回sum值是 45 为什么是45呢?因为你定义的sum变量是static(静态局部变量,所以当调用此函数的时候sum并不会为0,而是为15接着加数组b的元素)

这样 s = fun(a,5) + fun(b,4)   实际就是 s = 15 + 45     s = 60

结论:你这个结果和编译器并没有什么关系,所有编译器都应该是这个结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-5-10 17:43:41 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-5-11 01:54:07 | 显示全部楼层
#include<stdio.h>
int fun(int x[], int n){
    int sum =0,i;
    for(i = 0;i<n;i++){
        sum += x[i];
    }
    return sum;
}

int main(){
    int a[]={1,2,3,4,5}, b[]={6,7,8,9},s;
    s = fun(a,5) + fun(b,4);
    printf("%d\n",s);
    return 0;
}
可以把关键字static去掉对比了看,不加static结果是45
s = fun(a,5) + fun(b,4); 相当于两次调用了fun函数  int sum =0 ,意思每一次调用fun函数  sum都被置0;所以结果是15+30=45;

加上static关键字,修饰局部变量sum,作用是延长该局部变量的生命周期,直到程序结束时,该局部变量才被销毁! 但是并没有改变该局部变量的作用域,仅仅是改变了它的生命周期!
现在就应该容易理解结果为什么是60了!
s = fun(a,5) + fun(b,4); 两次调用fun函数,第一次调用完,sum=15,第二次调用的时候sum是在15的基础上做运算,所以结果是15+15+30=60

这边主要就是要弄明白static对局部变量的作用,延长局部变量的生命周期,但是不改变作用域
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-5-11 09:34:52 | 显示全部楼层
我叫MD 发表于 2019-5-10 16:40
不知道你说的从左向右读还是从右向左读是什么意思!
我这里只给你分析下答案,为什么是 60

噢,我没说明好。
是这一句, s = fun(a,5) + fun(b,4);
就是先算fun(a,5)还是先算fun(b,4)的问题,
我是按先算fun(b,4)进行的,答案是75,c不是从右向左计算的吗。。。。
实际电脑应该是先算fun(a,5)的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 17:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表