简体   繁体   English

使用数组初始化器作为静态数组

[英]Use array initializer as static array

Is it possible to use an array initializer as an array (sort of like a string literal?) 是否可以将数组初始值设定项用作数组(有点像字符串文字?)

#define TETRAMINO_I {{1,1,1,1},{0,0,0,0}}

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

(This code obviously doesn't work. (这段代码显然不起作用。

I have come up with the following solution (bypassing this requirement) 我提出了以下解决方案(绕过此要求)

#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};

Using a global instance of a struct. 使用结构的全局实例。 However, when trying to use: 但是,在尝试使用时:

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

I am unable to print (get segmentation fault) 我无法打印(获取分段错误)

Yes, kind of, but you have to give your array a type. 是的,有点,但你必须给你的阵列一个类型。 Since C99 we have compound literals: 从C99开始,我们有复合文字:

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

This gives the array a const -qualified type (syntactically similar to a cast). 这为数组提供了一个const限定类型(在语法上类似于强制转换)。 The type is const -qualified, so the compiler is less constraint on how to allocate the array, if it has to. 类型是const -qualified,因此编译器对如何分配数组的约束较少,如果必须的话。 It is allowed to just allocate one static copy for all your uses of the array. 允许为数组的所有使用分配一个静态副本。

But if you only use it as indicated in TETRAMINO_C[0][0] a decent optimizer of a modern C compiler should be able to optimize the array completely out and to only use the constants directly. 但是如果你只使用TETRAMINO_C[0][0]的指示,现代C编译器的一个不错的优化器应该能够完全优化数组并且只能直接使用常量。

The problem is that char[2][4] does not describe the same memory layout as char ** . 问题是char[2][4]没有描述与char **相同的内存布局。 The first is a contiguous two-dimensional array of char , while the second is a pointer to an array of pointers to char . 第一个是char的连续二维数组,而第二个是指向char的指针数组的指针。 You end up treating the character values as a pointer, which of course results in an invalid address and a segfault. 您最终将字符值视为指针,这当然会导致无效的地址和段错误。

In order for the code to work correctly, the newMino->blocks pointer has to be of type char *[4] , not of type char ** . 为了使代码正常工作, newMino->blocks指针必须是char *[4]类型,而不是char **类型。 Define it like this: 像这样定义:

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

or 要么

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM