如何使双维排列参数在功能上使用

时间:2018-06-02 04:31:04

标签: c

#include <stdio.h>

void Turn(int(*ptr)[4], int length, int vertical)
{
    int arr[100][100] = { 0, };
    for (int i = 0; i < vertical; i++)
    {
        for (int j = 0; j < length; j++)
        {
            arr[i][j] = *(*(ptr + (vertical - j - 1)) + i);
        }
    }
    for (int i = 0; i < vertical; i++)
    {
        for (int j = 0; j < length; j++)
        {
            *(*(ptr + i) + j) = arr[i][j];
        }
    }
}
int main(void)
{
    int BY[4][4] = {
        1,2,3,4,
        5,6,7,8,
        9,10,11,12,
        13,14,15,16,
    };
    int length = sizeof(BY[0]) / sizeof(int);
    int vertical = (sizeof(BY) / sizeof(int)) / length;

    Turn(BY, length, vertical);

    for (int i = 0; i < vertical; i++)
    {
        for (int j = 0; j < length; j++)
        {
            printf("%d ", BY[i][j]);
        }
        printf("\n");
    }
    return 0;
}

我编写了一个名为Turn的函数来向右旋转2D数组(旋转90度)。我想让这个函数转换每个具有相同垂直范围和长度的数组。但是我无法交出  (我使用谷歌翻译,我不知道如何描述它)2D数组的参数。

我第一次使用void Turn(int(*ptr)[] ....) 但它不起作用。所以我忍不住使用
此函数中为int (*ptr)[4]。 如何创建可与任何2D阵列一起使用的2D数组的参数?

1 个答案:

答案 0 :(得分:1)

使用C99可变长度数组(VLA)功能可以轻松解决问题。 C11支持VLA可选,但实现必须定义__STDC_NO_VLA__以表明它不支持VLA。

这是代码的一个版本。我已重命名您的Turn()函数(将矩阵向右旋转90°进入TurnR()并添加了TurnL()函数,该函数将矩阵向左旋转90°。因为代码处理非正方矩阵,输出矩阵与输入矩阵是分开的。(如果你只想使用方形矩阵,可以稍微简化代码。)

#include <stdio.h>

static void TurnR(size_t rows, size_t cols, int matrix[rows][cols], int result[cols][rows])
{
    for (size_t r = 0; r < rows; r++)
    {
        for (size_t c = 0; c < cols; c++)
            result[c][rows - 1 - r] = matrix[r][c];
    }
}

static void TurnL(size_t rows, size_t cols, int matrix[rows][cols], int result[cols][rows])
{
    for (size_t r = 0; r < rows; r++)
    {
        for (size_t c = 0; c < cols; c++)
            result[cols - 1 - c][r] = matrix[r][c];
    }
}

static void Print(const char *tag, size_t rows, size_t cols, int matrix[rows][cols])
{
    printf("%s (%zux%zu):\n", tag, rows, cols);
    for (size_t r = 0; r < rows; r++)
    {
        const char *pad = "";
        for (size_t c = 0; c < cols; c++)
        {
            printf("%s%3d", pad, matrix[r][c]);
            pad = " ";
        }
        putchar('\n');
    }
}

int main(void)
{
    int BY[4][4] = {
        {  1,  2,  3,  4, },
        {  5,  6,  7,  8, },
        {  9, 10, 11, 12, },
        { 13, 14, 15, 16, },
    };
    int out[4][4];

    Print("before", 4, 4, BY);
    TurnR(4, 4, BY, out);
    Print("right", 4, 4, out);
    TurnL(4, 4, BY, out);
    Print("left", 4, 4, out);

    int m4x6[4][6] =
    {
        {  1,  2,  3,  4,  5,  6, },
        {  7,  8,  9, 10, 11, 12, },
        { 13, 14, 15, 16, 17, 18, },
        { 19, 20, 21, 22, 23, 24, },
    };
    int m6x4[6][4];

    Print("before", 4, 6, m4x6);
    TurnR(4, 6, m4x6, m6x4);
    Print("right", 6, 4, m6x4);
    TurnL(4, 6, m4x6, m6x4);
    Print("left", 6, 4, m6x4);

    int m5x3[5][3] =
    {
        {  1,  2,  3, },
        {  4,  5,  6, },
        {  7,  8,  9, },
        { 10, 11, 12, },
        { 13, 14, 15, },
    };
    int m3x5[3][5];

    Print("before", 5, 3, m5x3);
    TurnR(5, 3, m5x3, m3x5);
    Print("right", 3, 5, m3x5);
    TurnL(5, 3, m5x3, m3x5);
    Print("left", 3, 5, m3x5);
    TurnL(3, 5, m3x5, m5x3);
    Print("doubleL", 5, 3, m5x3);

    return 0;
}

示例输出为:

before (4x4):
  1   2   3   4
  5   6   7   8
  9  10  11  12
 13  14  15  16
right (4x4):
 13   9   5   1
 14  10   6   2
 15  11   7   3
 16  12   8   4
left (4x4):
  4   8  12  16
  3   7  11  15
  2   6  10  14
  1   5   9  13
before (4x6):
  1   2   3   4   5   6
  7   8   9  10  11  12
 13  14  15  16  17  18
 19  20  21  22  23  24
right (6x4):
 19  13   7   1
 20  14   8   2
 21  15   9   3
 22  16  10   4
 23  17  11   5
 24  18  12   6
left (6x4):
  6  12  18  24
  5  11  17  23
  4  10  16  22
  3   9  15  21
  2   8  14  20
  1   7  13  19
before (5x3):
  1   2   3
  4   5   6
  7   8   9
 10  11  12
 13  14  15
right (3x5):
 13  10   7   4   1
 14  11   8   5   2
 15  12   9   6   3
left (3x5):
  3   6   9  12  15
  2   5   8  11  14
  1   4   7  10  13
doubleL (5x3):
 15  14  13
 12  11  10
  9   8   7
  6   5   4
  3   2   1

我不会梦想使用*(ptr + index)表示法编写代码,特别是使用双下标;它太容易出错而且难以阅读(确实是一场噩梦!)。