2013-07-08 12 views
1

다른 크기를 가질 수있는 대기열을 작성하는 데 관심이 있습니다. 8, 16, 32 요소를 가지고 malloc을 사용하지 않고 그것을하고 싶다고하자. 3 개의 다른 대기열을 만들면 쉽게 만들 수 있지만이 작업을 수행하고 싶지는 않습니다. 동일한 기능을 사용하고 3 가지 유형 만 정의하려고합니다.malloc이없는 다중 크기 대기열

내 문제는 정확히 이것입니다. 코드에서 큐를 사용하고 싶은 위치가 3 개 있지만이 경우 크기가 다른 큐를 사용하며 크기가 어느 정도인지 알고 있습니다. 세 개의 함수 그룹과 구조체를 만들어이 큐를 만들고 싶지 않습니다. 세 개의 구조체를 만들고 같은 함수를 사용하고 싶습니다. 또한 malloc은 임베디드 응용 프로그램이므로 사용할 수 없습니다.

C에서 추상 형식의 C++로 만드는 방법에 대한 아이디어를 받고 싶습니다. 내 문제를 해결할 수 있습니다.

이 방법이 있습니까?

감사합니다.

+0

C++에서는 템플릿 클래스를 만들 수 있습니다. –

+0

하지만 C에서 이것을하고 싶습니다. –

+2

행운을 빈다. :-))) –

답변

2

이렇게하는 방법에는 여러 가지가 있습니다. 여기에 몇 ...

  1. 대기열 헤더에 대기열의 크기를 포함합니다. 큐에 액세스하는 기능은

  2. 가 첫 번째 옵션은 덜 오류가

큐를 관리하는 기능에 대한 인수로 큐 크기를 통과 항목 수를 제한하는 헤더에서 크기를 사용 경향이 있지만 추가 헤더 필드를 필요로합니다.

구조체

는 큐가 inout 지수의 초기화가 필요합니다 어떤 경우

static struct s_que8 
{ 
    int in; 
    int out; 
    int size; // for option 1 
    int elements[8]; // or whatever size you like 
} que8; 

로 정의하고, 옵션 1의 size 값은 큐 프로토콜은 in == out 큐를 의미하는 경우 것 비어있는 경우 in = out = 0;을 초기화하도록 설정할 수 있습니다.

일부 특정 구조 선언 여기에 정적 문자열입니다 요소에 대한 부칙

:

static struct s_que8 
{ 
    int in; 
    int out; 
    int size; // for option 1 
    char * elements[8]; // for pointers to static strings 
} que8; 

또는

static struct s_que8 
{ 
    int in; 
    int out; 
    int size; // for option 1 
    char elements[8][MAX_STRING_SIZE]; // for strings stored in the queue 
} que8; 

변경 8은 특정 큐 크기를 이용할 수 있습니다.

대응 "일반적인"형식 정의는 다음과 같습니다

typedef struct s_queX 
{ 
    int in; 
    int out; 
    int size; // for option 1 
    char * elements[]; // for pointers to static strings 
} Queue; 

또는

typedef struct s_queX 
{ 
    int in; 
    int out; 
    int size; // for option 1 
    char elements[][MAX_STRING_SIZE]; // for strings stored in the queue 
} Queue; 
+0

좋아요,하지만 dequeue (Queue * queue)와 같은 함수는 어떻게 될까요 ?? 즉,이 함수에 대한 인수로 전달할 대상은 무엇입니까? –

+0

옵션 2의 경우'size'를'dequeue (Queue * queue, int size)'처럼 사용합니다. –

+0

이 경우 Queue는 무엇이겠습니까? 어떤 struct, s_que8, 16 또는 32에 대한 포인터입니까? –

0

당신은 free_elements와 TAILQ을 만들 수 당신이 요소를 할 때마다 당신은 free_elements에서 제거 할 수 있습니다 대기열에 넣고 사용하고 나중에 다시 목록에 삽입하십시오.

malloc 문제의 경우 정적 메모리로 큐를 초기화해야합니다.

예 :

static struct my_element free_elements_array[TOTAL_ELEMENTS]; 

extern int my_queue_init(void) 
{ 
    int i; 
    TAILQ_INIT(my_queue_head); 

    for (i=0; i<TOTAL_ELEMENTS;i++) 
     TAILQ_INSERT_TAIL(my_queue_head, &free_elements_array[i]); 

    return 0; 
} 

extern struct my_element *get_element(void) 
{ 
    struct my_element *element; 
    element = TAILQ_LAST(my_queue_head) 
    if (element) 
    { 
     TAILQ_REMOVE(my_queue_head, element) 
    } 
    return element. 
} 

TAILQ 그냥 제안하고, 내 코드에서 매크로는 단지 예로서 사용 완료되지 않습니다. 그들과 다른 큐에 대한 자세한 내용은 http://linux.die.net/man/3/queue을 참조하십시오.

0

나는 그것을하는 방법을 발견했습니다. 어쩌면 내가 표현했습니다 그것이 잘못하지만 내가 도달 한이 솔루션은 내 문제 해결 :

소스 파일 :

#include "Fila.h" 
#include <string.h> 
#include <stdio.h> 

