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

时间:2016-03-11 01:49:41

标签: c++ syntax

我(有点)自己学习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(); 
}

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

看看thisstd::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;
}

答案 2 :(得分:1)

(我发表了几条评论,他们可能很有趣,可以回答一下,就是这样......)

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

首先,尽可能使用数组(或向量,或其他C++ standard container);如果您不能这样做,请考虑编写某些脚本(用您喜欢的脚本语言)或C ++ 程序 会发出你想要的C ++代码。您需要更新构建过程,例如在Makefile

中添加几行

有时(但可能不适合你)使用C preprocessor的一些技巧就足够了(例如使用X-macro技巧)。您还可以考虑使用一些更强大的预处理器,例如GPP

通常, metaprogramming是一种有用的方法,特别是当您开始编写一些非常重复的代码时。然后考虑使用您的特定工具来生成该代码。这可能是一个脚本(在某些脚本语言中,如Python或awk)或您的专业C ++程序。阅读homoiconic种语言(例如Common Lisp ...),multi-stage programmingpartial evaluation

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

如果你生成巨大的 C ++例程(例如每行超过一万行),你会发现你的C ++编译器需要花费大量的时间来编译这样生成的C ++代码,特别是当你问optimize时(根据经验,g++ -O2需要在源代码中最长例程大小的二次方)。如果遇到此问题,只需修改C ++生成器以生成几个较小的例程。

在Linux或POSIX系统上,您甚至可以考虑让您的程序在运行时生成一些专门的C ++代码(取决于某些输入数据),例如:在/tmp/generated.cc中,然后将编译分配到/tmp/generated.so plugin(例如,使用system(3)运行某些命令,如g++ -Wall -fPIC -O2 -g -shared /tmp/generated.cc -o /tmp/generated.so ...),并使用{{ 3}}(例如void*dlh = dlopen("/tmp/generated.so",RTLD_NOW|RTLD_GLOBAL);然后测试dlh以防止失败,使用失败时dlerror)到dlopen(3)该插件,dynamically load找到一些({{ 1}})那里的符号(并以这种方式填充一些函数指针)。请注意dlsym(3),请阅读name mangling。在实践中,这种方法运行得非常好:我的C++ dlopen mini-howto C程序演示了你可以在Linux上加载数百万个这样的插件(当然实际的瓶颈是在运行时编译生成的插件所花费的时间!你需要几天生成一百万个插件并编译它们)。请注意,extern "C"主程序需要与dlopen-rdynamic相关联。

顺便说一句,您可以考虑在程序中嵌入一些解释器(如manydl.cGuile)......或者使用LuaJIT-compiling {3}}或GCCJITLLVMlibjit。但那是一个不同的故事。

另外,我不确定矢量矢量是2D矩阵的有效表示。我建议让-ldl在内部保留一些class Matrix - s数组并使用内联成员函数(获取维度,获取或放置给定两个索引的特定元素等等)。您可能会找到一些现有的库。