0

There are two program both work correct , can you explain me why?

//sorting of array using pointers
#define n 5
void sort(int m,int *x);
main()
{
    int i,a[n];

    printf("enter the values");
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    sort(n,a);//not sending the address but still my code works only when I define array but when i use int data type then I need to pass address , why is this so?
}
void sort(int m,int *x)
{
    int i,j,temp,k;
    for(i=1;i<=m-1;i++)
    {
        for(j=1;j<=m-1;j++)//this lop is to sort array
        {
            if(*(x+j-1)>=*(x+j))
            {
                temp=*(x+j-1);
                *(x+j-1)=*(x+j);
                *(x+j)=temp;
            }
        }
    }
    for(k=0;k<m;k++)
    {
        printf("\n%d\n",*(x));
        x++;//when i am not using *x++
    }
}

my progrm doest change or doesnt give error when i use this program

//sorting of arrays sing pointers
    #define n 5
    void sort(int m,int *x);
    main()
    {
        int i,a[n];

        printf("enter the values");
        for(i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        sort(n,&a);//and '&a' instead of 'a'
    }
    void sort(int m,int *x)
    {
        int i,j,temp,k;
        for(i=1;i<=m-1;i++)
        {
            for(j=1;j<=m-1;j++)//this loop is to sort array
            {
                if(*(x+j-1)>=*(x+j))
                {
                    temp=*(x+j-1);
                    *(x+j-1)=*(x+j);
                    *(x+j)=temp;
                }
            }
        }
        for(k=0;k<m;k++)
        {
            printf("\n%d\n",*(x));
            *x++;//here i have used *x++ instead of x++
        }
    }

why is it necessary to pass adress in function call when we define int data type and we do not need to pass address in array when calling a function , when we are woring in pointers? kindl clear my doubt.

1
  • 1
    main() should be int main(void), least. Where are the includes? Commented Mar 16, 2015 at 5:21

2 Answers 2

1

Your compilation results should certainly have changed.

Passing &a to a function expecting int * should have at-least flagged a compiler warning, and with any reasonably current standard compliant compiler, an outright error. The types int * and int(*)[5] are not synonymous. I don't know what toolchain you're using, but anything current should puke. For example, using std=c11 and clang 3.5 gives:

Incompatible pointer types passing 'int (*)[5]' to parameter of type 'int *'

Regardless, an array used in an expression as yours undergoes conversion to a pointer-to-type (in your case the type is int) who's value is the address of the first element in the sequence. Passing it as a parameter to a function results in such an expression, and thus such a conversion to a temporary pointer to int.

Thus,

foo(int *x);

int main()
{
    int ar[5];
    foo(ar);
}

results in x holding the address of ar's first element. The first element of an array also must reside at the address of the array itself, so strictly speaking the address expressed from ar and &ar are the same address. But the types of the pointer conversion results of those expressions are different. In the former case the pointer type is int *; a pointer to int. With the latter the type is int (*)[5]; a pointer to array-of-5-int. If you think it doesn't make a difference it certainly can, in particular with pointer arithmetic:

#include <stdio.h>

#define n 5

int main()
{
    int ar[n];

    printf("ar    = %p\n", ar);
    printf("ar+1  = %p\n", ar+1);
    printf("&ar   = %p\n", &ar);
    printf("&ar+1 = %p\n", &ar+1);

    return 0;
}

Output (Yours will vary, but differences should be similar)

ar    = 0x7fff5fbffa20
ar+1  = 0x7fff5fbffa24
&ar   = 0x7fff5fbffa20
&ar+1 = 0x7fff5fbffa34

Note how both ar and &ar reflect the same address, but pointer arithmetic of adding 1 demonstrates a significant difference when applied. That difference is due to the different type of these pointers. In the first it bumps by the size of an int. In the second it bumps by the size of an int[5]

Apologies to the purists that want all those addresses cast to void*. Sorry, its late.


Regarding x++ vs *x++, that is operator precedence at work. The postfix operator ++ has higher precedence than indirection *. As a result the solitary expression *x++; is effective something like:

  1. Take the value of the pointer x, store it in an unseen temporary.
  2. Increment the address in x.
  3. Apply the indirection operator * to the address saved to temp during (1). This is equivalent to *x before the increment.

Since you do nothing with the resulting valuation (3) becomes irrelavent and, *x++; is equivalent to x++; in final behavior: an increment of the address held in x equivalent to one type-width (int).

Sign up to request clarification or add additional context in comments.

Comments

0

You have to change the Declaration..

 #define n 5 
 void sort(int, int *); 
 main() 
 { 
  int i,a[n]; 
        printf("enter the values"); 
        for(i=0;i<n;i++)
        { 
          scanf("%d",&a[i]); 
        }
  sort(n,a);
 } 

 void sort(int m, int *x)
 { 
   int i,j,temp,k; 
         for(i=1;i<=m-1;i++) 
         {
           for(j=1;j<=m-1;j++)
           {
             if(*(x+j-1)>=*(x+j))
             {
              temp=*(x+j-1);
              *(x+j-1)=*(x+j); 
              *(x+j)=temp;
             }
           }
         } 
   for(k=0;k<m;k++)
   {
     printf("\n%d\n",*(x)); 
     x++;
    }
  }

1 Comment

Only one line is changed. Instead of void sort(int m, int *x); use void sort(int, int *);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.