C语言 使用数组初始值设定项作为静态数组



是否可以将数组初始值设定项用作数组(有点像字符串文字?

#define TETRAMINO_I {{1,1,1,1},{0,0,0,0}}
printf("%c",(TETRAMINO_I[0][0]) ? "#" : ' ');

(此代码显然不起作用。

我想出了以下解决方案(绕过此要求)

#define TETRAMINO_I {{1,1,1,1},{0,0,0,0}}
#define TETRAMINO_J {{1,1,1,0},{0,0,1,0}}
#define TETRAMINO_L {{1,1,1,0},{1,0,0,0}}
#define TETRAMINO_O {{1,1,0,0},{1,1,0,0}}
#define TETRAMINO_S {{0,1,1,0},{1,1,0,0}}
#define TETRAMINO_T {{1,1,1,0},{0,1,0,0}}
#define TETRAMINO_Z {{1,1,0,0},{0,1,1,0}}
typedef unsigned char byte;
typedef struct tetraminos{
    char I[2][4];
    char J[2][4];
    char L[2][4];
    char O[2][4];
    char S[2][4];
    char T[2][4];
    char Z[2][4];
}tet_minos_t;
tet_minos_t tet_mino_blocks{ TETRAMINO_I,TETRAMINO_J,TETRAMINO_L,TETRAMINO_O,TETRAMINO_S,TETRAMINO_T,TETRAMINO_Z};

使用结构的全局实例。但是,当尝试使用时:

newMino->blocks = (char**)tet_mino_blocks.I;
printf("%c",(newMino->blocks[0][0]) ? "#" : ' ');

我无法打印(出现分段错误)

是的,有点,但你必须给你的数组一个类型。自 C99 以来,我们有复合文字:

#define TETRAMINO_C ((unsigned char const[][4])TETRAMINO_I)

这为数组提供了 const 限定的类型(语法类似于强制转换)。该类型是const限定的,因此编译器对如何分配数组的限制较小(如果必须这样做)。允许只为数组的所有使用分配一个静态副本。

但是,如果您只按照TETRAMINO_C[0][0]中的指示使用它,那么现代 C 编译器的体面优化器应该能够完全优化数组,并且只直接使用常量。

问题是char[2][4]没有描述与char **相同的内存布局。第一个是连续的二维char数组,而第二个是指向char指针数组的指针。您最终会将字符值视为指针,这当然会导致地址无效和段错误。

为了使代码正常工作,newMino->blocks指针必须是 char *[4] 类型,而不是 char ** 类型。像这样定义它:

struct ... {
    char (*blocks)[4];
};

typedef char[4] tetromino_col_t;
struct ... {
    tetromino_col_t *blocks;
};

相关内容

  • 没有找到相关文章

最新更新