变量的变化

时间:2017-02-01 08:11:55

标签: c++

在下面的代码中,我试图在temp变量中存储索引0处的数组值。在这行代码中:a[i-1]=a[i]-a[i-1];当i = 0时,[i-1]变为[-1]。

  1. 为什么编译器没有给出任何错误?
  2. 为什么临时变量的值会受到影响并在第一次迭代后变为零,尽管只有当i = 0且其他地方没有使用temp时才会为其分配值?
  3. 例如,当我输入的内容为:

    3 1 2 3
    

    输出:

    i:0
    a[0]: 1
    TEMP: 1
    TEMP: 0
    TEMP: 0
    
    TEMP: 0
    

    实际发生了什么?请参考编译器的工作进行解释。我知道如果我提出条件if(i!=0) a[i-1]=a[i]-a[i-1];,代码将正常工作。但我想知道为什么会出现这种情况。

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int main()
    {
        int a[10],i,n,temp;
        cin>>n;
        for(i=0;i<n;i++){
            cin>>a[i];
            if(i==0){
                temp=a[i];
                cout<<"i: "<<i<<endl;
                cout<<"a[0]: "<<a[i]<<endl;
            }
            cout<<"TEMP: "<<temp<<endl;
            a[i-1]=a[i]-a[i-1];
        }
        cout<<endl<<"TEMP: "<<temp;
    }
    

2 个答案:

答案 0 :(得分:1)

  
      
  1. 为什么编译器没有给出任何错误?
  2.   

编译器不需要提供任何错误。访问数组越界有未定义的行为。似乎很明显,数组将在运行时被访问超出界限(然后再次,可能不是那么明显,因为程序的作者在运行程序之前没有捕获它),但是它的成本非常高编译器检查执行路径以搜索一般的错误。

  
      
  1. 为什么临时变量的值会受到影响并在第一次迭代后变为零,尽管只有当i = 0且其他地方没有使用temp时才会为其分配值?
  2.   

因为程序的行为未定义。

当允许程序以任何可能的方式运行时,分析为什么程序以某种方式运行通常是没有意义的。但是,这种情况似乎最有可能:当你写出界限时,你会覆盖一些不属于数组的内存。其他变量可能位于不属于数组的内存中。因此,覆盖一些不属于数组的内存可能会破坏某些其他变量的值。这就是你观察到的。

答案 1 :(得分:0)

  
      
  1. 为什么编译器没有给出任何错误?
  2.   

正如@ user2079303已经提到的,编译器找到这样的错误太困难了。有单独的工具可以找到更复杂的错误 - 静态和动态代码分析器。例如,如果您使用VS 2015中的默认静态代码分析器,则会发出以下警告:

Severity    Code    Description
Warning C4701   potentially uninitialized local variable 'temp' used
Warning C6385   Reading invalid data from 'a':  the readable size is '40' bytes, but '-4' bytes may be read.
Warning C6386   Buffer overrun while writing to 'a':  the writable size is '40' bytes, but '-4' bytes might be written.
Warning C6001   Using uninitialized memory 'temp'.

如果您想为项目提供额外的安全性,请考虑启用所有(或几乎所有)可用警告并定期运行代码分析。