2014-08-31 72 views
0

對於C編程,除了AVR微控制器的一些簡單的嵌入式編碼以外,我還是比較陌生。用指針返回函數值的正確方法

這裏最近我一直在試圖編寫一個簡單的環形緩衝區來接收串行數據,並且發現了一些似乎大部分工作的示例代碼。但是有一個指針傳遞給一個從環形緩衝區返回值的函數。不用說我努力去理解指針。

我附上了所有在Pelles C中完成的代碼,這看起來可行,但我不確定我是否正在處理來自int buf_get(char *pc)函數的*pc指針。我能夠編譯沒有錯誤或警告與附加的代碼。

是否有人請告訴我爲*pc設置變量的正確方法指向?

到目前爲止我使用的是char FromBuffer[1];,但我認爲它最好不過了。

/**************************************************************************** 
*                   * 
* File : main.c               * 
*                   * 
* Purpose : Console mode (command line) program.       * 
*                   * 
* History : Date  Reason            * 
*   8/28/2014 Ring Buffer Example         * 
*                   * 
***************************************************************************/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <conio.h>  //needed for _getch(),_getche() and _putch() 
#include <time.h>  //used by the random number generator to start seed based on time 

//============================= Constants =================================== 
#define BUFSIZE 16 

//============================= Functions =================================== 
void DumpBuffer(void); //Used to display buffer for debugging 
void buf_init(void); //Ring Buffer initialization 
int buf_put(char c); //Ring Buffer add function 
int buf_get(char *pc); //Ring Buffer get fucntion 

//============================= Global Variables============================= 
char buf[BUFSIZE];   //ring buffer 
char *pIn, *pOut, *pEnd; //pointers for buffer fucntions 
char full;     //fucntion value for buffer functions and control within 
char FromBuffer[1]; 
int BufferInputStatus;  //0 = FULL, 1 = OK 
int BufferOutputStatus;  //0 = EMPTY, 1 = OK 
long InputPointerBase;  //input pointer base value used during display of ring buffer 
long OutputPointerBase;  //output pointer base value used during display of ring buffer 

/**************************************************************************** 
*                   * 
* Function: main               * 
*                   * 
* Purpose : Main entry point.            * 
*                   * 
* History : Date  Reason            * 
*   8/28/2014 Ring Buffer Example         * 
*                   * 
***************************************************************************/ 
/**************************************************************************** 
MAIN function that does: 
1) 
2) 
****************************************************************************/ 
int main(int argc, char *argv[]) 
{ 
char CharIn; 
int RandomChar = 97;  //used by random character generator 
         //int num_between_x_and_y = (rand() % (X - Y)) + Y; 
int LastRandomChar =0;  //used to prevent two random char repeats in a row 

//tell the user the program has started 
printf("Start \n"); 

//seed the random number generator 
srand(time(NULL)); 

//initialize the ring buffer 
buf_init(); 

//find the base address of the pointers 
InputPointerBase = (long)(pIn); 
OutputPointerBase = (long)(pOut); 
printf("Base Address Input Pointer %x\n",(int)(InputPointerBase)); 
printf("Base Address Output Pointer %x\n",(int)(OutputPointerBase)); 


//Main loop that allows filling the buffer and removing from buffer 
//User used "i" or "o" to add or remove to ring buffer 
//User exits with "Q" 
while ((CharIn = _getch()) != 'Q') // "_getch()" does not wait for CR to return key and has no cho 
{ 
//add something to the input buffer 
if (CharIn == 'i') 
    { 
    RandomChar = (rand() % (122 - 97)) + 97; //get a ramdom character 

    //Only add to ring buffer is not a ramdom repeat 
    if (RandomChar != LastRandomChar) 
     { 
     printf ("Adding to buffer ==> %c\n", RandomChar); 
     LastRandomChar = RandomChar; 
     BufferInputStatus = buf_put((char)(RandomChar)); //add character to ring buffer 
     } 
    }//end of IF "input" 
//remove something from input buffer 
if (CharIn == 'o') 
    { 
    BufferOutputStatus = buf_get(FromBuffer); 
    } 
//Show what is in the buffer along with the input and output pointers 
DumpBuffer(); 

//Diaply what came out of the buffer 
printf("This was the output : %c\n",FromBuffer[0]); 

//printf("Input Pointing to %x\n",(int)(pIn)); 
if (BufferInputStatus == 1) printf("Buffer Input Status is OK\n"); 
    else printf("Buffer Input Status is FULL\n"); 

    if (BufferOutputStatus == 1) printf("Buffer Output Status is OK\n"); 
     else printf("Buffer Output Status is EMPTY\n"); 

    }//end of "While !='Q' " 
printf("Exit \n"); 
return 0; 
} 



