我仍然是 C++ 的新手,我一直在尝试模块化提供给我的一些意大利面条代码。到目前为止(除了学习如何使用 git 和安装 rarray 库以用它们替换自动数组之外)我一直对如何模块化事物然后通过 make 编译它感到困惑。
我知道我必须在 header 中创建原型(prototype),从我的函数创建我的目标文件,然后用“驱动程序”代码编译它。运行/编写 make 文件不是我关心的,但它是如何开始像这样模块化代码;我不确定如何创建修改数组的函数!
任何指向正确方向的指示都会很棒。如有必要,我可以澄清更多。
#include <cmath>
#include <iostream>
#include <rarray> // Including the rarray library.
#include <rarrayio> // rarray input/output, if necessary. Probably not.
int main()
{
// ants walk on a table
rarray<float,2> number_of_ants(356,356);
rarray<float,2> new_number_of_ants(356,356);
rarray<float,2> velocity_of_ants(356,356);
const int total_ants = 1010; // initial number of ants
// initialize
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
velocity_of_ants[i][j] = M_PI*(sin((2*M_PI*(i+j))/3560)+1);
}
}
int n = 0;
float z = 0;
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
number_of_ants[i][j] = 0.0;
}
}
while (n < total_ants) {
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
z += sin(0.3*(i+j));
if (z>1 and n!=total_ants) {
number_of_ants[i][j] += 1;
n += 1;
}
}
}
}
// run simulation
for (int t = 0; t < 40; t++) {
float totants = 0.0;
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
totants += number_of_ants[i][j];
}
}
std::cout << t<< " " << totants << std::endl;
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
new_number_of_ants[i][j] = 0.0;
}
}
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
int di = 1.9*sin(velocity_of_ants[i][j]);
int dj = 1.9*cos(velocity_of_ants[i][j]);
int i2 = i + di;
int j2 = j + dj;
// some ants do not walk
new_number_of_ants[i][j]+=0.8*number_of_ants[i][j];
// the rest of the ants walk, but some fall of the table
if (i2>0 and i2>=356 and j2<0 and j2>=356) {
new_number_of_ants[i2][j2]+=0.2*number_of_ants[i][j];
}
}
}
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
number_of_ants[i][j] = new_number_of_ants[i][j];
totants += number_of_ants[i][j];
}
}
}
return 0;
}
最佳答案
I've been sort of stumped as to how to modularize things and then compile it via make.
部分原因可能是您尝试模块化的代码。模块化是一种习惯用法,通常用于帮助分离问题域,这样如果一个代码区域出现问题,它就不一定*影响另一个区域,并且在构建更大的应用程序时特别有用;模块化也是面向对象设计中类的重点之一。
*关于“意大利面条化”,也就是说,如果代码真的是“意大利面条代码”,经常修改或修复一个代码区域肯定会影响代码的其他区域,产生意想不到或无法预料的后果,换句话说,不是模块化的。
您发布的代码是 63 行(主要功能),实际上不需要任何模块化。虽然如果你愿意,你会想看看什么可以被模块化以及什么应该是,但是再一次,没有太多的方式来分离out,除了制作单独的功能(这只会增加代码量)。既然你特地问过
I'm not sure how to make functions that modify arrays!
这可以通过以下方式完成:
// to pass a variable by reference (so as to avoid making copies), just give the type with the & symbol
void run_simulation(rarray<float,2>& noa, rarray<float,2>& new_noa, rarray<float,2>& voa)
{
// do something with the arrays
}
int main()
{
// ants walk on a table
rarray<float,2> number_of_ants(356,356);
rarray<float,2> new_number_of_ants(356,356);
rarray<float,2> velocity_of_ants(356,356);
...
run_simulation(number_of_ants, new_number_of_ants, velocity_of_ants);
...
}
此外,应该注意您的代码中存在潜在错误;在 run simulation
循环下,您声明 float totants = 0.0;
然后对该变量进行操作直到循环结束,此时您仍使用 对其进行修改totants += number_of_ants[i][j];
.如果此变量是用于保持“运行”总数而不被重置,则需要将 totants
声明移到 for
循环,否则,严格来说,最后的 totants +=
语句是不必要的。
希望这可以帮助增加一些清晰度。
关于c++ - 模块化意大利面条代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35007152/