是否可以使用循环来声明多个变量?并创建文件

Is it possible to use a loop to declare multiple variables? And to create files?

本文关键字:变量 创建 文件 可以使 循环 声明 是否      更新时间:2023-10-16

我(有点)自己学习了 c++ 用于物理目的,所以如果这是一个简单的问题,我深表歉意。我试图自己使用谷歌找到答案,但我没有找到任何有用的东西(可能是因为我不确定要使用哪种搜索词)。

对于我的 c++ 程序,我必须声明 100 个(或更多)变量,如下所示:

vector< vector<double> > pol1_t1_matrix(SPACE_pol, vector<double>(2));
vector< vector<double> > pol1_t2_matrix(SPACE_pol, vector<double>(2));
vector< vector<double> > pol1_t3_matrix(SPACE_pol, vector<double>(2));
vector< vector<double> > pol1_t4_matrix(SPACE_pol, vector<double>(2));
vector< vector<double> > pol1_t5_matrix(SPACE_pol, vector<double>(2));
vector< vector<double> > pol1_t6_matrix(SPACE_pol, vector<double>(2));
vector< vector<double> > pol1_t7_matrix(SPACE_pol, vector<double>(2));
vector< vector<double> > pol1_t8_matrix(SPACE_pol, vector<double>(2));
vector< vector<double> > pol1_t9_matrix(SPACE_pol, vector<double>(2));
vector< vector<double> > pol1_t10_matrix(SPACE_pol, vector<double>(2));
etc.;

我还使用这些来编写文件,如下所示:

ofstream outputFile_2D_pol1_t1("gnu_2D_pol1_t1_matrix_2sol_num.dat"); 
for(i=0;i<SPACE_pol;i=i+1)
{
    outputFile_2D_pol1_t1 << x_begin + (i * h_pol) << setw(18);
    outputFile_2D_pol1_t1 << pol1_t1_matrix[i][1] << setw(18);
    outputFile_2D_pol1_t1 << endl;
}
outputFile_2D_pol1_t1.close(); 
ofstream outputFile_2D_pol1_t2("gnu_2D_pol1_t2_matrix_2sol_num.dat"); 
for(i=0;i<SPACE_pol;i=i+1)
{
    outputFile_2D_pol1_t2 << x_begin + (i * h_pol) << setw(18);
    outputFile_2D_pol1_t2 << pol1_t2_matrix[i][1] << setw(18);
    outputFile_2D_pol1_t2 << endl;
}
outputFile_2D_pol1_t2.close();
ofstream outputFile_2D_pol1_t3("gnu_2D_pol1_t3_matrix_2sol_num.dat"); 
for(i=0;i<SPACE_pol;i=i+1)
{
    outputFile_2D_pol1_t3 << x_begin + (i * h_pol) << setw(18);
    outputFile_2D_pol1_t3 << pol1_t3_matrix[i][1] << setw(18);
    outputFile_2D_pol1_t3 << endl;
}
outputFile_2D_pol1_t3.close();
etc.;
如果我必须这样做超过 100 次

(至少到 t100 次,上述内容将变得非常费力,但有时我将不得不这样做 1000 次或更多)。所以我的问题是:有没有办法使用(单独的)循环来完成上述所有操作?

天真地,我会假设它看起来像这样(以替换费力的"变量声明",如上所示):

for(i=1;i<101;i=i+1)
{
    double (pol1_t"i"_matrix)[2] = new double[SPACE_pol][2];
}

和(替换费力的"写入文件",如上所示):

for(i=1;i<101;i=i+1)
{
        ofstream outputFile_2D_pol1_t"i"("gnu_2D_pol1_t"i"_matrix_2sol_num.dat"); 
        for(j=0;j<SPACE_pol;j=j+1)
        {
            outputFile_2D_pol1_t"i" << x_begin + (j * h_pol) << setw(18);
            outputFile_2D_pol1_t"i" << pol1_tj_matrix[i][1] << setw(18);
            outputFile_2D_pol1_t"i" << endl;
        }
        outputFile_2D_pol1_t"i".close(); 
}

你不想使用new,特别是使用原始指针。我相信您的程序目前因此泄漏内存。坚持使用嵌套向量。

您可以嵌套三个向量,但仅使用为此设计的类可能会更容易,例如 Boost.MultiArray

