0

I'm rather new to C programming other than some simple embedded coding for AVR micro-contollers.

Here lately I have been trying to write a simple ring buffer for receiving serial data and have found some example code that seems to work for the most part. But has a pointer passed to a function for returning the value from the ring buffer. Needless to say I struggling to understand pointers.

I have attached all my code done in Pelles C, which seems to work, BUT I not sure if I'm dealing with the *pc pointer from the int buf_get(char *pc) function. I was able to compiler with no error or warning with the attached code.

Would someone please tell me the correct way to setup a variable for the *pc to point?

So far I'm using char FromBuffer[1];, but I think it sloppy at best.

/****************************************************************************
 *                                                                          *
 * 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
}
timrau
  • 22,578
  • 4
  • 51
  • 64

2 Answers2

2

You asked:

Would someone please tell me the correct way to setup a variable for the *pc to point?

Looking at your code and how you are using FromBuffer, I would say:

  1. Get rid of FromBuffer altogether.
  2. In main, declare a variable

    char fromBufferChar;
    
  3. Replace the use of FromBuffer in the two places that you are using it with fromBufferChar.

    Change

     BufferOutputStatus = buf_get(FromBuffer);
    

    to

     BufferOutputStatus = buf_get(&fromBufferChar);
    

    Change

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

    to

    printf("This was the output : %c\n",fromBufferChar);
    
R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

First we try something simple, using a pointer to assign a value to a variable:

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

Then we do the same thing, but pass the pointer to a function which performs the action:

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

...

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

We can also do away with the unnecessary pointer variable:

char c;
foo(&c);

Now use an element of an array:

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

The value of the array variable is the address of the first element, so we can do this:

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

Therefore we can use the function this way:

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

or this way:

char m[5];
foo(m);

Does that make things clear?

Beta
  • 96,650
  • 16
  • 149
  • 150