将char ****作为连续数据复制到char *变量

时间:2015-11-28 04:59:47

标签: c++ pointers

如何在不使用嵌套循环的情况下将char**** first中的所有内容复制到连续变量:char* second

例如,我可以使用嵌套的for循环,如下所示:

for (size_t a=0; a < sizeof(***first); a++) {
    for (size_t b=0; b < sizeof(**first); b++) {
      //etc
    }
}

我只是想知道这是否可行。

2 个答案:

答案 0 :(得分:2)

您似乎对sizeof所做的事情存在严重误解。

sizeof(x)返回对象x字节中的大小。处理指针sizeof(*x)时,x指向的元素数通常不一样。

另请注意,在您使用的情况下,sizeof(x)是在编译时决定的值,而sizeof(*x)甚至不查看x 1}}指向(仅查看对象x指向的 类型):例如int *x = NULL;表达式sizeof(*x)是与sizeof(int))相同。

此外,您需要了解int s:

的多维数组之间的区别
int x[10][10];

和指向int的指针:

int **y;

即使可以使用相同的语法取消引用这两个

x[1][2] = 42;
y[1][2] = 42;

意思是完全不同。更具体地说,例如y[0]y[1]可能指向不同大小的数组(的第一个元素),它们可能是NULL或者可能指向单个整数({{1} }和y[0]甚至可以指向同一个对象。)

没有办法将指针指针数据结构复制到没有循环的多维数组中,因为这两个数据通常是具有完全不同形状的对象。

答案 1 :(得分:1)

IFF你知道多维数组的各个大小,你可以在一个循环中展平数组。应该注意的是,虽然你可能没有看到在一个循环中扁平化数组而不是有一些嵌套循环的性能提升;它可以依赖于您的编译器优化(如矢量化)和平台/体系结构,如果您必须确定每个嵌套数组的大小,您将在大循环之上产生性能影响。 YMMV,所以最好做一些小规模的基准测试,以验证它能达到你想要的结果和性能。

以下是关于如何展平数组的一些示例代码;请注意,我在此示例中使用的是std::string类型,因此您可以运行代码并打印到文件/标准输出以查看数组确实已被展平。

#include <iostream>
#include <string>
#include <sstream>

void flatten(std::string**** first, int len_a, int len_b, int len_c, int len_d, std::string* second)
{
    int i, a, b, c, d;
    int max_len = len_a * len_b * len_c * len_d;
    a = b = c = d = -1;
    for (i = 0; i < max_len; ++i) {
        d = (i % len_d);
        // if all lengths were equal, you could further optimize this loop
        if (d == 0) {
            ++c;
            if ((c % len_c) == 0) {
                c = 0;
                ++b;
                if ((b % len_b) == 0) {
                    b = 0;
                    ++a;
                }
            }
        }
        second[i] = first[a][b][c][d];
    }
}

int main()
{
    const int len_a = 11;
    const int len_b = 22;
    const int len_c = 33;
    const int len_d = 44;
    const int max_len = len_a * len_b * len_c * len_d;
    // create the arrays
    std::string**** first = new std::string***[len_a];
    std::string* second = new std::string[max_len];
    for (int i1 = 0; i1 < len_a; ++i1) {
        first[i1] = new std::string**[len_b];
        for (int i2 = 0; i2 < len_b; ++i2) {
            first[i1][i2] = new std::string*[len_c];
            for (int i3 = 0; i3 < len_c; ++i3) {
                first[i1][i2][i3] = new std::string[len_d];
                for (int i4 = 0; i4 < len_d; ++i4) {
                    std::stringstream ss;
                    ss <<"["<<i1<<"]["<<i2<<"]["<<i3<<"]["<<i4<<"]";
                    first[i1][i2][i3][i4] = ss.str(); // or what have you
                }
            }
        }
    }

    // flatten the multidimensional array 'first' into the array 'second'
    flatten(first, len_a, len_b, len_c, len_d, second);

    // print it
    for (int i1 = 0; i1 < max_len; ++i1) {
        std::cout<<"second["<<i1<<"] = "<<second[i1]<<std::endl;
    }

    // clean up
    delete[] second;
    for (int i1 = 0; i1 < len_a; ++i1) {
        for (int i2 = 0; i2 < len_b; ++i2) {
            for (int i3 = 0; i3 < len_c; ++i3) {
                delete[] first[i1][i2][i3];
            }
            delete[] first[i1][i2];
        }
        delete[] first[i1];
    }
    delete[] first;
    return 0;
}

同样,这显然不是一个安全/干净/有效的方法来做你想要的,但我只是想证明你可以实现它,我会留下更多的效率/实施细节给你

我希望可以提供帮助。