简体   繁体   中英

My pointer in an array doesn't work as it supposed to

I wanted to create a function, that would accept an 1:array_of_int, and 2:size_of_array, then return sum of the 3 biggest int. Code follows:

#include <stdio.h>
#include <stdlib.h>

int max_3(int arr[], int asize)
{ 
   int max_arr[3];
   int max =0; 
   int sum = 0;
   int* pi; 

   for(int j=0; j<3; j++)
   {   
      for(int i =0; i<asize;i++)
      {   
         if(arr[i] > max)
         {
           max = arr[i];
           pi = (arr + i); // to know the address of the max int of 'i' cycle
         }
      }   
      max_arr[j] = max;
      *pi = 0; // make the max int = 0 so that the next 'i' cycle doesnt have the previous max in it 
               //(so it can look for another max value - the second one)
   }   

   for(int i=0; i<3; i++)
      sum += max_arr[i];

   return sum;
}


int main (int argc, char** argv) {
   int arr[6] = {1,5,9,12,16,14};
   printf("%i\n",max_3(arr, 6));
   return (EXIT_SUCCESS);
}

The pointer pi doesn't make the value of the current max value 0, and the next cycle in for (int i..) make the biggest one again as from the previous. So instead of returning max val1 + val2 + val3, it returned 3 * val1 (the biggest one) -- in my particular example - it printed out 48 instead of 42 (12 + 16 + 14) - as it should. But how when I make the value of address (which my pointer point to) as 0 ? I do not understand that properly.

Your if statement:

if (arr[i] > max)

isn't going to be entered after the first time you find max ( ie when j > 0 ).

You need to zero it after:

max_arr[j] = max;
max = 0;

The following proposed code:

  1. performs the desired functionality
  2. is very straight forward in its' algorithm
  3. incorporates a bubble sort for selecting the top three entries in the array
  4. eliminates the 'magic' number 6
  5. modifies the second parameter to type size_t as that is the type returned by sizeof()
  6. the expression: sizeof(arr)/sizeof(arr[0]) lets compiler calculate number of entries in array
  7. the statement: int arr[] = {1,5,9,12,16,14}; lets compiler allocate room for array
  8. avoids modifying the original array, when sorting

and now, the proposed code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>  // memcpy()


void swap(int *xp, int *yp) 
{ 
    int temp = *xp; 
    *xp = *yp; 
    *yp = temp; 
} 


// A function to implement bubble sort 
void bubbleSort(int arr[], size_t n) 
{ 
    size_t i;
    size_t j; 
    for (i = 0; i < n-1; i++)  
    {     
       // Last i elements are already in place    
       for (j = 0; j < n-i-1; j++)  
       {
            if (arr[j] > arr[j+1]) 
            {
              swap(&arr[j], &arr[j+1]); 
            }
        }
    }
} 


int max_3(int arr[], size_t asize)
{ 
    int localArray[ asize ];
    memcpy( localArray, arr, asize*sizeof( int ) );
    // sort array
    bubbleSort( localArray, asize );

    // calculate sum of max 3 entries
    int sum = localArray[asize-1] + localArray[asize-2] + localArray[asize-3];
    return sum;
}   


int main ( void ) 
{
   int arr[] = {1,5,9,12,16,14};
   printf( "%i\n", max_3( arr, sizeof(arr)/sizeof(arr[0])) );
   return (EXIT_SUCCESS);
}

a run of the proposed code results in:

42

After the very first iteration of the outer loop (the loop for(int j=0; j<3; j++) ) the value of max and pi will never change.

In that first iteration of the outer loop, you will find that the fifth element in the array will be largest, max will be equal to 16 and pi will point to that element. You set max_arr[0] to 16 and set *pi to zero. Then the outer loop starts over with max still being equal to 16 . And now there will be no value in the array that will be equal or larger than that. So you set max_arr[1] to 16 as well, and set *pi (where pi is still pointing to the fifth element) to zero again . And the same thing the next iteration.

The natural solution would be to define max and pi inside the outer loop:

for(int j=0; j<3; j++)
{
    // The variables will be redefined and reinitialized each iteration of the loop
    int max = 0;
    int *pi;

    for(int i =0; i<asize;i++)
    {
        if(arr[i] > max)
        {
            max = arr[i];
            pi = (arr + i); // to know the address of the max int of 'i' cycle
        }
    }
    max_arr[j] = max;
    *pi = 0; // make the max int = 0 so that the next 'i' cycle doesnt have the previous max in it
             //(so it can look for another max value - the second one)
}

There are a few other problems with the code, like for example the possibility that pi will never be initialized. I leave it as an exercise to the reader to figure when that will happen and how to solve it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM