整数**与整数[const][const]之差
前几天我在写一段代码,我发现很奇怪,int**和int[][]的行为方式不一样。有人能指出他们之间的区别吗?下面是我的示例代码,如果我通过一个恒定大小的2d数组,它会因分段错误而失败,而当我通过一个随机分配的2d数组时,它确实可以正常工作 我感到困惑的主要原因是ant int[]数组的工作原理与int*相同整数**与整数[const][const]之差,c,multidimensional-array,C,Multidimensional Array,前几天我在写一段代码,我发现很奇怪,int**和int[][]的行为方式不一样。有人能指出他们之间的区别吗?下面是我的示例代码,如果我通过一个恒定大小的2d数组,它会因分段错误而失败,而当我通过一个随机分配的2d数组时,它确实可以正常工作 我感到困惑的主要原因是ant int[]数组的工作原理与int*相同 #include<stdio.h> #include<stdlib.h> void sort_by_first_row(int **t, int n, int m)
#include<stdio.h>
#include<stdlib.h>
void sort_by_first_row(int **t, int n, int m)
{
int i, j;
for(i = m-1 ; i > 0 ; --i)
{
for(j = 0 ; j < i; ++j)
{
if(t[0][j] < t[0][j+1])
{
int k;
for(k = 0 ; k < n ;++k)
{
int swap;
swap = t[k][j];
t[k][j] = t[k][j+1];
t[k][j+1] = swap;
}
}
}
}
}
int main(void) {
int i, j;
/* Working version */
/*int **t;
t =(int**) malloc(3*sizeof(int*));
for(i = 0; i < 3; ++i)
{
t[i] = (int*) malloc(6*sizeof(int));
}*/
/*WRONG*/
int t[3][6];
t[0][0] = 121;
t[0][1] = 85;
t[0][2] = 54;
t[0][3] = 89;
t[0][4] = 879;
t[0][5] = 11;
for( i = 0; i < 6; ++i )
t[1][i] = i+1;
t[2][0] = 2;
t[2][1] = 4;
t[2][2] = 5;
t[2][3] = 3;
t[2][4] = 1;
t[2][5] = 6;
sort_by_first_row(t, 3, 6);
for(i = 0; i < 3; ++i)
{
for(j = 0; j < 6; ++j)
printf("%d ", t[i][j]);
printf("\n");
}
return 0;
}
#包括
#包括
按第一行无效排序(int**t,int n,int m)
{
int i,j;
对于(i=m-1;i>0;--i)
{
对于(j=0;j
根据下面的答案,我意识到多维数组是以行的主要顺序连续存储的。经过一些修改后,以下代码起作用:
#include<stdio.h>
#include<stdlib.h>
void sort_by_first_row(int *t, int n, int m)
{
int i, j;
for(i = m-1 ; i > 0 ; --i)
{
for(j = 0 ; j < i; ++j)
{
if(t[j] < t[j+1])
{
int k;
for(k = 0 ; k < n ;++k)
{
int swap;
swap = t[k*m + j];
t[k*m + j] = t[k*m + j+1];
t[k*m + j+1] = swap;
}
}
}
}
}
int main(void) {
int i, j;
/* Working version */
/*int **t;
t =(int**) malloc(3*sizeof(int*));
for(i = 0; i < 3; ++i)
{
t[i] = (int*) malloc(6*sizeof(int));
}*/
/*WRONG*/
int t[3][6];
t[0][0] = 121;
t[0][1] = 85;
t[0][2] = 54;
t[0][3] = 89;
t[0][4] = 879;
t[0][5] = 11;
for( i = 0; i < 6; ++i )
t[1][i] = i+1;
t[2][0] = 2;
t[2][1] = 4;
t[2][2] = 5;
t[2][3] = 3;
t[2][4] = 1;
t[2][5] = 6;
sort_by_first_row(t, 3, 6);
for(i = 0; i < 3; ++i)
{
for(j = 0; j < 6; ++j)
printf("%d ", t[i][j]);
printf("\n");
}
return 0;
}
#包括
#包括
按第一行无效排序(int*t,int n,int m)
{
int i,j;
对于(i=m-1;i>0;--i)
{
对于(j=0;j
我的新问题是:如何修改代码,使过程也能与int[][]和int**一起工作?int**与int[][]有很大不同。int**只是指向指针的指针,如下所示: 实际上,您可以使用指向第一个元素的int*来访问整个多维数组,并从中进行简单的数学运算 以下是单独分配的结果(在您的注释代码中): 但是,当您分配多维数组时,所有内存都是连续的,因此很容易进行简单的数学运算以达到所需的元素
int t[3][6];
int *t = (int*) malloc((3 * 6) * sizeof(int)); // <-- similarly
int t[3][6];
int*t=(int*)malloc((3*6)*sizeof(int));// 认识到int**t
使t
成为指向指针的指针,而int t[3][6]
使t
成为数组的数组。在大多数情况下,当在表达式中使用数组时,它将成为其第一个成员的地址值。因此,对于int t[3][6]
,当t
传递给函数时,该函数实际上将获取&t[0]
的值,该值具有指向数组的类型指针(在本例中为int(*)[6]
)
指针的类型对于指针在索引时的行为非常重要。当指向对象的指针递增5时,它将指向当前对象后面的第5个对象。因此,对于int**t
,t+5
将指向第五个指针,而对于int(*t)[M]
,t+5将指向第五个数组。也就是说,t+5
的结果与&t[5]
的结果相同
在本例中,您已经实现了void sort\u by\u first\u row(int**t,int n,int m)
,但您正在向它传递一个不兼容的指针。也就是说,&t[0]
(这是t
将在main
中变成的类型)与函数想要的类型不同,即int**t
。因此,当排序函数开始使用该地址时,当底层结构是数组数组时,它会将其索引视为指针。Aint**
是指向int
的指针,可以是指向int
数组的指针数组的指针。int[][]
是int
s的二维数组。二维数组在一个方面与C中的一维数组完全相同:它基本上是指向第一个对象的指针。唯一的区别是访问,二维数组可以同时以两种不同的步幅访问。
长话短说,一个int[][]
比一个int**
更接近一个int*
,int t[3][6]
与int t[18]
非常接近。在这两种情况下,都会分配一个由18个整数组成的连续块。变量t
提供st的地址
void sort_by_first_row(int t[][6], int n)
void sort_by_first_row(int t[3][6])
void f(int* t, int m, int n)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
std::cout << t[i * n + j] << " ";
std::cout << std::endl;
}
void f2(int t[][6], int m)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < 6; j++)
std::cout << t[i][j] << " ";
std::cout << std::endl;
}
int main()
{
int t[3][6];
int val = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 6; j++)
{
t[i][j] = val;
val++;
}
}
f(&(t[0][0]), 3, 6);
f2(t, 3);
return 0;
}