bubble sorting arrays

Hi,

I’ve got a mock array of temperature values. I can print it, but when I try to sort it, it doesn’t seem to work using the bubble array in my function, but I don’t know why.

It just prints the original array, which surprises me, since I declared the original array, temps, as a global variable so I thought it would get edited in the sorting function, and then be usable as a sorted array thereafter.

/***** GLOBAL VARIABLES *****/
const int arraySize = 10;
int temps[arraySize] = { 76, 77, 46, 83, 47, 55, 59, 34, 61, 83 };
int min_temp_value;
int max_temp_value;

int a = 0;  // used in for loop for printing raw temp data
bool printOnce = true;    // printing array data
bool printValues = true;  // print min and max temps
bool resetVars = true;    // reset vars to enable printing array data



/***** FUNCTION PROTOTYPES *****/
int sort_temps(int temps[]);  // takes temps array, and will sort, low to high into new array
int min_temp(int temps[]);    
int max_temp(int temps[]); 

void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  // print original array
  for (a; a < arraySize; a++)
    {
       if (printOnce == true)
      {
        Serial.print("raw temp data = { ");
        printOnce =! printOnce; // toogles true to false
      }
      
      // test for last element in array
       if (a == (arraySize - 1))
         {           
           Serial.print(temps[a]);
           Serial.println(" }");  // end of data set
         }

          else
            {
              Serial.print(temps[a]);
              Serial.print(", ");      
            }
    }

   

  // function call to sort original array
int sort_temps(int temps[]);

  
  // print sorted array

    // reset vars to defults
    if (resetVars == true)
      {
        a = 0;
        printOnce = true;
        resetVars =! resetVars;
      }
    
    for (a; a < arraySize; a++)
    {
       if (printOnce == true)
      {
        Serial.print("sorted temp data = { ");
        printOnce =! printOnce; // toogles true to false
      }
      
      // test for last element in array
       if (a == (arraySize - 1))
         {           
           Serial.print(temps[a]);
           Serial.println(" }");  // end of data set
         }

          else
            {
              Serial.print(temps[a]);
              Serial.print(", ");      
            }
    }




}

/***** FUNCTIONS *****/
// sort temp array, low to high
int sort_temps(int temps[])
  {      
    int hold;
    
    // bubble sort, make 9 passes, as number of req. passes = arraySize - 1
    for (int passCounter = 0; passCounter < arraySize - 1; passCounter++) 
      {
        // number of comparisons per pass
        for (int i = 0; i < arraySize - 1; i++)
          {
            // compare adjacent elements and swap them if left element is larger than next element to its right
            if (temps[i] > temps[i+1])
              {
                hold = temps[i]; // stores left element, to be swapped into position to right 
                temps[i] = temps[i+1];
                temps[i+1] = hold;
              }
          }
      }

      // return temps; // returns temps array with its elements sorted from low to high
      return 0;  // don't need to return anything, as the fed in array, temps[], has been changed
    }

for (a; a < arraySize; a++)Oops

  // function call to sort original array
int sort_temps(int temps[]);

That is not calling anything. That is only declaring a function prototype.

Cleaner version of code.

/***** GLOBAL VARIABLES *****/
int temps[] = { 76, 77, 46, 83, 47, 55, 59, 34, 61, 83 };
const int arraySize = sizeof(temps)/sizeof(int);
int min_temp_value;
int max_temp_value;

/***** FUNCTION PROTOTYPES *****/
void sort_temps(int temps[]);  // takes temps array, and will sort, low to high into new array
int min_temp(int temps[]);
int max_temp(int temps[]);

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  // print original array
  Serial.print("raw temp data = { ");
  for (int a = 0; a < arraySize; a++)
  {
    Serial.print(temps[a]);
    if (a < (arraySize - 1)) Serial.print(", ");
  }
  Serial.println(" }");  // end of data set

  // function call to sort original array
  sort_temps(temps);

  Serial.print("sorted temp data = { ");

  for (int a = 0; a < arraySize; a++)
  {
    Serial.print(temps[a]);
    if (a < (arraySize - 1)) Serial.print(", ");
  }
  Serial.println(" }");  // end of data set
}

