方大侠 发表于 2019-5-10 15:51:09

到底是从左向右读取还是从右向左

到底是从左向右读取还是从右向左

#include<stdio.h>
int fun(int x[], int n){
    static int sum =0,i;
    for(i = 0;i<n;i++){
      sum += x;
    }
    return sum;
}

main(){
    int a[]={1,2,3,4,5}, b[]={6,7,8,9},s;
    s = fun(a,5) + fun(b,4);
}

一般来说不是从右向左读的吗?但是这道题答案却是60(从左向右);
难道是和编译器有关吗。。。。

Croper 发表于 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)

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

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

我叫MD 发表于 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

结论:你这个结果和编译器并没有什么关系,所有编译器都应该是这个结果

人造人 发表于 2019-5-10 17:43:41

https://blog.csdn.net/xuleisdjn/article/details/51567337

HUMMER军 发表于 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;
    }
    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对局部变量的作用,延长局部变量的生命周期,但是不改变作用域

方大侠 发表于 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)的
页: [1]
查看完整版本: 到底是从左向右读取还是从右向左