void Fila_Init(Fila_t * fila, const uint32_t qtdLinhas, const uint32_t qtdColunas, char ** buffer) 
{ 
    fila->qtdLinhas = qtdLinhas; 
    fila->qtdColunas = qtdColunas; 
    fila->head = 0; 
    fila->tail = 0; 
    fila->tamanho = 0; 
    fila->linhas = buffer; 
    uint32_t i; 
    for(i = 0; i < fila->qtdLinhas; i++) 
     memset(fila->linhas[i], FILA_CARACTERE, FILA_COLUNAS); 
} 

void Fila_Enfileira(Fila_t * fila, int tamDado, const char * dado) 
{ 
    if(tamDado > FILA_COLUNAS) 
     tamDado = FILA_COLUNAS; 

    if (FILA_TAIL == FILA_HEAD && (fila->tamanho + 1) > fila->qtdLinhas) 
      fila->head++; 

    memset(fila->linhas[FILA_TAIL], FILA_CARACTERE, FILA_COLUNAS); 
    fila->linhas[FILA_TAIL][tamDado] = '\0'; 

    memcpy(fila->linhas[FILA_TAIL_INC], dado, tamDado); 

    if(fila->tamanho < fila->qtdLinhas) 
     fila->tamanho++; 
} 

char * Fila_Desenfileira(Fila_t * fila) 
{ 
    if(Fila_TemProximo(fila)) 
     fila->tamanho--; 

    return fila->linhas[FILA_HEAD_INC]; 
} 

inline char * Fila_Primeiro(Fila_t * fila) 
{ 
    return fila->linhas[FILA_HEAD]; 
} 

inline bool Fila_TemProximo(Fila_t * fila) 
{ 
    return (fila->tamanho > 0); 
} 

void Fila_Imprime(Fila_t * fila) 
{ 
    int tamanho = fila->tamanho; 
    int cabeca = fila->head; 
    while(tamanho > 0) 
    { 
    printf("%s\n", fila->linhas[(cabeca++ % fila->qtdLinhas)]); 
    tamanho--; 
    } 
} 

헤더 파일 : 또한

/* 
* Fila.h 
* 
* Created on: 18/06/2013 
*  Author: Leandro 
*/ 

#ifndef FILA_H_ 
#define FILA_H_ 

#include "types.h" 
#include <stdint.h> 

#define FILA_COLUNAS (fila->qtdColunas) 
#define FILA_CARACTERE 0xff 
#define FILA_TAIL (fila->tail % fila->qtdLinhas) 
#define FILA_HEAD (fila->head % fila->qtdLinhas) 
#define FILA_TAIL_INC (fila->tail++ % fila->qtdLinhas) 
#define FILA_HEAD_INC (fila->head++ % fila->qtdLinhas) 

typedef struct { 
    uint32_t qtdLinhas; 
    uint32_t qtdColunas; 
    uint32_t head; 
    uint32_t tail; 
    uint32_t tamanho; 
    char ** linhas; 
} Fila_t; 

void Fila_Init(Fila_t * fila, const uint32_t qtdLinhas, const uint32_t qtdColunas, char ** buffer); 
void Fila_Enfileira(Fila_t * fila, int tamDado, const char * dado); 
char * Fila_Desenfileira(Fila_t * fila); 
bool Fila_TemProximo(Fila_t * fila); 
char * Fila_Primeiro(Fila_t * fila); 
void Fila_Imprime(Fila_t * fila); 

#endif /* FILA_H_ */ 

을하고, 테스터 파일 :

#include "Fila.h" 
#include <stdio.h> 
#include <string.h> 

Fila_t testeStatic() 
{ 
    static char ele[8][512]; 
    const int c = sizeof(ele[0])/sizeof(ele[0][0]); 
    const int l = sizeof(ele)/c; 

    printf("Tamanho da matriz: %d bytes.\n", c*l*sizeof(char)); 
    char* ele2[c]; 
    int i = 0; 
    for (i = 0; i < l; i++) 
     ele2[i] = ele[i]; 

    Fila_t fila; 
    Fila_Init(&fila, l, c, ele2); 

    printf("Tamanho da matriz de ponteiros na fila: %d bytes.\n", sizeof(fila) - 5*sizeof(uint32_t)); 
    printf("Tamanho da fila: %d bytes.\n", sizeof(fila)); 
    printf("Tamanho final de uma fila [8][512]: %d\n", c*l*sizeof(char)+sizeof(fila)); 
    printf("Overhead de apenas 24 bytes ou %f por cento.\n", (float)((sizeof(fila) * 100))/(c*l*sizeof(char))); 
    return fila; 
} 
void testaFila(Fila_t * fila) 
{ 
    char texto[20]; 
    int i; 
    for (i = 0; i < 50; i++) 
     Fila_Enfileira(fila, sprintf(texto, "Entrada [%d]", i), texto); 

    while (Fila_TemProximo(fila)) 
     printf("%s\n", Fila_Desenfileira(fila)); 
} 

int main() 
{ 
    Fila_t fila = testeStatic(); 
    testaFila(&fila); 

    return 0; 
} 

죄송합니다. 포르투갈어로되어있어서 유감이지만, 제 언어로도 도움이 될 것입니다. 도움과 인내심 덕분에 @Doug Currie에게 특별한 감사를드립니다. 누군가이 코드를 이해하는 데 도움이 필요하면 설명하는 것이 즐겁습니다. 또한 Google 코드에이 코드 project을 만들었으며 아이디어와 비평을받는 것이 큰 기쁨입니다.

+0

여러분? 그건 약간 추측이야. – mikeyq6