2014-08-31 73 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);