2013-11-28 3 views
1

나는 기본적으로 (곱하기) 연결된 목록에 의해 멋지게 해결 될 것이라고 생각하는 문제를 해결하고 있습니다. 그러나, 내 플랫폼은 매우 제한된 SRAM을 가진 Arduino이므로 PROGMEM (avr/pgmspace.h 라이브러리 사용)에서이 모든 것을 유지하고 싶습니다.PROGMEM (Arduino)에서 연결된 목록 만들기

포인터가있는 구조체의 필드를 참조하는 데 문제가 있습니다. 또는 다른 말로하면, 나는 연결된 목록을 따르는 데 어려움을 겪고 있습니다. 여기

가 일부 코드입니다 (나는 그것을 짧게 만들려고했습니다) :

#include <avr/pgmspace.h> 

typedef struct list_item 
{ 
    const prog_char * header; 
    const struct list_item *next_item; 
}; 

// declarations 
extern const list_item PROGMEM first_item; 
extern const list_item PROGMEM second_item; 
extern const list_item PROGMEM third_item; 

// name 
const prog_char first_header[] PROGMEM = "Foo"; 
const prog_char second_header[] PROGMEM = "Bar"; 
const prog_char third_header[] PROGMEM = "Baz"; 

// instantiation & initialization 
const list_item first_item = { &first_header[0], &second_item }; 
const list_item second_item = { &second_header[0], &third_item }; 
const list_item third_item = { &second_header[0], &first_item }; 

// pointers to our items, just for testing 
list_item const * const pointer_to_first_item = &first_item; 
list_item const * const pointer_to_second_item = &second_item; 
list_item const * const pointer_to_third_item = &third_item; 

// prints the address of the pointer passed to it 
void print_pointer_address(char * description, const void * pointer) 
{ 
    Serial.print(description); 
    Serial.println((unsigned int) pointer,HEX); 
} 

// a test 
void setup() 
{ 
    Serial.begin(57600); 

    Serial.println("\n--addresses of everything--"); 

    print_pointer_address("pointer to first_item = ", pointer_to_first_item); 
    print_pointer_address("pointer to second_item = ", pointer_to_second_item); 
    print_pointer_address("pointer to third_item = ", pointer_to_third_item); 

    Serial.println("\n--go through list via pointers--"); 

    list_item const * the_next_item; 
    the_next_item = pointer_to_first_item; 
    print_pointer_address("item 1 = ", the_next_item); 

    the_next_item = the_next_item->next_item; 
    print_pointer_address("item 2 = ", the_next_item); 

    the_next_item = the_next_item->next_item; 
    print_pointer_address("item 3 = ", the_next_item); 

    the_next_item = the_next_item->next_item; 
    print_pointer_address("item 4 = ", the_next_item); 

} 

void loop() 
{ 
} 

그것은 출력 :

--addresses of everything-- 
pointer to first_item = 68 
pointer to second_item = 6C 
pointer to third_item = 70 

--go through list via pointers-- 
item 1 = 68 
item 2 = 6C 
item 3 = 1 
item 4 = 5350 

내 질문은 왜 않는 항목 3 같지 "70"?

아마도 저는 구조체를 읽으려면 pgmspace 함수 중 하나를 사용해야한다고 생각하지만 첫 번째 항목에 대해 왜 작동하는지 이해할 수 없습니다. 어떤 도움을 주셔서 감사합니다.

답변

1

좋아, 해결했다. PROGMEM의 구조체 필드에서 포인터를 가져 오는 올바른 방법은 다음과 같습니다.

the_next_item = (list_item*) pgm_read_byte(&(the_next_item->next_item)); 

확실히 혼란 스러웠습니다. 또한 첫 번째 몇 가지 예제에서 작동하는 것처럼 보인 사실은 잘못된 길로 나를 던져 넣은 붉은 청어였다. 나는 아직도 그것을 완전하게 설명 할 수 없다 - 아마도 운이 좋았을 것인가? 나는 잘 모르겠다.

포인터 및 PROGMEM에 대한 유용한 정보는 여기를 참조하십시오. http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

관련 문제