【问题标题】:3 dimensional array in C changes values after the for loopC中的3维数组在for循环后更改值
【发布时间】:2013-03-23 18:39:40
【问题描述】:

我在这件事上真的很矛盾。我在 C 中填充了一个三维数组,如下所示:

double maxEval = 0;        
double Evals[2][le-1];  
double Waves[2][2][le-1];

for(int i=0; i<le-1; i++){

  getEvalsandWaves(&Evals[0][i], &Evals[1][i], &Waves[0][0][i], &Waves[0][1][i],
                   &Waves[1][0][i], &Waves[1][1][i], g, dx, &maxEval,
                   Q[0][i], Q[0][i+1], Q[1][i], Q[1][i+1]);

  if(myRank==0){
    printf("i= %d, %f  %f\n",i,Waves[0][0][i],Waves[0][1][i]);
    printf("       %f  %f\n\n",Waves[1][0][i],Waves[1][1][i]);
  }
}

getEvalsandWaves的proto函数和函数在这里:

/*The objective of this function is to calculate eigenvalues which have a close*/
/*form (e1 and e2) as well as the wave speeds associated with each eigenvalue  */
/*[w00; w10]) and [w01;w11] which then are stored in a thee dimensional matrix */

void getEvalsandWaves(double *e1, double *e2, double *w00,double *w01, double *w10,
                      double *w11, double g,double dx, double *max, double him, 
                      double hi, double uim, double ui);

void getEvalsandWaves(double *e1, double *e2, double *w00, double *w01, double *w10, 
                      double *w11, double g, double dx, double *max, double him, 
                      double hi, double uim, double ui){

                      double hbar=0; double ubar=0;

                      /*this function only returns the Roe averages */
                      /*using the values him,hi,uim,ui which are all*/
                      /*doubles */
                      RoeAvg(&hbar, &ubar,him,hi,uim,ui);

                      (*e1) = ubar - sqrt(g*hbar);
                      (*e2) = ubar + sqrt(g*hbar);

                      /*I tried to use this values instead of (*e1) and (*e2)*/
                      /*in calculating the w'sbelow to see if it fixed the   */
                      /*problem but it didn't work.                          */
                      double ei1 = ubar - sqrt(g*hbar);
                      double ei2 = ubar + sqrt(g*hbar);

                      if(fabs((*e1))>(*max))
                      (*max)=fabs((*e1));

                      if(abs((*e2))>(*max))
                      (*max)=fabs((*e2));

                      double c = 1/(2*sqrt(g*hbar));

                      (*w00) = c * ( ei2*(hi-him)+(ui-uim) ) * 1;      
                      (*w01) = c * ( (-1)*ei1*(hi-him)-(ui-uim) ) * 1;
                      (*w10) = c * ( ei2*(hi-him)+(ui-uim) ) * ei1;    
                      (*w11) = c * ( (-1)*ei1*(hi-him)-(ui-uim) ) * ei2;
}

所以这里是我不知道发生了什么的地方。如果您注意到在 for 循环中,我正在打印三维数组 Waves 的值,并给出以下示例输出:

...
i= 47, 0.000000  0.000000
       -0.000000  0.000000

i= 48, 0.000000  0.000000
       -0.000000  0.000000

i= 49, -1.000000  -1.000000
        1.414214  -1.414214
...

哪些是正确的值。但是,如果我在 for 循环之后立即打印 Waves 的值,这就是我得到的:

...
i= 47, 0.000000  0.000000
      -1.000000  -1.000000

i= 48, 0.000000  0.000000
       0.000000  0.000000

i= 49, -1.000000  -1.000000
        0.000000  0.000000
...

我真的不明白为什么当 for 循环完成时值会发生变化。任何帮助将不胜感激。(Evals 数组和 maxEval 变量在循环后确实保持正确的值。)

【问题讨论】:

  • 这是一些可怕的功能。如果您希望有人提供帮助,评论您的代码可能会有所帮助。
  • 感谢您的建议。我粗略地解释了这些函数应该做什么。
  • 不幸的是,cmets 没用。示例:“此函数仅返回使用值 he,hi,uim,ui 的 Roe 平均值,这些值都是双精度值。” – 这传达了代码中不存在的无信息(检查函数名称和参数)。 cmets 需要提供附加信息,而不是以更冗长的形式重复代码。
  • 仅供参考:如果您的数组大小为x,则for(...) 循环终止条件为...;i &lt; x;... 永远不会达到list_member[x]
  • 你有进步吗?循环后在哪里以及如何打印值?似乎很重要,特别是如果您认为它们在循环之后保持正确的值 - 而且,无论如何,您怎么知道它们保持正确的值?

标签: c arrays for-loop


【解决方案1】:

感谢那些花时间阅读我的问题的人,并对一些 cmets 的回复较晚感到抱歉,但我正忙于另一个项目。

所以,我在阅读了这篇文章后解决了这个问题:

How are 3D arrays stored in C?

所以我知道我的 cmets 根本没有帮助解释我在做什么,但最终它归结为试图存储矩阵数组。所以我们可以将数组 A[x][y] 视为一个二维数组,我想将其中的 z 个存储为 A[x][y][z]。

我知道 C 将二维数组存储为线性数组,但在阅读了上面链接中的文章后,我意识到如果我尝试将 7 存储在数组中位置 [0][1] 的第三个矩阵中:

A[0][1][3]=7;

然后尝试稍后检索它,我会得到不同的东西。原因是如果我尝试以这种方式存储它,我必须考虑 C 如何将三维数组存储为一维数组,因此索引会有所不同。

我应该将 A[x][y][z] 作为一个 x 数组的数组来读取,每个数组都有 z 个元素。最后为了我的目的(存储一个 z 矩阵数组)什么工作是:

A[z][x][y];
A[3][0][1]=7;

这样,如果我以后检索,

printf("The value at A[3][0][1]= %d",A[3][0][1]);

它会打印出正确的值 7。

这篇文章更好地解释了我刚刚想说的话。如果有人有更多想法或 cmet,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2017-03-07
    • 2021-01-07
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    相关资源
    最近更新 更多