3

我对 C 非常陌生,并且遇到以下问题。我初始化数组:

double Cx[101];
for(int i=0; i<101; i++){
  Cx[i]=-5+i*0.1;
}

double Q[2][101];
double y[101];

我在主要方法之外有以下功能:

double InitHeight(double g, double dx, double x){
  return 3;
}

double InitMom(double g, double dx, double x){
 return 2;
}

double plainTopo(double x){
 return x*10;
}

现在,在主要方法中,我执行以下操作:

double g=1;
double dx=0.1;
for(int i=0; i<101; i++){
  Q[1][i] = InitHeight(g,dx,Cx[i]);
  Q[2][i] = InitMom(g,dx,Cx[i]);
  y[i] = plainTopo(Cx[i]);
}

所以,我的问题是 Cx 数组的原始值被修改了。这是原始 Cx 的一部分:

-5.000000
-4.900000
-4.800000
-4.700000
-4.600000
-4.500000
-4.400000
...

在我运行代码之后,这就是我得到的:

   Cx[]   Q[1][]   Q[2][]     y[]
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000
2.000000 3.000000 2.000000 20.000000

我一生都无法理解为什么 Cx 数组会被修改。我尝试使用指针来代替,结果相同,还尝试在循环中执行 double x = Cx[i] 然后将 x 传递给函数,但 Cx 再次发生变化。

任何帮助将不胜感激。

4

4 回答 4

6

您的索引Q不正确。C中的数组索引从0开始,而不是1。所以你应该有

double g=1;
double dx=0.1;
for(int i=0; i<101; i++){
  Q[0][i] = InitHeight(g,dx,Cx[i]); /* Used to be Q[1][i] */
  Q[1][i] = InitMom(g,dx,Cx[i]); /* Used to be Q[2][i] */
  y[i] = plainTopo(Cx[i]);
}

至于为什么Cx会改变,访问数组中的越界项会导致未定义的行为,这意味着 C 编译器可以做任何它想做的事情。您的特定编译器生成分配到Cx. 从技术上讲,这是因为数组在堆栈上的布局方式,但编译器不需要做与编译器相同的事情,而是可以选择导致程序崩溃(这是最好的情况,因为它可以帮助您找到错误),覆盖其他数据(这就是您所看到的),或删除所有文件(我所知道的编译器实际上没有这样做)。真的,编译器有完全的自由每当发生未定义的行为时都会造成尽可能多的破坏,其中一种情况是当您访问超出范围的数组索引时。

于 2013-03-21T22:30:45.747 回答
5

这超出了数组的范围Q,导致未定义的行为:

Q[1][i] = InitHeight(g,dx,Cx[i]);
Q[2][i] = InitMom(g,dx,Cx[i]);

必须是Q[0]并且Q[1]定义Q为:

double Q[2][101];

代码中的另一个索引表明您知道数组索引是从零开始的,并且从数组0N - 1N元素数开始运行。

于 2013-03-21T22:30:29.040 回答
1
double g=1;
double dx=0.1;
for(int i=0; i<101; i++){
  Q[1][i] = InitHeight(g,dx,Cx[i]);
  Q[2][i] = InitMom(g,dx,Cx[i]);
  y[i] = plainTopo(Cx[i]);
}

您没有可用的 Q[2][i],因此它可能会覆盖到您的 Cx 数组中

我想你的意思是

Q[0][i] = InitHeight(g,dx,Cx[i]);
Q[1][i] = InitMom(g,dx,Cx[i]);
于 2013-03-21T22:32:43.307 回答
1
double Q[2][101];
:
Q[2][i] = InitMom(g,dx,Cx[i]);

您的腐败正在发生,因为 Q 的合法索引包括Q[2][...].

您似乎知道这一点,因为您i从 0 迭代到 100(含),对于Cx[101]数组,所以它似乎只是一个暂时的错误 - 它对于数组的所有维度都是相同的规则。

于 2013-03-21T22:32:43.493 回答