arrayscfor-loopduplicatespost-increment

C language: When [variables++] in array[ ] work? For example, when array[j++] = arr[i]. It is doing j++ first or do = arr[i] first?


disclaimer this is not my code and this code is from Remove Duplicate Elements from an Array in C - Javatpoint

What I want to know is in the Example 2 coding part. (I edit code a bit for me or you can see the code clearly.)

/* program to delete the duplicate elements from sorted array in C. */  
#include <stdio.h>  
  
int duplicate_element ( int arr[], int num)  
{  
    // check num is equal to 0 and num == 1  
    if (num == 0 || num == 1)  
    {        
        return num;  
    }
         
    // create temp array to store same number     
    int temp [num];   
      
    // declare variable  
    int i, j = 0;  
      
    // use for loop to check duplicate element  
    for (i = 0; i < num - 1; i++)  
    {  
        // check the element of i is not equal to (i + 1) next element  
        if (arr [i] != arr[i + 1])  
        {            
             temp[j++] = arr[i];  
        }
    }
  
    temp[j++] = arr[ num - 1];  
  
    // check the original array's elements with temporary array's elements  
    for (i = 0; i < j; i++)  
    {  
        arr[i] = temp[i];  
    }     
          
    return j;     
}  
  
int main ()  
{  
    int num;

    printf (" Define the no. of elements of the array: ");  
    scanf (" %d", &num);  
      
      
    int arr[num], i;  
      
    printf (" Enter the elements: ");  
    // use loop to read elements one by one  
    for ( i = 0; i < num; i++)  
    {  
        scanf (" %d", &arr[i]);  
    }  
      
    printf (" \n Elements before removing duplicates: ");  
    
    for ( i = 0; i < num; i++)  
    {  
        printf (" %d", arr[i]);  
    }  
      
    num = duplicate_element (arr, num);  
      
    // print array after removing duplicates elements  
    printf (" \n Display array's elements after removing duplicates: ");  
    
    for ( i = 0; i < num; i++)  
    {  
        printf (" %d", arr[i]);  
    }     
          
    return 0;     
      
}  

Here's the question, what does all j++ in function duplicate_element do? (If possible I would like to know what the code is doing since line // use for loop to check duplicate element until before return too. This part I'm just curious if I know it correctly or not.)

This is my understanding (j is the final size of arr[]). In the first question, when executed

j right now is 0

temp[j++]

is it plus the value of j by 1 first then assign value arr[i] to temp[1]. (Does this right?)

The second question, in the first for loop checks when the value in arr[i] is not equal to the value in arr[i + 1] then assign value in temp[j++] with value in arr[i] until for loop is over then assign temp[j++] with arr[num - 1]

(j++ right now is dependent on the if condition for example when all value is not equal to the value of j++ == value of num - 1 and num - 1 is equal to the last value of arr)

and in the last for loop, it assigns every value in Array arr with Array temp. (Does this right?)


Solution

  • For starters the code is very bad.

    Firstly, the function should be declared like

    size_t duplicate_element ( int arr[], size_t num );  
    

    That is the size of the passed array should be specified using the unsigned integer type size_t instead of the signed int type int. Otherwise this declaration of the variable length array

    // create temp array to store same number     
    int temp [num]; 
    

    along with this statement

    temp[j++] = arr[ num - 1];
    

    will invoke undefined behavior if the user will pass as the second argument a negative number and according to the function specification it allows to pass a negative number.

    Secondly, using the variable length array temp

    // create temp array to store same number     
    int temp [num]; 
    

    makes the function unsafe. It can occur such a way that the program will be unable to define this variable length array.

    The approach is too complicated, confusing and inefficient.

    As for your question relative to the postfix operator ++ then according to the C Standard (6.5.2.4 Postfix increment and decrement operators)

    2 The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it).

    So in fact this statement

    temp[j++] = arr[i];
    

    may be equivalently rewritten like

    temp[j] = arr[i];
    j += 1;
    

    As the function adds to the array temp the last element in a series of duplicated elements in the array arr then after this main loop

    // use for loop to check duplicate element  
    for (i = 0; i < num - 1; i++)  
    {  
        // check the element of i is not equal to (i + 1) next element  
        if (arr [i] != arr[i + 1])  
        {            
             temp[j++] = arr[i];  
        }
    }
    

    you need to add the last element pf the array arr to the array temp

    temp[j++] = arr[ num - 1];
    

    Here is a demonstration program that shows how the function can be rewritten and can look more simpler.

    #include <stdio.h>
    
    size_t duplicate_element( int a[], size_t n )
    {
        size_t m = 0;
    
        for (size_t i = 0; i < n; i++)
        {
            if (i == 0 || a[i] != a[m-1])
            {
                if (i != m) a[m] = a[i];
                ++m;
            }
        }
    
        return m;
    }
    
    int main( void )
    {
        int a[] = { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 };
        const size_t N = sizeof( a ) / sizeof( *a );
    
        for (size_t i = 0; i < N; i++)
        {
            printf( "%d ", a[i] );
        }
        putchar( '\n' );
    
        size_t m = duplicate_element( a, N );
    
        for (size_t i = 0; i < m; i++)
        {
            printf( "%d ", a[i] );
        }
        putchar( '\n' );
    }
    

    The program output is

    1 2 2 3 3 3 4 4 4 4 5 5 5 5
    1 2 3 4 5