/***** FUNCTIONS *****/
// sort temp array, low to high
void sort_temps(int temps[])
{
  int hold;
  bool swaps = true;

  // bubble sort, make 9 passes, as number of req. passes = arraySize - 1
  while (swaps)
  {
    swaps = false;
    // number of comparisons per pass
    for (int i = 0; i < arraySize - 1; i++)
    {
      // compare adjacent elements and swap them if left element is larger than next element to its right
      if (temps[i] > temps[i + 1])
      {
        swaps = true;
        hold = temps[i]; // stores left element, to be swapped into position to right
        temps[i] = temps[i + 1];
        temps[i + 1] = hold;
      }
    }
  }
}

Got it! Thanks for the help, I fixed the issues. Not totally efficient, but it works. Below is my code. However, below that, is what I want to do now, is take the code, and instead of using pass-by-value into functions, I wanted to learn pass-by-reference. It’s new to me, so I took the original code (below), and tried to do my best to modify it to pass-by-value (which is below it). That’s where things go wrong.

// Pass By Value (original code - attached)

// Pass By Reference (new code)

/***** LIBRARIES AND HEADERS *****/
#include <stdio.h>  // what is this doing?

/***** GLOBAL VARIABLES *****/
const int arraySize = 10;
int temps[arraySize] = { 76, 77, 46, 83, 47, 55, 59, 34, 61, 83 };
int min_temp;
int max_temp;
int temp_stats;     // will get sorted temps and min / max, used in loop

bool printOnce = true;    // printing array data
bool printValues = true;  // print min and max temps
bool resetVars = true;    // reset vars to enable printing array data



/***** FUNCTION PROTOTYPES *****/
int sort_and_calc_temps(int temps[], int *min_temp, int *max_temp);  // takes temps array, and will sort, low to high into new array, then get min / max temps from it
//int min_temp(int temps[]);    
//int max_temp(int temps[]); 

void setup() 
{
  Serial.begin(9600);
}

void loop() 
{

  if (printOnce == true)
      {
        Serial.print("raw temp data = { ");
        printOnce =! printOnce; // toogles true to false
      
       // print original array
       for (int a = 0; a < arraySize; a++)
       {
    
                // test for last element in array
           if (a == (arraySize - 1))
             {           
               Serial.print(temps[a]);
               Serial.println(" }");  // end of data set
             }

              else
                {
                  Serial.print(temps[a]);
                  Serial.print(", ");      
                }
       }
     }

   

// function call to sort original array
temp_stats = sort_and_calc_temps(temps, &min_temp, &max_temp);  
                     /* When passing the array into a function, you don't include the brackets [], 
                       just the variable name

                       This allows the function call to reference the lvalue of the array.  This occurs since arrays are reference types, rather than value types.
                    */

  
// print sorted array

    // reset vars to defults
if (resetVars == true)
    {
      printOnce = true;
      resetVars =! resetVars;
    
    
        for (int a = 0; a < arraySize; a++)
        {
           if (printOnce == true)
          {
            Serial.print("sorted temp data = { ");
            printOnce =! printOnce; // toogles true to false
          }
          
          // test for last element in array
           if (a == (arraySize - 1))
             {           
               Serial.print(temps[a]);
               Serial.println(" }");  // end of data set
             }
    
              else
                {
                  Serial.print(temps[a]);
                  Serial.print(", ");      
                }
        }
}

// print once
if (printValues == true)
{
   printValues =! printValues; // toggles so doesn't run again

  // print min temp
  Serial.print("min temp = ");
  Serial.println(&min_temp);
  
  // print max temp
  Serial.print("max temp = ");
  Serial.println(&max_temp);
}



}

/***** FUNCTIONS *****/


// Follwing function does 3 things: (1) sort temp array, low to high, (2) calc min from new array (3) max from new array
int sort_and_calc_temps(int temps[], int *min_temp, *int max_temp)
  { 
    /***** Sorting Array of Raw Temps - Will Overwrite for New Array of Now Sorted Temps, Low to High *****/
    int hold;
    
    // bubble sort, make 9 passes, as number of req. passes = arraySize - 1
    for (int passCounter = 0; passCounter < arraySize - 1; passCounter++) 
      {
        // number of comparisons per pass
        for (int i = 0; i < arraySize - 1; i++)
          {
            // compare adjacent elements and swap them if left element is larger than next element to its right
            if (temps[i] > temps[i+1])
              {
                hold = temps[i]; // stores left element, to be swapped into position to right 
                temps[i] = temps[i+1];
                temps[i+1] = hold;     // new array of sorted temps has been created
              }
          }
      }


        /***** Min temp from sorted array *****/ 
        *min_temp = temps[0]; // gets 1st element in array
  
        /***** Max temp from sorted array *****/ 
        *max_temp = temps[arraySize - 1]; // gets last element in array

  return hold; // it's an int to return, but unsure if I'll need to do anything with it 
  
}

When I compile, I see several errors, but I want to start with just two:

  1. When compiling, I get errors msg in the function part of code (after loop):
Temperature_5_pass_by_reference:155:53: error: expected identifier before '*' token
 int sort_and_calc_temps(int temps[], int *min_temp, *int max_temp)
                                                     ^
Temperature_5_pass_by_reference:155:54: error: expected ',' or '...' before 'int'
 int sort_and_calc_temps(int temps[], int *min_temp, *int max_temp)
  1. I get an error msg:
error: no matching function for call to 'println(int*)'
   Serial.println(&min_temp);

I’m confused here because I thoughts that:
*min_temp = &min_temp
*max_temp = &max_temp

Where should I start with to fix these?

Temperature_4_upload.ino (3.96 KB)

int *min_temp, *int max_temp

Let’s play spot the difference.

Serial.println(&min_temp); There is no overload of print that accepts an int pointer.

project_science:
I'm confused here because I thoughts that:
*min_temp = &min_temp
*max_temp = &max_temp

Yep, you seem a bit confused.

A variable 'max_temp' which can store an int...

int max_temp;

A pointer 'p_max' to that int variable (& gets the address of the memory location and puts it in the pointer 'p_max')...

int* p_max = &max_temp;

Entirely equivalent to...

int* p_max;
p_max  = &max_temp;

Setting the 'max_temp' variable via the pointer (* dereferences the pointer and sets what is in that memory location to the result of the expression)...

*p_max = 1234;

Printing/accessing the 'max_temp' variable directly...

Serial.println(max_temp);

Printing/accessing the 'max_temp' variable via the pointer (again * dereferences and gets what is in the memory location pointed to by the pointer)...

Serial.println(*p_max);

Edit:
By far the hardest part of this is getting your head round the fact that * has two usages:

  1. defining a pointer variable:
int* p_max;
  1. dereferencing that pointer to get at the actual variable (both read and write):
*p_max = 1234;
Serial.println(*p_max);

Wow, thanks for your input - I got the code to work! I fixed a dumb error in my function arguments, and I changed how I was printing.

/***** LIBRARIES AND HEADERS *****/
#include <stdio.h>  // what is this doing?

/***** GLOBAL VARIABLES *****/
const int arraySize = 10;
int temps[arraySize] = { 76, 77, 46, 83, 47, 55, 59, 34, 61, 83 };
int min_temp;
int max_temp;

int *ptr_min_temp = NULL;  // will be dereferenced, and equated to l-value of min_temp, so when referenced in print re-using *, it will print r-value of min_temp
int *ptr_max_temp = NULL;  // will be dereferenced, and equated to l-value of max_temp, so when referenced in print re-using *, it will print r-value of max_temp

int temp_stats;     // will get sorted temps and min / max, used in loop

bool printOnce = true;    // printing array data
bool printValues = true;  // print min and max temps
bool resetVars = true;    // reset vars to enable printing array data



/***** FUNCTION PROTOTYPES *****/
int sort_and_calc_temps(int temps[], int *min_temp, int *max_temp);  // takes temps array, and will sort, low to high into new array, then get min / max temps from it


void setup() 
{
  Serial.begin(9600);
}

