c - 通过指针打印二维数组

标签 c

我的老师给了我一个问题来解决:-

1) User will input "n" number of triangles.

2) After inputting "n", The user will input the sides of triangles.

3) We basically have to print those sides (Basically a question of 2-D arrays).

这是我对问题的实现:-

# 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)) 然后我会收到错误:-

Indirection requires pointer operand ('int' invalid).

我在 C 中学到的是,为了取消引用二维数组指针,我们必须使用前一种方法,而不是我在代码中使用的后一种方法。我哪里出错了?

最佳答案

您不能取消引用两次。您正在处理一个一维数组,并将其用作二维数组。

array + i 的类型为 int *,因此 *(array + i) 的类型为 int,您无法再次取消引用。

相反,您希望使用 ij 来获取正确的索引。您想要的索引是i * 3 + j:

*(array + i * 3 + j)

但是使用 [] 表示法要漂亮得多,它是等效的:

array[i * 3 + j]
<小时/> 当您有一个通过指向数组的指针数组构造的二维数组时,或者当使用的类型是多维数组时,可以使用

*(*(array + i) + j)) .

例如:

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 * 类型的左值 指向三角形 iint 数组 3。

*(array + i) + j 是一个 int *,指向三角形 i 的边 j >,因此 *(*(array + i) + j)) 是该元素的 int 类型的左值。

同样,使用数组表示法会更漂亮,将 *(*(array + i) + j)) 替换为 array[i][j]

关于c - 通过指针打印二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57661397/

相关文章:

c - pthread C 中的线程队列 - Web 服务器响应流水线

c++ - c\c++ - 以 union 作为参数以满足特定要求的函数

c - 缩进#define

c - 反转命令行参数 (C)

c - memcpy() 无法正常工作

c:以十六进制表示形式逐个字符发送字符串

c - 在解密消息的末尾打印了一些额外的字符

用于查找和修改/替换 .c 文件中的字符串的 C++ 代码

c - 如何使用指针执行冒泡排序

c++ - 如何告诉 C++ 根据索引指示符放弃 vector 中的某些元素