void DumpBuffer(void) 
{ 
char BufferLocation = 0; 
char InputPointerValue = 0; 
char OutputPointerValue = 0; 

//Display the buffer pointers and buffer content 
for (BufferLocation = 0; BufferLocation < BUFSIZE; BufferLocation++) 
    { 
    //Show the location of the input pointer 
    InputPointerValue = (char)(pIn - InputPointerBase); 
    if (BufferLocation == InputPointerValue) printf("%-3s",">>>"); 
    else printf("%-3s",""); 

    //Show the buffer location 
    printf(":%-3d:",BufferLocation); 

    //Display what is in the buffer at that location 
    printf(":%-3c:",buf[BufferLocation]); 

    //Show the location of the output pointer 
    OutputPointerValue = (char)(pOut - OutputPointerBase); 
    if (BufferLocation == OutputPointerValue) printf("%-3s",">>>"); 
    else printf("%-3s",""); 

    //end the displayed line with a CR-LF 
    printf("\n"); 
    }//End of FOR-LOOP for printing buffers 
}//end of "DumpBuffer" 


/**************************************************************************** 
* Raw example code from:             * 
* Example code from:              * 
* http://stackoverflow.com/questions/827691/how-do-you-implement-a-circular-buffer-in-c 
*                   * 
* No changes were made!!!!            * 
*                   * 
****************************************************************************/ 

// init 
void buf_init(void) 
{ 
pIn = pOut = buf;  // init to any slot in buffer 
pEnd = &buf[BUFSIZE]; // past last valid slot in buffer 
full = 0;    // buffer is empty 
} 

// add char 'c' to buffer 
int buf_put(char c) 
{ 
if (pIn == pOut && full) 
    return 0;   // buffer overrun 

*pIn++ = c;    // insert c into buffer 
if (pIn >= pEnd)  // end of circular buffer? 
    pIn = buf;   // wrap around 

if (pIn == pOut)  // did we run into the output ptr? 
    full = 1;   // can't add any more data into buffer 
return 1;    // all OK 
} 

// get a char from circular buffer 
int buf_get(char *pc) 
{ 
if (pIn == pOut && !full) 
    return 0;   // buffer empty FAIL 

*pc = *pOut++;   // pick up next char to be returned 
if (pOut >= pEnd)  // end of circular buffer? 
    pOut = buf;   // wrap around 

full = 0;    // there is at least 1 slot 
return 1;    // *pc has the data to be returned 
} 
+0

如果要格式化指針值,請使用'%p'(並將值轉換爲'(void *)'。不要將其轉換爲整數類型,尤其是有符號整數類型,並使用'%x'(這是**無符號**類型)。 – dreamlax 2014-08-31 03:02:43

+0

你會給'pc'寫幾個字符? – 2014-08-31 03:17:05

+0

只有一個字符就像從串口收到一樣。 – 2014-08-31 04:33:37

回答

0

首先我們嘗試一些簡單操作,用指針賦值給一個變量:

char c; 
char *p; 
p = &c; 
*p = 'x'; 

然後我們做同樣的事情,但指針傳遞到執行動作的功能:

void foo(char *a) 
{ 
    *a = 'z'; 
} 

... 

char c; 
char *p; 
p = &c; 
foo(p); 

我們也可以用不必要的指針變量做掉:

char c; 
foo(&c); 

現在使用的陣列的元素:

char m[5]; 
char *p; 
p = &m[0]; 
*p = 'j'; 

數組變量的值是所述第一元件的地址,因此,我們可以這樣做:

char m[5]; 
char *p; 
p = m; 
*p = 'j'; 

因此,我們可以使用功能是這樣的:

char m[5]; 
char *p; 
p = m; 
foo(p); 

或者這樣說:

char m[5]; 
foo(m); 

這是否使事情清楚?

+0

是的,沒有。我需要在一些練習中嘗試以確保我完全理解。謝謝,傑拉爾德 – 2014-08-31 04:36:17

2

你問:

會有人請告訴我正確的方法來設置爲* PC中的變量指向?

看你的代碼,你如何使用FromBuffer,我會說:

  1. 獲得完全擺脫FromBuffer
  2. main,聲明一個變量

    char fromBufferChar; 
    
  3. 替換正在使用它fromBufferChar兩個地使用的FromBuffer

    變化

    BufferOutputStatus = buf_get(FromBuffer); 
    

    BufferOutputStatus = buf_get(&fromBufferChar); 
    

    變化

    printf("This was the output : %c\n",FromBuffer[0]); 
    

    printf("This was the output : %c\n",fromBufferChar);