Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在运行时将一维数组视为二维数组_C_Arrays - Fatal编程技术网

C 在运行时将一维数组视为二维数组

C 在运行时将一维数组视为二维数组,c,arrays,C,Arrays,我有一些数据存储在一个一维数组中,大小为“M”。现在我需要将其视为一个二维数组,其维数为NxP,其中N和P的乘积等于M。我只在运行时知道N和P的值。如何在C中实现这样一个函数 int array[M]; /* one dimensional array where some data is stored*/ int** newArray; /* the dimension of newArray should be NxP such that we can access the data in

我有一些数据存储在一个一维数组中,大小为“M”。现在我需要将其视为一个二维数组,其维数为NxP,其中N和P的乘积等于M。我只在运行时知道N和P的值。如何在C中实现这样一个函数

int array[M]; /* one dimensional array where some data is stored*/
int** newArray; /* the dimension of newArray should be NxP such that we can access the data in 'array' as a two-dimensional array*/

您不需要定义新数组。您可以使用现有的

假设您知道N和p,并且N是行数,您可以访问项(i,j),如下所示:


你可以这样做:

int ** newArray = malloc(sizeof(int*) * N);
for (i = 0; i < N; ++i) {
  newArray[i] = array[i * J];
}
int**newArray=malloc(sizeof(int*)*N);
对于(i=0;i
这将使一个数组“看起来”就像动态分配的由N行和J列组成的2D数组,但实际上指向1D数组的行


这样,如果您已经有函数在2D数组上运行,则无需重写它们以使用其他答案中描述的1D语法。

运行时会使这一点变得更困难,但是:-

newArray = malloc( sizeof( int*) * N ); /* create an array of pointers.
{ 
     size_t i;
     for( i = 0; i < N; i++ ) {
         newArray[i] = &array[ i* P];
     }
}
newArray=malloc(sizeof(int*)*N);/*创建一个指针数组。
{ 
尺寸i;
对于(i=0;i

/*现在newArray[i][j]可用*/

只需将其强制转换为适当的数组指针类型:

int (*newArray)[N] = (int (*)[N])array;
之后,您可以通过以下方式访问阵列:

for(int y = 0; y < P; y++) {
    for(int x = 0; x < N; x++) {
        array[y][x] = 42;
    }
}
for(int y=0;y
这相当于以下索引:

for(int y = 0; y < P; y++) {
    for(int x = 0; x < N; x++) {
        newArray[y*N + x] = 42;
    }
}
for(int y=0;y

即使只有在C99之后的运行时才知道
N
,这也可以工作。请注意,您不需要这样设置索引数组,如果使用
int**

则必须这样做,您可以将1d数组强制转换为所需的2d数组。这只是一块内存

int _tmain(int argc, _TCHAR* argv[])
{
    int oneDArray[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
    int(*twoDArray)[3] = (int(*)[3])&oneDArray[0]; // This is the magic line!

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            printf("i: %d j: %d value: %d\r\n", i, j, twoDArray[i][j]);
        }
    }

    _getch();

    return 0;
}
int-tmain(int-argc,_-TCHAR*argv[]
{
int oneDArray[12]={0,1,2,3,4,5,6,7,8,9,10,11};
int(*twoDArray)[3]=(int(*)[3])&oneDArray[0];//这是一条神奇的线!
对于(int i=0;i<4;i++)
{
对于(int j=0;j<3;j++)
{
printf(“i:%d j:%d值:%d\r\n”,i,j,twoDArray[i][j]);
}
}
_getch();
返回0;
}
另见问题


这样做有一些内在的不安全性,但是你的问题表明NxP=M,所以如果这是真的,它会起作用。人们会皱眉。< /P>“我如何在C中实现这样的函数?”——THSULY,删除C++标签。@ WOZKRAIG:谢谢编辑。如果<代码> N>代码>行数,索引方程是错误的。如果是列数,则是正确的。感谢您的回复。但我想访问它作为二维数组与两个索引。谢谢你的答复。我想避免额外的内存分配!然后在堆栈上声明它,如
int*newArray[N]而不是mallocing。因为你在回答中说了
int**
,所以我认为你想要malloc。请注意,如果您返回它,虽然您将不得不malloc它。感谢您的回复。我想避免额外的内存分配!是的,这是正确的方法,指向指针的指针从一开始就是错误的工具。对于3D阵列(例如,
array[X][Y][Z]
),这会是什么情况?我尝试了
int(*newArray)[X][Y]=(int(*)[X][Y])array
,它不起作用:-/@ijverig这是错误的:它是指针中省略的最外面的维度。因此,对于维度顺序
数组[X][Y][Z]
,您需要删除
[X]
int(*newArray)[Y][Z]=(int(*)Y][Z])数组
@ijverig注意,我们通常在C:
数组[Z][Y][X]
中使用相反的维度顺序,因此
int(*newArray)[Y][X]=(int(*)Y][X])数组
这样,我们将
数组[z][y]
中一行的所有
X
值存储在一起。我当天的投票限额已超过,但如果没有,我会加上一个:)谢谢你的这个小把戏,确保你明白发生了什么。c中的指针只是内存,所以可以将其视为包含任何内容。但是如果你把索引弄错了,c不在乎你读的内容是否超过了实际分配的末尾,这是人们对c/c++最大的抱怨,这就是缓冲区溢出。我的意思是,c在结构对齐方面有很多陷阱,有时东西放在哪里并不直观,例如,请看这里,但我猜数组总是连续的,因此在您的示例中,转换为
*int[3]
是可以的。关键是
int[12]
int
边界对齐,否则偏移量总是一个线性级数(如果不是这样的话,通常取消对数组的引用会慢得多)。我认为即使使用
struct foo[12],您的技巧也可以
如果您的数据类型在两个数组定义中保持不变,您就不必担心它的存储方式,因为编译器知道int是x字节,所以索引0是字节0,索引1是字节(1 x sizeof(int))等等,如果您做了一些疯狂的事情,比如将阵列保存到磁盘,然后在具有不同体系结构的计算机上重新加载它,而该体系结构对int的定义不同,那么您就会遇到问题。(非常确定INT在不同的体系结构上可以有不同的大小。)
int _tmain(int argc, _TCHAR* argv[])
{
    int oneDArray[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
    int(*twoDArray)[3] = (int(*)[3])&oneDArray[0]; // This is the magic line!

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            printf("i: %d j: %d value: %d\r\n", i, j, twoDArray[i][j]);
        }
    }

    _getch();

    return 0;
}