C语言 如何动态实现具有不同列大小的二维数组?

bq9c1y66  于 2022-12-03  发布在  其他
关注(0)|答案(3)|浏览(195)

如何在C中动态实现一个具有不同列大小的二维数组?
我尝试了很多方法来实现一个二维数组动态与不同的列大小在c但我不能得到它。
请告诉我一个建议...

dluptydi

dluptydi1#

首先读取行大小(这里行大小是r)然后声明二维数组&一维数组如下:int a[r][100],n[r];然后,读取一维数组元素(这些只是不同的列大小),最后读取二维数组元素。

f4t66c6m

f4t66c6m2#

//Hemanth you can find the below code,
#include <stdio.h>
#include <stdlib.h> 
int main() {
   int row = 2, col = 3; //number of rows=2 and number of columns=3
   int *arr = (int *)malloc(row * col * sizeof(int)); 
   int i, j;
   for (i = 0; i < row; i++)
      for (j = 0; j < col; j++)
         *(arr + i*col + j) = i + j;    
   printf("The matrix elements are:\n");
   for (i = 0; i < row; i++) {
      for (j = 0; j < col; j++) {
         printf("%d ", *(arr + i*col + j)); 
      }
      printf("\n");
   }
   free(arr); 
   return 0;
}
//let me know if you are still finding any problems with it.
vxf3dgd4

vxf3dgd43#

下面是一个解决方案,它创建了一个表示这样一个数组的结构体,并对该结构体进行了相关操作(create、get和set元素)。
它就像C中的类:有一个构造函数、一个析构函数和访问函数,数组类型本身称为struct jagged_col_arr_ST,无法保留方括号中的普通数组索引:C不允许我们定义自己的操作符,例如operator[](jagged_col_arr_ST)。数组中的数据结构必须是面向列的,因此列必须是第一个索引。因此,访问元素必须通过函数JCA_get_elem(arr, rowInd, colInd),该函数必须获取数组在C中,这是一个成员函数,数组参数是隐式的(并且是一个指针)。
因为数组类型本身保存的数据非常少(一个大小和一个指针),所以它更像是一个句柄,而不是一个保存数据的对象。它可以通过值传递,这为我们节省了“工厂函数”create_jagged_col_arr()中的动态分配:我们只是返回整个结构体。对于单个列也是如此。这有点不寻常--传统C总是通过指针传递结构体(事实上,这是原始K&R C中传递结构体的唯一方式)。在C++中,这样的工厂通常用于在运行时提供不同派生类型的对象,这些对象必须通过指向基类的指针返回。这反过来又需要动态初始化。2但无论如何C语言中没有多态性。
此外,现代计算机喜欢并行处理独立数据,因为它们具有许多内核;指针是别名,也就是共享内存访问的一种方式。有趣的是,由于实际数据没有被复制,我们可以像处理原始对象一样处理复制的对象:所有的副本都是“浅”的,并且引用相同的数据。当然,你不应该为一个数组和同一个数组的副本调用JCA_dispose()
大多数函数的前缀都是JCA_(表示“锯齿状列数组”),因为像getElem()这样的函数名可能会与大型项目中的其他名称冲突。
好的,下面是结构体及其函数的头:

锯齿状列数组. h
#include <stdint.h> // size_t
/// <summary>
/// A column with its size and a pointer to the dynamically allocated data
/// </summary>
struct JCA_col_ST { size_t mColSz;  int* mColDataPtr; };

/// <summary>
/// The array structure, holding a pointer to a dynamically 
/// allocated array of colum structures plus the column count
/// </summary>
struct jagged_col_arr_ST
{
    size_t mNumCols;
    struct JCA_col_ST* mCols;
};

/// <summary>
/// Return a jagged array with the given number of columns that have
/// the sizes given in the array the pointer points to.
/// </summary>
/// <param name="numCols">the number of columns the new array should have</param>
/// <param name="colSizes">the numbers of elements in each of those columns</param>
struct jagged_col_arr_ST create_jagged_col_arr(size_t numCols, size_t* colSizes);

size_t JCA_getNumCols(struct jagged_col_arr_ST arr);

size_t getNumRows(struct jagged_col_arr_ST arr, size_t colInd);

/// <summary>
/// return the element in the given position.
/// </summary>
/// <param name="arr">The array to obtain the element from</param>
/// <param name="row">The row of the desired element</param>
/// <param name="col">The column of the desired element</param>
/// <returns></returns>
int JCA_get_elem(struct jagged_col_arr_ST arr, size_t rowInd, size_t colInd);

/// <summary>
/// return the element in the given position.
/// </summary>
/// <param name="arr">The array in which to set the value of the element</param>
/// <param name="row">The row of the target element</param>
/// <param name="col">The column of the target element</param>
/// <param name="val">The new value of the target element</param>
/// <returns></returns>
void JCA_set_elem(struct jagged_col_arr_ST arr, size_t rowInd, size_t colInd, int val);

/// <summary>
/// Delete the dynamically allocated data.
/// </summary>
/// <param name="arr"></param>
void JCA_dispose(struct jagged_col_arr_ST arr);

下面是实现:

交错列数组. c
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h> // debatable
#include "jagged_col_arr.h"
/// <summary>
/// Return a structure that has the given column size 
/// and points to the corresponding amount of memory
/// </summary>
/// <param name="colSz">The size the column should have</param>
struct JCA_col_ST create_JCA_col_ST(size_t colSz)
{
    struct JCA_col_ST newCol;

    newCol.mColSz = colSz;
    newCol.mColDataPtr = colSz ? malloc(colSz * sizeof(int)) : 0;
    if (newCol.mColSz && !newCol.mColDataPtr)
    {
        fprintf(stderr, "Out of memory");
        exit(2);
    }
    return newCol;
}