(我给出了几条评论,它们可能很有趣,可以做出答案,就是这样......

如果可以,至少使用 C++11。 例如,如果使用最近的 GCC 进行编译,请使用 g++ -std=c++11 -Wall(调试时也可能-g)...

首先,如果可能的话,使用数组(或向量,或其他一些C++标准容器);如果你不能做到这一点,考虑编写一些脚本(用你最喜欢的脚本语言)或一个C++程序,它会发出你想要的C++代码。您需要更新构建过程,例如在Makefile中添加几行

有时(但可能不是在您的情况下)使用带有 C 预处理器的一些技巧就足够了(例如,使用 X 宏技巧)。您也可以考虑使用一些更强大的预处理器,例如GPP。

一般来说,元编程是一种有用的方法,特别是当你开始编写一些非常重复的代码时。然后考虑使用您的特定工具来生成该代码。这可以是一个脚本(在某些脚本语言中,如Python或awk)或您的专用C++程序。阅读有关同象语言(如Common Lisp...),多阶段编程,部分评估的信息。

在编写一些(例如C++)代码生成器时,一个有用的建议是:在内存中保留一些AST格式,例如发出代码的表示形式(因此,首先构建整个生成代码的AST,然后打印它)。

如果你生成了大量的C++例程(例如,每个例程超过一万行),你会发现你的C++编译器需要花费大量时间来编译这种生成的C++代码,特别是当你要求它优化时(从经验上讲,g++ -O2需要的时间是源代码中最长例程大小的二次元)。如果遇到此问题,只需修改C++生成器即可生成几个较小的例程。

在 Linux 或 POSIX 系统上,您甚至可以考虑让您的程序在运行时生成一些专门的C++代码(取决于一些输入数据),例如在 /tmp/generated.cc 中,然后将编译分叉到/tmp/generated.so插件中(例如使用 system(3) 运行一些命令,如 g++ -Wall -fPIC -O2 -g -shared /tmp/generated.cc -o /tmp/generated.so ...),并使用 dlopen(3)(例如 然后void*dlh = dlopen("/tmp/generated.so",RTLD_NOW|RTLD_GLOBAL);测试dlh失败,使用 dlerror on failure)动态加载该插件,dlsym(3) 在那里找到一些(extern "C")符号(并以这种方式填充一些函数指针)。当心名称混乱,所以请阅读C++ dlopen 迷你指南。在实践中,这种方法的效果出奇地好:我的manydl.c C程序演示了你可以在Linux上加载数百万个这样的插件(当然,实际的瓶颈是在运行时编译生成的插件所花费的时间!你需要几天的时间才能生成一百万个插件并编译它们)。请注意,dlopen -ing 主程序需要与 -rdynamic-ldl 链接。

顺便说一句,你也许可以考虑在你的程序中嵌入一些解释器(如 Guile 或 Lua)......或者使用一些JIT编译库,如GCCJIT或LLVM,libjit或asmjit。但那是另一回事了。

另外,我不确定向量的向量是否是 2D 矩阵的有效表示。我建议有一个class Matrix在内部保留一些 double -s 数组并具有内联成员函数(获取维度、获取或放置给定两个索引的特定元素等)。您可能会发现一些现有的库正在这样做。

看看这个。 std::vector动态分配的,请参阅修饰符部分。所以你可以声明它的大小为零、十、...无论什么。这里的关键是您可以在执行期间调整其大小并添加内容,然后使用简单的索引 [i] 访问其元素。例程是在一个 for 循环(如果你在执行过程中得到了大小)或一个 while 循环(如果从文件 f.e 读取),你可以在每次迭代时push_back()元素。您最终会得到循环迭代大小的数组。很好。

这是双精度数二维向量的基本演示,需要#include <vector>

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<vector<double>> my2dVector; // vector of vectors<double>. initially its size is zero-by-zero and it's possible to assign an initial size.
    vector<double> temp; // this will hold data for everyrow. Notice the clear() in the beginning of the outerloop and the push_back() at the end of it
    for (int Rows = 0; Rows < WhateverDesiredRowSize; Rows++)
    {
        temp.clear();
        for (int Columns = 0; Columns < WhateverDesiredColumnSize; Columns++)
        {
            // here you push_back into temp. Imagine it as the row. So you fill the whole 2d structure row-by-row
            temp.push_back(WhateverDoubleDataYouWant);
        }
        // here you push the whole row into your 2d structure
        my2dVector.push_back(temp);
    }
    return 0;
}