【问题标题】:Problems with a getter for a 4x4 matrix in cc中4x4矩阵的getter问题
【发布时间】:2016-04-22 21:57:39
【问题描述】:

您好,我必须在明天之前用 C 语言编写一个俄罗斯方块游戏,但我在使用 getter 时遇到了一些麻烦,它应该将精灵作为 4x4 矩阵返回。

这很可能很简单,尽管我对指向数组的指针不太熟悉。

所以在我存储形状的第一个文件中,这是 1 个形状的测试吸气剂

int shape_i[4][4] = {
    {1,0,0,0},
    {1,0,0,0},
    {1,0,0,0},
    {1,0,0,0}
};


int **get_shape(){
return shape_i;}

现在从我的绘图文件中我这样称呼它

void draw_shape(){
int **shape= get_shape();
for (int i = 0; i<4; i++){
    for (int j=0; j<4; j++){
        int value = shape[j][i];

            if (value != 0){
                SDL_Rect rect;
                rect.x = (get_x()+i)*BLOCK_WIDTH;
                rect.y = (get_y()+j) *BLOCK_HEIGHT;
                rect.h = BLOCK_HEIGHT;
                rect.w = BLOCK_WIDTH;
                SDL_FillRect(window,&rect,0x044DDE);
            }
            }
    }
SDL_Flip(window);
}

编译时不会出错,但我的程序一旦到达 get_shape() 就会停止

【问题讨论】:

  • 你有什么错误?目前尚不清楚哪个是所需的输出,哪个是您得到的输出。
  • 如果我替换 **shape=get_shape(); 我的窗口一旦到达 get_shape() 就会关闭并停止运行,它不会给我一个错误。 int shape[4][4] = { {1,0,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0} };它工作得很好
  • 而且for循环也错了,应该从0到3
  • @Teepeemm 如果在分配中,那么 shape[4][4] = {...} 是正确的

标签: c arrays pointers return tetris


【解决方案1】:

TL;DR:使用memcpy 将数据复制到您的形状数组,请参见下面的第二个示例。其他示例是带有解释的替代方法。


在 C 中,您不能返回数组。您只能将指向第一个元素的指针返回到数组。数组的第一个元素本身就是一个数组,一个由 4 个ints 组成的数组。

定义一个指向四个整数数组的指针的语法有点巴洛克式:

int (*p)[4];

当你必须将它定义为函数的返回类型时,它更加巴洛克:

int (*get_shape(int c))[4] { ... }

解决这个问题的方法是使用typedef:

typedef int (*Shape)[4];

现在您的变量和函数原型如下所示:

Shape p = get_shape(c);

Shape get_shape(int c) { ... }

这是一个完整的例子:

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

typedef int (*Shape)[4];

int shape_i[4][4] = {{1,0,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0}};
int shape_l[4][4] = {{1,0,0,0}, {1,0,0,0}, {1,1,0,0}, {0,0,0,0}};
int shape_z[4][4] = {{1,0,0,0}, {1,1,0,0}, {0,1,0,0}, {0,0,0,0}};

Shape get_shape(int c)
{
    switch (c) {
    case 'I':   return shape_i;
    case 'L':   return shape_l;
    case 'Z':   return shape_z;
    }
    return NULL;
}

int main()
{
    int c;

    for (c = 'A'; c <= 'Z'; c++) {
        Shape p = get_shape(c);

        if (p) {
            int i, j;

            for (j = 0; j < 4; j++) {
                for (i = 0; i < 4; i++) {
                    putchar(p[j][i] ? '#' : ' ');
                }
                puts("");
            }
            puts("--");
        }        
    }

    return 0;
}

注意形状的定义仍然需要您使用int[4][4],因为数组不是指针。您需要在其中定义数据的数组。另请注意,此解决方案返回指向原始shape_i 的指针。当你修改p中的数据时,你修改了shape_ip,从而破坏了你的形状原型。


如果你想用数据填充数组,只需传入数据。即使对于一维数组,这也是一种常见的方法:传递一个数组并让函数填充它。返回一个(否则不相关的)值,告诉您操作是否成功。

int get_shape(int shape[4][4], int c)
{
    switch (c) {
    case 'I':   memcpy(shape, shape_i, sizeof(shape)); return 1;
    case 'L':   memcpy(shape, shape_l, sizeof(shape)); return 1;
    case 'Z':   memcpy(shape, shape_z, sizeof(shape)); return 1;
    }
    return 0;
}

memcpy 是标准库的一个函数,您应该为其包含&lt;string.h&gt;。返回值只是为了检查形状是否有效。像这样使用它:

int p[4][4];

if (get_shape('I')) {
    // p is now filled with a copy of shape_i
}

我认为这是您应该使用的方法。它将shape_t的内容复制到p,这就是你想要的。您将旋转和翻转当前块 p,而您希望保持块原型 shape_i 不变以用于未来的“克隆”。


我在上面说过,您不能在 C 中返回数组。您可以做的是将数组包装在 struct 中并返回。结构体是按值传递的,不会衰减为像数组这样的指针。

struct Shape {
    int data[4][4];
};

struct shape shape_i = {{{1,0,0,0}, {1,0,0,0}, {1,0,0,0}, {1,0,0,0}}};

struct Shape get_shape(void) {
    return shape_i;
};

struct Shape p = get_shape();

这也会复制内容,但您必须以p.data[i][j] 访问元素。

【讨论】:

  • 哇,非常感谢 :D 现在我可以继续一个漫长的编程之夜了
猜你喜欢
  • 2017-08-21
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 2014-11-13
  • 1970-01-01
相关资源
最近更新 更多