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

Copying char**** as contiguous data to a char* variable

本文关键字:char 复制 变量 数据 连续      更新时间:2023-10-16

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

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

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

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

您似乎对sizeof的功能有严重的误解。

sizeof(x)返回对象x的大小(以字节为单位)。当处理指针时,sizeof(*x)通常不会与相同,x指向的元素数

还要注意,在使用的情况下,sizeof(x)是在编译时决定的值,sizeof(*x)甚至不查看x指向的内容(只查看对象x指向的类型:例如,对于int *x = NULL;,表达式sizeof(*x)sizeof(int)相同)。

此外,您需要了解ints:的多维数组之间的区别

int x[10][10];

以及指向指向CCD_ 16:的指针的指针

int **y;

即使两者可以使用相同的语法来取消引用

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

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

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

IFF如果知道多维数组的单个大小,就可以在单个循环中压平数组。不过,应该注意的是,与一些嵌套循环相比,在1个循环中扁平化数组实际上可能不会提高性能;它可能取决于编译器的优化(如矢量化)和平台/体系结构,如果必须确定每个嵌套数组的大小,那么在大循环的顶部,性能会受到影响。YMMV,所以最好做一些小规模的基准测试来验证它是否达到了您想要的结果和性能。

以下是一些关于如何展平数组的示例代码;请注意,我在本例中使用了std::string类型,这样您就可以运行代码并打印到文件/stdout,以查看数组是否确实已被展平。

#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;
}

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

我希望这能有所帮助。