我有一个函数可以获取一堆粒子的速度矩阵,并尝试计算粒子的总动能。
它没有给我正确的价值。为了调试,我在函数中添加了一些printf("value: %e \n", energy)
。
现在,返回值取决于我留下的printf
中有多少人没有注释。
double GetKineticEnergy(int dim, int nParticles, double vel[nParticles][dim], double mass)
{
int i,j;
double sum;
double energy = 0;
for(i=0;i<nParticles;i++) {
sum = 0;
for(j=0;j<dim;j++) {
sum += vel[i][j]*vel[i][j];
}
energy += sum*mass/2;
// printf("energy: %e \n", energy);
}
// printf("total: %e \n", energy);
return(energy);
}
并在返回调用者后立即打印返回的值。我得到18.0
,19.0
,21.0
或24.0
,具体取决于printf
我取消注释的组合。
我做错了什么?
更新
在尝试解决此问题时,我已经评论了几乎所有内容。该功能简化为
{
double energy = 123;
return(energy);
}
主程序是
int main() {
double a;
double vel[5][5];
a = GetKineticEnergy(1, 1, vel, 1);
printf("value: %e \n", a);
}
我得到了
value: 0.000000e+00
作为输出。
更新
如果我硬编码2D数组double vel[][3]
的第二维,问题就会消失。目前,这似乎是一个有用的解决方案,但我对这种类型的硬编码感到畏惧。
答案 0 :(得分:1)
如果GetKineticEnergy
函数位于不同的文件中且原型不可用,则可能发生这种情况。考虑在main
中声明其原型或包含必需的头文件。
答案 1 :(得分:0)
您已调用未定义的行为。
当您面对来自C程序的看似无法解释的行为时,通常是未定义行为的结果。以下是您应该研究的一些潜在问题:
编译器警告
默认情况下,编译器通常会省略许多重要的警告消息,您必须自己启用它们。由于添加了代码分析,在启用优化的情况下进行编译还可以激活一些其他警告消息。如果您正在使用GCC,则至少应使用gcc -ansi -pedantic -W -Wall -O2
之类的内容。
功能原型
您是否为所有代码中的函数提供了正确的函数声明(带原型)?如果没有正确的GetKineticEnergy()
声明,编译器会将最后一个参数作为int
传递,并假设返回类型为int
。
你有#include <stdio.h>
吗? printf()
是一种可变函数。变量函数通常需要与普通函数不同的调用约定。在没有正确原型的情况下调用可变参数函数会导致未定义的行为。
缓冲区溢出
您为传递给函数的数组分配了足够的内存,还是指定了足够大的内容?你传递的是正确的尺寸吗?访问超出缓冲区限制的元素可能会导致令人费解的结果,尤其是在启用了优化的情况下。