2017-01-03 2 views
0

안녕하세요,함수 포인터 함수 매크로

다른 유형을 받아 들일 수있는 동적 배열을 C로 작성하려고합니다. 주요 구조로 구축

은 다음과 같습니다 나 '

int item = 13; 
st_array a = NewArray(32); 
a.push(&a, (void*)&item); 

int item_ret = *(int*)a.at(&a, 0); 

:

이를 사용하려면
typedef struct st_array 
{ 
    void* array; 
    uint16_t size; 
    uint16_t used; 

    void (*push)(struct st_array*, void*); 
    void* (*at )(struct st_array*, uint16_t); 
} st_array; 

void pushInArray(st_array* this, void* item) 
{ 
    // Check for last occupied bin 
    // if equal size, realloc() and increase this->size 
    this->array[this->used++] = item; 
} 

void* getAt(st_array* this, utf16_t idx) 
{ 
    if(idx <= this->used) 
     return this->array[idx]; 
    return NULL; 
} 

st_array NewArray(uint16_t size) 
{ 
    st_array this; 
    this.array = malloc(size * sizeof(void*)); 

    this.push = &pushInArray; 
    this.at = &getAt; 
    ... 
    return this; 
} 

, 내가 push()at()의 각 호출에 내 변수 유형에 캐스팅해야 d는 캐스팅을 피하는 것을 선호합니다 (프로그래머가 무엇을하고 있는지 알기 위해 유용 할지라도). 형식을 매개 변수로 허용하는 함수 스타일 매크로를 정의 할 수는 있지만 구조 함수 포인터에 "바인딩"하는 방법을 여전히 파악해야합니다.

#define push(a, b) a->array[a->used++] = (void*)b 
#define get(a, i, t) *(t*)a->array[i] 

과로를 사용 :

내가 가장 간단한 해결책은 단지 (짧은 그것을 유지하기 위해 지금 확인없이 작성)와 같은 함수 스타일 매크로를 정의 할 수 있습니다 상상

push(&a, &item); 
int item_ret = get(&a, 0, int); 

하지만, 계속 진행하는 방법에 대한 확신이 없습니다. 누군가 제게 조언 해주세요.

+1

'this.array = malloc (size * sizeof (void *)); 그리고'this.state = malloc (size * sizeof (int));'는'st_array'의 정의를 고려하지 마십시오. – Quentin

+2

"* 내 변수 유형 *에 캐스트해야합니다."C에서는 그렇지 않습니다. 'void' 포인터와의 변환은 C에서 암묵적으로 수행됩니다. 따라서 밀어 넣기에 대한 경우 캐스트를 삭제할 수 있습니다. – alk

+1

"* 진행 방법 *"어디로? – alk

답변

0

좋아, 내가 여기에 모아 그렇게 운이 좋았다 모든 건설적인 의견에서 학습 대답을 합산하고 있습니다 : 포인터 만의 배열을 저장할 수있는 선언 구조 st_array

주어진 그 선언은 void * arrayvoid ** array이되도록 수정 :

typedef struct st_array 
{ 
    void** array; 
    uint8_t size, used; 
    ... 
} st_array 

는 따라서 어떤 배열에 보내고 void*push()으로 캐스팅 할 필요가 있지만, 명시 적 캐스트는 물론 필요가없는 경우 012,필요한 값을 입력하십시오.

가장 간단한 방법은 크기 검사를 쉽게 수행 할 수 있도록 필요한 항목으로 포인터를 반환

#define get(struct_ptr, index, type) if(index <= struct_ptr->used) (type*)struct_ptr->array[index]; else NULL; (void)index 

매크로 함수 스타일을 정의하는

은 (최신 명령에만 힘을 사용 표기법 일관성을 위해 get() 문장의 끝에 ;을 사용).

함수 스타일의 매크로를 가리킬 수 없으므로 (컴파일 할 때 매크로의 코드가 대체되므로 실제 함수가 정의되지 않습니다.) 일관성을 위해 push() 함수는 포인터 참조없이 구현되어야합니다 구조.