Как инициализировать массив структур внутри функции? - PullRequest
2 голосов
/ 13 июня 2010

В функции make_quad () ниже, как мне установить значения по умолчанию для массива vertex_color в структуре quad_t?

/* RGBA color */
typedef struct {
    uint8_t r,g,b,a;
} rgba_t;

/* Quad polygon - other members removed */
typedef struct {
    rgba_t vertex_color[ 4 ];
} quad_t;

В другом месте, функция для создания и инициализации квада:

quad_t *make_quad() {
    quad_t *quad = malloc( sizeof( quad_t ) );
    quad->vertex_color = ??? /* What goes here? */
    return ( quad );
}

Очевидно, что я могу сделать это так:

quad->vertex_color[ 0 ] = { 0xFF, 0xFF, 0xFF, 0xFF };
...
quad->vertex_color[ 3 ] = { 0xFF, 0xFF, 0xFF, 0xFF };

, но это:

quad->vertex_color = {
    { 0xFF, 0xFF, 0xFF, 0xFF },
    { 0xFF, 0xFF, 0xFF, 0xFF },
    { 0xFF, 0xFF, 0xFF, 0xFF },
    { 0xFF, 0xFF, 0xFF, 0xFF }
};

... приводит к « ошибка: ожидаемое выражение до»{'token".

EDIT: исправлено несколько опечаток

Ответы [ 4 ]

4 голосов
/ 13 июня 2010

В вашем коде было несколько ошибок, я исправил их все здесь. quad_t уже был определен в <sys/types.h>, поэтому я изменил его на myquad_t.

По сути, вы не можете статически инициализировать память, которая динамически выделяется во время выполнения, поэтому вы можете создать глобальный объект, который инициализируется во время компиляции, и затем вы используете memcpy для копирования в динамически выделенную память.

Вот объяснение обозначенных инициализаторов .

#include    <stdlib.h>
#include    <string.h>
#include    <stdint.h>

/* RGBA color */
typedef struct rgba {
    uint8_t r,g,b,a;
} rgba_t;

/* Quad polygon - other members removed */
typedef struct quad {
    rgba_t vertex_color[ 4 ];
} myquad_t;

static const myquad_t init_quad = {
     .vertex_color[ 0 ... 3 ] = { 0xFF, 0xFF, 0xFF, 0xFF } 
    };    

myquad_t *make_quad() {
    myquad_t *q = malloc( sizeof( myquad_t ) );
    memcpy(q , &init_quad, sizeof( myquad_t ) );
    return ( q );
}    

int main(void) {

    myquad_t * q = make_quad();

    return 0;
}
1 голос
/ 15 июня 2010

В C99 вы можете сделать что-то вроде

*quad = (quad_t const){
  .vertex_color = {
    { .r = 0xFF, .g = 0xFF, .b = 0xFF, a. = 0xFF },
    { .r = 0xFF, .g = 0xFF, .b = 0xFF, a. = 0xFF },
    { .r = 0xFF, .g = 0xFF, .b = 0xFF, a. = 0xFF },
    { .r = 0xFF, .g = 0xFF, .b = 0xFF, a. = 0xFF },
  }
};

, где правая часть - это так называемый составной литерал.Любой современный компилятор должен реализовать это наиболее эффективным способом.

Но, вероятно, было бы лучше быть немного более систематичным

#define RGBA_INITIALIZER { .r = 0xFF, .g = 0xFF, .b = 0xFF, a. = 0xFF }
#define QUAD_INITIALIZER {                      \
.vertex_color = {                               \
  RGBA_INITIALIZER, RGBA_INITIALIZER,           \
  RGBA_INITIALIZER, RGBA_INITIALIZER            \
  }                                             \
}

, а затем просто написать

*quad = (quad_t const)RGBA_INITIALIZER;
1 голос
/ 13 июня 2010

Попробуйте

memset(quad, 0xFF, sizeof(quad_t));
1 голос
/ 13 июня 2010

Пожалуйста, оставьте актуальный код. Это, например:

typedef {
    uint8_t r,g,b,a;
} rgba_t;

не скомпилируется. И кажется, что вы пытаетесь выполнить назначение, а не инициализацию. Если вы правильно объявили структуру, вы сможете сказать:

rgba_t t = { 1,2,3,4 };

но не:

t = { 1,2,3,4 };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...