/// <summary>
/// Return a jagged array with the given number of columns that have
/// the sizes given in the array.
/// </summary>
/// <param name="numCols">the number of columns the new array should have</param>
/// <param name="colSizes">the number of elements in each of those columns</param>
struct jagged_col_arr_ST create_jagged_col_arr(size_t numCols, size_t* colSizes)
{
    struct jagged_col_arr_ST newArr;
    newArr.mNumCols = numCols;
    newArr.mCols = numCols 
                 ? (struct JCA_col_ST*)malloc(numCols * sizeof(struct JCA_col_ST)) 
                 : 0;
    if (newArr.mNumCols && !newArr.mCols)
    {
        fprintf(stderr, "Out of memory");
        exit(2);
    }

    for (size_t colInd = 0; colInd < numCols; colInd++)
    {
        newArr.mCols[colInd] = create_JCA_col_ST(colSizes[colInd]);
    }
    return newArr;
}

size_t JCA_getNumCols(struct jagged_col_arr_ST arr) { return arr.mNumCols; }

size_t getNumRows(struct jagged_col_arr_ST arr, size_t colInd)
{
    if (colInd >= arr.mNumCols)
    {
        fprintf(stderr, "Column index %uz out of bounds", colInd);
        exit(1);
    }
    return arr.mCols ? arr.mCols[colInd].mColSz : 0; // empty columns are not allocated at all.
}

/// <summary>
/// return the colum struct at the given index.
/// </summary>
static struct JCA_col_ST JCA_getCol(struct jagged_col_arr_ST arr, size_t colInd) 
{
    if (colInd >= arr.mNumCols)
    {
        fprintf(stderr, "Column index %uz out of bounds", colInd);
        exit(1);
    }
    return arr.mCols[colInd];
}

/// <summary>
/// return the element in the given position.
/// </summary>
/// <param name="arr"></param>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>
int JCA_get_elem(struct jagged_col_arr_ST arr, size_t rowInd, size_t colInd)
{
    if (colInd >= arr.mNumCols)
    {
        fprintf(stderr, "Column index %uz out of bounds", colInd);
        exit(1);
    }
    struct JCA_col_ST col = JCA_getCol(arr, colInd);
    if (rowInd >= col.mColSz)
    {
        fprintf(stderr, "Row index %uz out of bounds for column %uz", rowInd, colInd);
        exit(1);
    }
    return col.mColDataPtr[rowInd];
}

void JCA_set_elem(struct jagged_col_arr_ST arr, size_t rowInd, size_t colInd, int val)
{
    if (colInd >= arr.mNumCols)
    {
        fprintf(stderr, "Column index %uz out of bounds", colInd);
        exit(1);
    }
    struct JCA_col_ST col = JCA_getCol(arr, colInd);
    if (rowInd >= col.mColSz)
    {
        fprintf(stderr, "Row index %uz out of bounds for column %uz", rowInd, colInd);
        exit(1);
    }
    col.mColDataPtr[rowInd] = val;
}

void JCA_dispose(struct jagged_col_arr_ST arr)
{
    // null pointers are OK to "free".
    for (size_t colInd = 0; colInd < arr.mNumCols; colInd++)
    {
        free(arr.mCols[colInd].mColDataPtr);
    }
    free(arr.mCols);
}

下面是一个使用示例:

可变列大小. c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdint.h> // size_t
#include <stdlib.h> // malloc
#include "jagged_col_arr.h"

void print_arr(struct jagged_col_arr_ST arr)
{
    // We'll buffer each printed line because we only know that it was empty
    // after we have visited it. But we don't want to print anything 
    // after the last line.
    char* linePrintBuf = malloc(arr.mNumCols * 3 + 1); // 3 per column, plus terminating 0
    if (!linePrintBuf)
    {
        fprintf(stderr, "Out of memory");
        exit(2);
    }

    int lastRowHadData = 1;
    // We don't know how many rows the longest column has. We must try each and check.
    // We do this on the fly.
    for (size_t rowInd = 0; lastRowHadData; rowInd++)
    {
        size_t linePrintPos = 0;
        lastRowHadData = 0; // potentially; if not, corrected in inner loop
        for (size_t colInd = 0; colInd < arr.mNumCols; colInd++, linePrintPos+=3)
        {
            if (rowInd < getNumRows(arr, colInd))
            {
                sprintf(linePrintBuf + linePrintPos, "%3d", JCA_get_elem(arr, rowInd, colInd));
                lastRowHadData = 1;
            }
            else
            {
                sprintf(linePrintBuf + linePrintPos, " . ");
            }
        }
        if (lastRowHadData)
        {
            printf("%s\n", linePrintBuf);
        }
    }
    free(linePrintBuf);
}

int main()
{
    size_t colSizes[] = { 3,7,1,0,10 };

    struct jagged_col_arr_ST arr 
            = create_jagged_col_arr(sizeof colSizes / sizeof *colSizes, colSizes);

    // Initialize all elements in the array with an integer 
    // reflecting its row and column position.
    for (size_t colInd = 0; colInd < JCA_getNumCols(arr); colInd++)
    {
        for (size_t rowInd = 0; rowInd < getNumRows(arr, colInd); rowInd++)
        {
            JCA_set_elem(arr, rowInd, colInd, rowInd*10+colInd);
        }
    }

    print_arr(arr);

    JCA_dispose(arr);
}

输出如下所示:

0  1  2 .   4
 10 11 .  .  14
 20 21 .  .  24
 .  31 .  .  34
 .  41 .  .  44
 .  51 .  .  54
 .  61 .  .  64
 .  .  .  .  74
 .  .  .  .  84
 .  .  .  .  94

相关问题