【问题标题】:How to pass the starting index of a two dimensional subarray in c?如何在c中传递二维子数组的起始索引?
【发布时间】:2021-05-21 15:42:42
【问题描述】:

我想在 C 中传递二维子数组,因为我们可以传递一维子数组:

我通过了如下的一维子数组:

代码

#include <stdio.h>

void print_array(int *arr, int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%d ", arr[i]);
    }
}

int main(void)
{
    int arr[] = {1, 2, 3, 4, 5};
    int size = sizeof(arr) / sizeof(int);
    print_array(&arr[2], size - 2);
    return 0;
}

输出

3 4 5 

但是我怎样才能对二维数组做同样的事情呢? 我有一个二维数组如下:

int arr[6][6] = {
        {1, 2, 3, 4, 5, 6},
        {2, 3, 4, 5, 6, 7},
        {3, 4, 5, 6, 7, 8},
        {4, 5, 6, 7, 8, 9},
        {5, 6, 7, 8, 9, 10},
        {6, 7, 8, 9, 10, 11}};

我想传递arr[1][1] 元素的索引,以便打印子二维数组:

3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
6 7 8 9 10
7 8 9 10 11

我尝试如下,但没有成功:

代码

#include <stdio.h>

void print_array(int row, int column, int (*arr)[column])
{
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < column; j++)
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}

int main(void)
{
    int arr[6][6] = {
        {1, 2, 3, 4, 5, 6},
        {2, 3, 4, 5, 6, 7},
        {3, 4, 5, 6, 7, 8},
        {4, 5, 6, 7, 8, 9},
        {5, 6, 7, 8, 9, 10},
        {6, 7, 8, 9, 10, 11}};

    print_array(5, 5, &arr[1]);
    return 0;
}

输出

2 3 4 5 6 
7 3 4 5 6 
7 8 4 5 6 
7 8 9 5 6 
7 8 9 10 6

我不知道这个输出是如何产生的,也请告诉我如何通过传递地址来实现我的目标。

注意:我已经通过了&amp;arr[1],因为通过&amp;arr[1][1] 表示incompatible pointer type for the function argument

我知道我们可以通过其他方式做到这一点,但是,我怎样才能像在一维数组中那样传递子数组?

如果以任何方式都不可能,那么请告诉我背后的主要原因是什么,因为该方法适用于一维数组但不适用于二维数组。

因为我认为传递arr 是做同样的事情(即以arr[0][0]arr[1][0] 等方式访问其成员。那么为什么不传递子数组的起始索引以轻松获取整个子数组。

【问题讨论】:

  • 你所说的在逻辑上是不可能的。你不能像这样切割二维子阵列。想一想。即使您能够传递一些起始索引,您也会从那里开始,然后当您更改行时,您最终将落后于起始索引。你不能这样剪列。
  • 您可以改为传递原始尺寸和起始索引。然后在打印那些在起始索引之前的索引时,只需使用if 条件。

标签: c for-loop multidimensional-array function-declaration


【解决方案1】:

实现此目的的一种方法是传递arr 的原始尺寸和起始索引srowscol,然后在这些索引处开始循环。

#include <stdio.h>

void print_array(int row, int column, int srow, int scol, int (*arr)[column])
{
    for (int i = srow; i < row; i++)
    {
        for (int j = scol; j < column; j++)
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}

int main(void)
{
    int arr[6][6] = {
        {1, 2, 3, 4, 5, 6},
        {2, 3, 4, 5, 6, 7},
        {3, 4, 5, 6, 7, 8},
        {4, 5, 6, 7, 8, 9},
        {5, 6, 7, 8, 9, 10},
        {6, 7, 8, 9, 10, 11}};

    print_array(6, 6, 1, 1, arr);
    return 0;
}

【讨论】:

    【解决方案2】:

    如果你有这样的二维数组

    enum { M = 6, N = 6 };
    int arr[M][N] = 
    {
        { 1, 2, 3, 4,  5,  6 },
        { 2, 3, 4, 5,  6,  7 },
        { 3, 4, 5, 6,  7,  8 },
        { 4, 5, 6, 7,  8,  9 },
        { 5, 6, 7, 8,  9, 10 },
        { 6, 7, 8, 9, 10, 11 }
    };
    

    并希望从行位置pos 开始输出它,其中pos 的值小于M,那么您可以将其传递给类似表达式的函数

    arr + pos
    

    您不能更改数组中一行中的元素数。所以指定子数组的函数参数必须是这样的

    int ( *arr )[columns]
    

    其中columns 指定原始数组中的实际列数。

    您还需要传递给函数的是要从中输出子数组的列的起始编号。

    这是一个演示程序

    #include <stdio.h>
    
    void print_array( size_t rows, size_t columns, size_t pos, int ( *arr )[columns] )
    {
        if ( pos < columns )
        {
            for ( size_t i = 0; i < rows; i++ )
            {
                for ( size_t j = pos; j < columns; j++ )
                {
                    printf( "%2d ", arr[i][j] );
                }
                putchar( '\n' );
            }
        }
    }
    
    int main(void) 
    {
        enum { M = 6, N = 6 };
        int arr[M][N] = 
        {
            { 1, 2, 3, 4,  5,  6 },
            { 2, 3, 4, 5,  6,  7 },
            { 3, 4, 5, 6,  7,  8 },
            { 4, 5, 6, 7,  8,  9 },
            { 5, 6, 7, 8,  9, 10 },
            { 6, 7, 8, 9, 10, 11 }
        };
        
        for ( size_t pos = 1; pos < M; ++ pos )
        {
            print_array( M - pos, N, pos, arr + pos );
            putchar( '\n' );
        }
        
        return 0;
    }
    

    程序输出是

     3  4  5  6  7 
     4  5  6  7  8 
     5  6  7  8  9 
     6  7  8  9 10 
     7  8  9 10 11 
    
     5  6  7  8 
     6  7  8  9 
     7  8  9 10 
     8  9 10 11 
    
     7  8  9 
     8  9 10 
     9 10 11 
    
     9 10 
    10 11 
    
    11 
    

    注意行的起始地址和列的起始地址不一定要相等。例如,您可以调用类似的函数

    print_array( M - 3, N, 1, arr + 3 );
    

    【讨论】:

      【解决方案3】:

      我建议使用嵌套的std::arraystd::vector。如果您的数组大小在运行时未知,请使用向量。如果您的数组大小已知,请使用 std::array

      #include <array>
      using nested_int_array = std::array<std::array<int, 6> >, 6>; //6 = size of array
      
      void printsubarray(int begin_row, int begin_column, const nested_int_array& ar)
      {
         for (int r = begin_row; r < ar.size(); r++)
         {
            for (int c = begin_column; c < ar[0].size(); c++)
            {
                 printf("%i ", ar[r][c]);
            }
            printf("\n");
         }
      }
      
      
      

      【讨论】:

      • 问题标记为 C,而不是 C++。 C中有std::arraystd::vector
      • 它是 C,而不是 C++
      猜你喜欢
      • 2015-09-19
      • 1970-01-01
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 2013-01-02
      • 1970-01-01
      相关资源
      最近更新 更多