2016-03-05 24 views
1

我正在爲AVR編碼一段代碼。我想構建一個可以推送和彈出的隊列,並且此隊列是一個字符數組(字符串)。所以,當我把 '一':
['b', 'c', 'd', 'e', 'f']
變爲:
['a','b', 'c', 'd', 'e', 'f']
當我彈出,f出來。我已經寫了這段代碼,但它只將1個字符推送到隊列中,就好像它刪除了整個隊列。這裏是我的隊列代碼:
作爲隊列中的字符數組C

char queue[50] = ""; 
char* queue_tail = &queue[0]; 
char* queue_head = &queue[0]; 

void queue_push(char l_item) 
{ 
    if(queue_head != &queue[strlen(queue) - 1]) //if queue is not full, do the job 
    { 
     //Push all elements one step further 
     char* traveler = queue_head; 
     for(; traveler != queue_tail; --traveler) 
     { 
      *(traveler+1) = *traveler; 
      *traveler = ''; 
     } 
     ++queue_head; 
     *queue_tail = l_item; 
    } 
} 

char queue_pop() 
{ 
    char temp = *queue_head; 
    *queue_head = ''; 
    --queue_head; 
    return temp; 
} 

這是我的主要功能:

#include <mega32.h> 
#include <alcd.h> 
#include <delay.h> 
#include <string.h> 

void main(void) 
{ 

const char text[] = "Hello world!"; 
int col_counter = 0; 
char* p_head = ''; 

lcd_init(32); 
p_head = &text[12]; 

while(1) 
{ 
    lcd_clear(); 

    if(col_counter + strlen(text) > 32) 
    { 
     queue_push(*p_head); 
     --p_head; 
    } 

    lcd_gotoxy(col_counter, 0); 
    lcd_puts(text); 
    lcd_gotoxy(0,0); 
    lcd_puts(queue); 
    delay_ms(200); 
    ++col_counter; 

} 
} 

任何幫助,將不勝感激。提前致謝。

+1

'strlen(隊列)'可能爲0,則'queue [strlen(queue)-1]'超出範圍。 – MikeCAT

+0

爲什麼'strlen(隊列)'爲0? –

+0

因爲你用空字符串初始化了'queue'。 – MikeCAT

回答

1

我將queue_head的含義從最後一個元素更改爲一個超過隊列中最後一個元素的值,並調整了代碼。

這裏是一個校正的碼(在該代碼main()是用於通常的PC的測試代碼):

#include <stdio.h> 

char queue[50] = ""; 
char* queue_tail = &queue[0]; 
char* queue_head = &queue[0]; 

void queue_push(char l_item) 
{ 
    if(queue_head != queue + sizeof(queue)/sizeof(*queue)) //if queue is not full, do the job 
    { 
     //Push all elements one step further 
     char* traveler = queue_head; 
     for(; traveler != queue_tail; --traveler) 
     { 
      *traveler = *(traveler - 1); 
     } 
     ++queue_head; 
     *queue_tail = l_item; 
    } 
} 

char queue_pop(void) 
{ 
    char temp; 
    if (queue_head == queue_tail) return '\0'; // the queue is empty 
    --queue_head; 
    temp = *queue_head; 
    *queue_head = '\0'; 
    return temp; 
} 

int main(void) { 
    queue_push(100); 
    queue_push(110); 
    printf("%d\n",queue_pop()); 
    printf("%d\n",queue_pop()); 
    return 0; 
} 
0

提案的環形緩衝器實現(避免了需要將緩衝區的內容複製來回):

char queue[50] = ""; 
char* queue_tail = &queue[0]; 
char* queue_head = &queue[0]; 

#define END_OF_QUEUE (&queue[sizeof(queue)/sizeof(*queue)]) // The first element _after_ the buffer. 

#define QUEUE_NOT_FULL 0 
#define QUEUE_IS_FULL 1 

uint8_t queueState; 

void queue_push(const char l_item) 
{ 
    // 0) Addition is always modulus buffer size (50) 
    // 1) head points to the next empty location which can store an incoming byte 
    // 2) tail points to the next location from where a byte may be read 
    // 3) Queue is empty iff tail == head && queueState == QUEUE_NOT_FULL 
    // 4) Queue is full iff tail == head && queueState == QUEUE_IS_FULL 

    if (queueState == QUEUE_NOT_FULL) { 

     // Store item to the current head: 
     *queue_head = l_item; 

     // Advance head by one: 
     queue_head++; 

     if (queue_head == END_OF_QUEUE) { 
      // head passed the end of buffer -> continue at the start: 
      queue_head = &queue[0]; 
     } 

     // If head meets tail after appending the new element, the buffer is now full. 
     if (queue_head == queue_tail) { 
      queueState = QUEUE_IS_FULL; 
     } 

    } else { 
     // Buffer overflow! - Options: Ignore new data, overwrite old data, wait until not full, signal an error somehow. 
    } 

} 

char queue_pop() 
{ 

    if ((queue_tail == queue_head) && (queueState == QUEUE_NOT_FULL)) { 
     // Queue is empty. "Buffer underflow." - Options: Return dummy value, wait until data available, signal an error somehow. 
     return '\0'; 
    } else { 
     const char result = *queue_tail; 
     queue_tail++; 

     if (queue_tail == END_OF_QUEUE) { 
      // tail passed the end of buffer -> continue at the start: 
      queue_tail = &queue[0];   
     } 

     // We just removed an element from the queue, so the queue cannot be full now even if it was full a moment ago. 
     queueState = QUEUE_NOT_FULL; 

     return result; 
    } 

} 

(注意,無需進一步的同步分量,該代碼將無法正常同時運行時,工作即訪問來自一個ISR內的緩衝器(讀或寫)時。)