[英]Printing 2-D array through pointers
我的老师给我解决了一个问题,其中:-
1)用户将输入“ n”个三角形。
2)输入“ n”后,用户将输入三角形的边。
3)我们基本上必须打印这些面(基本上是二维数组的问题)。
这是我对问题的执行:-
# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
int main(void)
{
int number_of_triangles; // Takes the value of number of triangles the user will input.
scanf("%d", &number_of_triangles);
int *array;
array = malloc(number_of_triangles * 3 * sizeof(int));
//trying to create a 2D array whose column size is fixed i.e. 3.
int i,j; // Counter variables.
for(i = 0; i < number_of_triangles; i++)
{
for(j = 0; j < 3; j++)
{
scanf("%d", ((array + i) + j)); // Scanning value of sides of triangle.
}
}
for(i = 0; i < number_of_triangles; i++)
{
for(j = 0; j < 3; j++)
{
printf("%d ", (*(array + i) + j));//printing those sides. <-This is the problem statement.
}
printf("\n");
}
return 0;
}
代码工作正常,但我对下面给出的这一行表示怀疑:-
for(i = 0; i < number_of_triangles; i++)
{
for(j = 0; j < 3; j++)
{
printf("%d ", (*(array + i) + j));
//printing those sides. <-This is the problem statement.
}
printf("\n");
}
如果不是printf("%d ", *(*(array + i) + j))
而不是printf("%d ", (*(array + i) + j))
来获取边的值三角形?
如果我把printf("%d ", *(*(array + i) + j))
放进去printf("%d ", *(*(array + i) + j))
我会报错:
间接需要指针操作数(“ int”无效)。
我在C语言中学到的是,要取消对2-D数组指针的引用,我们必须使用前一种方法,而不是我在代码中使用的后一种方法。 我要去哪里错了?
您不能两次取消引用。 您正在处理一维数组,将其用作2D数组。
array + i
类型为int *
,因此*(array + i)
类型为int
,您不能再次取消引用。
相反,您想使用i
和j
获得正确的索引。 您想要的索引是i * 3 + j
:
*(array + i * 3 + j)
但是,使用[]
表示法更漂亮,它是等效的:
array[i * 3 + j]
*(*(array + i) + j))
可以在通过数组指针数组构造2D数组时使用,也可以在使用的类型为多维数组时使用。
例如:
int **array;
array = malloc(number_of_triangles * sizeof(int *));
for (int i = 0; i < number_of_triangles; ++i)
array[i] = malloc(3 * sizeof(int));
for (int i = 0; i < number_of_triangles; ++i)
for (int j = 0; j < 3; ++j)
printf("array[%d][%d]: %d\n", i, j, *(*(array + i) + j)));
(我省去了所有检查分配成功的检查。如果正在使用此代码,则必须包括这些检查。)
请注意,示例的最后一行非常丑陋。 *(*(array + i) + j))
等价于array[i][j]
。 因此可以将其重写:
printf("array[%d][%d]: %d\n", i, j, array[i][j]);
双引用的另一种用法是使用多维数组类型。
例如,如果您提前知道三角形的数量:
int array[5][3];
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 3; ++j)
printf("array[%d][%d]: %d\n", i, j, *(*(array + i) + j)));
在这种情况下,我们利用了数组标识符衰减到指向其第一个元素的指针这一事实。 array + i
是第i
个三角形的指针,因此*(array + i)
是int *
类型的左值int *
指向三角形i
的int
数组3。
*(array + i) + j
是一个int *
指向三角形i
的边j
,因此*(*(array + i) + j))
是该元素的int
类型的左值。
同样,使用数组表示法更漂亮,将*(*(array + i) + j))
替换为array[i][j]
。
对于初学者,您没有分配二维数组。 您分配了带有3 * number_of_triangles
元素的一维数组。
该程序无效,因为在此循环中
for(i = 0; i < number_of_triangles; i++)
{
for(j = 0; j < 3; j++)
{
scanf("%d", ((array + i) + j)); // Scanning value of sides of triangle.
}
}
您正在覆盖已经输入的值。
这个表达
((array + i) + j)
等效于表达式
array + ( i + j)
所以array + ( 0 + 1 )
等于array + ( 1 + 0 )
就是说,如果使用索引,则两个表达式都等于&array[1]
如果您的编译器支持可变长度数组,则程序看起来像
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int number_of_triangles; // Takes the value of number of triangles the user will input.
scanf("%d", &number_of_triangles);
int ( *array )[3] = malloc( sizeof( int[number_of_triangles][3] ) );
for ( int ( *p )[3] = array; p != array + number_of_triangles; ++p )
{
for( int *q = *p; q != *p + 3; ++q )
{
scanf( "%d", q ); // Scanning value of sides of triangle.
}
}
for ( int ( *p )[3] = array; p != array + number_of_triangles; ++p )
{
for( int *q = *p; q != *p + 3; ++q )
{
printf( "%d ", *q );
}
putchar( '\n' );
}
free( array );
return 0;
}
您可以将循环也重写为
for ( int i = 0; i < number_of_triangles; i++ )
{
for( int j = 0; j < 3; j++ )
{
scanf( "%d", *( array + i ) + j ); // Scanning value of sides of triangle.
}
}
for ( int i = 0; i < number_of_triangles; i++ )
{
for( int j = 0; j < 3; j++ )
{
printf( "%d ", *( *( array + i ) + j ) );
}
putchar( '\n' );
}
否则,您必须将一维指针数组分配给一维整数数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.