保存二维数组中的元素

问题描述 投票:0回答:1

我如何在二维数组中保存数字?为什么这段代码不工作?

void input_arr(int *arr, int n, int m);

void print_arr(int *arr, int n, int m);

int main()
{
    int *arr;
    int n, m;

    printf("Insert line of array: ");
    scanf("%d", &n);

    printf("Insert column of array: ");
    scanf("%d", &m);

    arr = calloc(n * m, sizeof(int));

    input_arr(arr, n, m);

    return 0;
}

void input_arr(int *arr, int n, int m)
{
    int i;
    int j;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            printf("Insert element in line %d and column %d: ", i, j);
            scanf("%d", (&arr[i][j]));
        }
    }
}

void print_arr(int *arr, int n, int m)
{
    int i, j;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            printf("%d ", *arr[i][j]);
        }
    }
}
c arrays multidimensional-array
1个回答
1
投票

你传递的是一个指向分配空间的指针,这就像存储一个线性数组一样,要做到你想要的,一个二维数组,或者可以用同样方式使用的东西,你需要。

  1. 一个由线的指针组成的数组 为每一个指针分配内存,以模拟列。
  2. 双指针,并为其分配内存,以模拟行和列的方式存储值。
  3. 你也可以使用线性数组,让输入和输出看起来像一个2D数组。
  4. 或者你可以直接使用一个普通的2D数组。

由于你使用的是内存分配 这里是一个可能的实现 使用双指针。

#include <stdio.h>
#include <stdlib.h>

void input_arr(int **arr, int n, int m); //double pointer to int parameter
void print_arr(int **arr, int n, int m); //same

int main() {

    int n, m;
    int **arr; //double pointer for 2D array like memory allocation

    printf("Insert line of array: ");

    if(scanf("%d", &n) != 1 || n < 1) {  //always check input
        puts("positive integer value expected!"); 
        return 1;
    }

    printf("Insert column of array: ");

    if(scanf("%d", &m) != 1 || m < 1) {  //always check input
        puts("positive integer value expected!");
        return 1;
    }

    if(!(arr = malloc(n * sizeof(*arr)))){ //allocate memory lines, check for errors
        perror("Memory allocation failed!");
        return 1;
    }

    for(int i = 0; i < n; i++)
        if(!(arr[i] = malloc(m * sizeof(**arr)))) { //allocate memory for columns, check for errors
            perror("Memory allocation failed");
            return 1;
        }

    input_arr(arr, n, m);
    print_arr(arr, n, m);

    return 0;
}

void input_arr(int **arr, int n, int m) {

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            printf("Insert element in line %d and column %d: ", i, j);
            scanf("%d", &arr[i][j]);
        }
    }
}

void print_arr(int **arr, int n, int m) {

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            printf("%d ", arr[i][j]); //no dereferencing
        }
        putchar('\n');
    }
}

2
投票

替换你的函数声明,就像这样

void input_arr(int *arr[], int n, int m)
void print_arr(int *arr[], int n, int m)

只要你有 scanfprintf 调用数组元素,用这个。

scanf("%d", arr + i * m + j);
printf("%d", *(arr + i * m + j));

为了保证良好的实践,当你完成后,释放你的内存。在你的 main():

free(arr);

另外,如果你有一个C99或更高版本的编译器,你可以使用 可变长度数组 来完成这项工作,并允许你用 arr[i][j] 而不是丑陋 arr + i * m + j.

#include <stdio.h>
#include <stdlib.h>

//note that the arr parameter must be declared AFTER the m parameter since it uses its information
void input_arr(int n, int m, int arr[][m]);

void print_arr(int n, int m, int arr[][m]);

int main(void)
{
    int n, m;

    printf("Insert line of array: ");
    scanf("%d", &n);

    printf("Insert column of array: ");
    scanf("%d", &m);

    int arr[n][m];

    input_arr(n, m, arr);

    print_arr(n, m, arr); //I am assuming you also want to print the array

    //return 0; //not needed in C99
}

void input_arr(int n, int m, int arr[][m])
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            printf("Insert element in line %d and column %d: ", i, j);
            scanf("%d", &arr[i][j]);
        }
    }
}

void print_arr(int n, int m, int arr[][m])
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            printf("%d ", arr[i][j]);
        }
        //you probably want a new line here to display it as a matrix
        printf("\n");
    }
}

1
投票

代码分配和初始化一个连续的内存块,并将一个指针传递给 int 的函数。问题是,在这些函数里面,这个指针被重新引用了太多次。

void input_arr(int *arr, int n, int m)
{
    // ...
    scanf("%d", (&arr[i][j]));
    //                  ^^^ 
}

void print_arr(int *arr, int n, int m)
{
    // ...
    printf("%d ", *arr[i][j]);
    //            ^      ^^^
}

如果你可以使用可变长度的数组,那么与其他答案中已经发布的答案不同的选择是在这些函数中声明一个指向VLA的指针。

void input_arr(int *arr, int n, int m)
{
    // ...
    scanf("%d", arr++);
    //          ^^^ Here you can just access to every element in order 
}

void print_arr(int *arr, int n, int m)
{
    // Declare a pointer to array of m elements
    int (*mat)[m] = (void *)arr;

    // ...
    printf("%d ", mat[i][j]);
    //            ^^^^^^^^^  Use it as if it's a 2D VLA
}

另外,记得在函数中释放分配的内存 main.


1
投票

如何在二维数组中保存数字?

例子:

int twoD[2][3];
twoD[1][1] = 42;

为什么这段代码不能用?

OP的代码没有使用二维数组,而是使用了一个指向 int 然后错误地使用该指针。

int *arr;
// Allocate memory for a 1-D array of  n*m `int` 
arr = calloc(n * m, sizeof(int));

函数代码试图去引用一个叫做 int

void input_arr(int *arr, int n, int m) {
  ...
  scanf("%d", (&arr[i][j])); // bad

arr[i] 是一个 int. arr[i][j] 没有意义。


要分配内存,你需要一个指针,但什么类型的呢?

你想要一个指向一个二维数组的指针,下面,一个指向数组的 int [m] DarkAtom 或指向数组指针的指针。int @anastaciu?

int (*TwoD)[m][n] = malloc(sizeof *Two);
(*TwoD)[1][1] = 42;
....

或者用类似2D的方式使用当前代码,用计算出的索引访问1D数组分配。

// scanf("%d", (&arr[i][j]));
scanf("%d", &arr[i*m + j]);

// printf("%d ", *arr[i][j]);
printf("%d ", arr[i*m + j]);

0
投票

你需要将数组作为一个双指针(int **array或更简单的int *array[])来传递。

解释通过将数组传递为int*数组,当你说&array[i]时,你推断的是数组的复制值,而不是原始值.具体来说,在一个函数中,当你只是想读取(或打印)数组数据时,你可以简单地使用单指针,但如果你想改变它,你必须使用双指针。

© www.soinside.com 2019 - 2024. All rights reserved.