void loop() 
{

  if (printOnce == true)
      {
        Serial.print("raw temp data = { ");
        printOnce =! printOnce; // toogles true to false
      
       // print original array
       for (int a = 0; a < arraySize; a++)
       {
    
                // test for last element in array
           if (a == (arraySize - 1))
             {           
               Serial.print(temps[a]);
               Serial.println(" }");  // end of data set
             }

              else
                {
                  Serial.print(temps[a]);
                  Serial.print(", ");      
                }
       }
     }

   

// function call to sort original array
temp_stats = sort_and_calc_temps(temps, &min_temp, &max_temp);  
                     /* When passing the array into a function, you don't include the brackets [], 
                       just the variable name

                       This allows the function call to reference the lvalue of the array.  This occurs since arrays are reference types, rather than value types.
                    */

  
// print sorted array

    // reset vars to defults
if (resetVars == true)
    {
      printOnce = true;
      resetVars =! resetVars;
    
    
        for (int a = 0; a < arraySize; a++)
        {
           if (printOnce == true)
          {
            Serial.print("sorted temp data = { ");
            printOnce =! printOnce; // toogles true to false
          }
          
          // test for last element in array
           if (a == (arraySize - 1))
             {           
               Serial.print(temps[a]);
               Serial.println(" }");  // end of data set
             }
    
              else
                {
                  Serial.print(temps[a]);
                  Serial.print(", ");      
                }
        }
}

// print once
if (printValues == true)
{
   printValues =! printValues; // toggles so doesn't run again

  // print min temp
  ptr_min_temp = &min_temp;  // passes address (l-value) of min_temp into r-value of var ptr_max_temp
  Serial.print("min temp = ");
  Serial.println(*ptr_min_temp);
  
  // print max temp
  ptr_max_temp = &max_temp;  // passes address (l-value) of max_temp into r-value of var ptr_max_temp
  Serial.print("max temp = ");
  Serial.println(*ptr_max_temp);
}



}

/***** FUNCTIONS *****/


// Follwing function does 3 things: (1) sort temp array, low to high, (2) calc min from new array (3) max from new array
int sort_and_calc_temps(int temps[], int *min_temp, int *max_temp)
  { 
    /***** Sorting Array of Raw Temps - Will Overwrite for New Array of Now Sorted Temps, Low to High *****/
    int hold;
    
    // bubble sort, make 9 passes, as number of req. passes = arraySize - 1
    for (int passCounter = 0; passCounter < arraySize - 1; passCounter++) 
      {
        // number of comparisons per pass
        for (int i = 0; i < arraySize - 1; i++)
          {
            // compare adjacent elements and swap them if left element is larger than next element to its right
            if (temps[i] > temps[i+1])
              {
                hold = temps[i]; // stores left element, to be swapped into position to right 
                temps[i] = temps[i+1];
                temps[i+1] = hold;     // new array of sorted temps has been created
              }
          }
      }


        /***** Min temp from sorted array *****/ 
        *min_temp = temps[0]; // gets the address of where the 1st element in array is stored, and copies it to r-value of the pointer
        //ptr_min_temp = &min_temp;  // passes address (l-value) of min_temp into r-value of var ptr_max_temp
        
  
        /***** Max temp from sorted array *****/ 
        *max_temp = temps[arraySize - 1]; // gets the address of where the last element in array is stored, and copies it to r-value of the pointer
        //ptr_max_temp = &max_temp;  // passes address (l-value) of max_temp into r-value of var ptr_max_temp
        

  return hold; // it's an int to return, but unsure if I'll need to do anything with it 
  
}

But I’m a bit confused why it works in some areas. Here’s what I think is going on:

When I called the function in the loop, I’m passing the pointers *min_temp and *max_temp, along with the temp array into the function sort_and_calc_temps. After sorting the array, I did the following:

*min_temp = temps[0]; // gets the address of where the 1st element in array is stored, and copies it to r-value of the pointer

This copies the address of where the 1st element of the array is stored into the r-value of the pointer. (The following does similar.)

*max_temp = temps[arraySize - 1]; // gets the address of where the last element in array is stored, and copies it to r-value of the pointer

By the function call, I passed the temp array, and the address of min_temp and max_temp into the function sort_and_calc_temps. This has the equivalent:

int *min_temp = &min_temp;
int *max_temp = &max_temp;

I then printed the values of the temps:

// print min temp
  ptr_min_temp = &min_temp;  // passes address (l-value) of min_temp into r-value of var ptr_max_temp
  Serial.print("min temp = ");
  Serial.println(*ptr_min_temp);

Here, I dereferenced the pointer *ptr_min_temp to the var int ptr_min_temp, and had it store the address of min_temp in its r-value.

I then printed the pointer *ptr_min_temp which, because it has access to the address of var min_temp, it thus printed the r-value of min_temp.

  1. Does this makes sense how I’ve described what’s occurring in my code?

  2. Why was I not able to put the following line in the function? It only let me use it in the loop:

ptr_min_temp = &min_temp;  // passes address (l-value) of min_temp into r-value of var ptr_max_temp