1

Why does this program produce p and q as outputs? What is the difference between passing an array as a pointer or as an array.

 #include<stdio.h>

  void fun(char i[]){
   printf("%c,%c", i[1],i[2]);
  }
  void fun2(char *i){
    printf("\n%c,%c", i,i+1);
  }
  int main(){
    char ar[] = {"Aba"};   
    fun(ar);
    fun2(ar);
    return 0;
  }

Output:

  b,a
  p,q
1
  • You must be using a 32-bit compiler to see p,q (consecutive letters), and you are 'lucky' that the values printed are letters. If you were using a 64-bit system, the characters printed would almost certainly not be correlated like that. Commented Aug 27, 2016 at 17:04

4 Answers 4

3

You are printing the ASCII conversion of a pointer address in the second function. You must dereference the pointer via *i and *(i+1).

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

3 Comments

I did as you said and the output gives me A and B, why is B capital as well?
I have modified his answer to *(i+1) and *(i+2), Change that and you will get the correct output :)
It is probably capitalized because you did *i + 1 instead of *(i +1)
0

To print the value you should use either *i and *(i+1) or i[0] and i[1] in both the functions. i contains the first address cell of the array you have passed. In either cases, both pass their address.

Comments

0

what is the difference between passing array as pointer or as an array.

Both functions, fun and fun2, signatures are equivalent. So, you don't really have an array in fun() as you think. This is because in C, when you pass an array to a function, it gets converted into a pointer to its first element.

So, this statement in fun2()

printf("\n%c,%c", i,i+1);

doesn't print the chars but the addresses i and i+1. And that's not right either since they don't match with the format specifies you have.

When I compiled your code with gcc, it warns:

In function ‘fun2’:
warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=]
     printf("\n%c,%c", i,i+1);
            ^
warning: format ‘%c’ expects argument of type ‘int’, but argument 3 has type ‘char *’ [-Wformat=]

As you can see, the format specifiers and the arguments you pass don't match. To print values that i and i+1 point to, you can print it just like how you do in fun():

 int fun2(char *i){
    printf("\n%c,%c", i[1],i[2]);
 }

Comments

-1

Hope my long answer here helps!

I have taken integers, the concept remains the same with any data type: char, floats, etc, etc.

Okay, a quick short lesson on arrays and pointers.

Thumb rule 1: Arrays and pointers are almost always interchangable but there are exceptions!

Taking a 1-D array, we can declare it like this :-

int arr[10];

This declares a variable named arr which can hold 10 integer elements.

I can similarly use the pointer notation to represent this array using a pointer variable or by using the array name (arr) itself.

printf ("%d", arr[2]); // Array method : will print out the third element, indexing starts from 0

Thumb rule 2: Array name(be it 1D 2D 3D 4D) always decays into a pointer or an address.

printf ("%lu", arr) //will print out the base address of the array, i.e address of the first element

How to print the value using a pointer ? Simply, dereference it using * operator.

printf("%d", *arr) //Pointer notation - will print the first value

How to reference the array using another variable?

 int *ptr = arr; //Pointer notation - just simply write the array name as it decays into an address

printf("%d", *ptr); //Pointer notation - prints the first element

Many people say int *ptr is pointer to an array.

In reality it's not. It's actually a pointer to an integer not an array. Why?

Because in the first place we are storing the address of the first integer of the array and then we can traverse it by incrementing the pointer. So, in real pointer is storing the address of an integer(First integer).

Now, coming to 2D arrays :-

Declaration:-

int arr[2][3]; // arrays of 2 rows and 3 columns, total 6 elements

Same above rules implies :-

printf("%d", arr[0][1]); //prints the second element of the first row.

printf("%lu", arr) //prints the base address of the 2D array

Coming to Pointer Notation :-

printf("%d", *(*(arr + 0) + 1); // how this works?

arr contains the address. Adding a integer to it with make you jump to that row.

arr + 1 // gives the second row, i.e. arr is currently pointing to the first element of second row.

Now, further adding an integer to it, will make you skip to that specified column in that particular row.

((arr + 1) // second row  +  2 ) // will you skip to third element of the second row

This is the implicit pointer notation that language gives you, when you choose to treat the array name as a pointer.

Now coming to your problem : - Explicit Pointer Notation:-

What are you trying to achieve is, storing the base address of the 2D array in a pointer.

How to correctly do that ?

int (*ptr)[3]; //reading it goes like this - ptr is a pointer to a 1D array of 3 ints

The 3 here specifies the number of columns your 2D array has.

So what it is doing is, trying to store the base address of first 1D array of that 2D array (which means 0th row base address) into the pointer.

The rest remains the same.

int (*ptr)[3] = arr; // storing the 2D array in ptr

Now, you can use it as a normal pointer(Pointer notation applies on it)

(ptr + 1) //now ptr is pointer to the Second 1D array of that 2D array or you can say to the second row's first element.

Another way you can catch an array in a function is like this:-

I use it very less though.

int main()
{
    int arr[2][2];
    fun(arr);
}

void fun(int catch[][])
{


}


// This is simple to understand and as well as to relate. Now, again catch can be used as pointer or as an array. It depends on you :)

void fun1(int (*ptr)[2])
{
      //my way
printf("%d", ptr[1][1]);
printf("%d", *(*(ptr + 1) + 1));

//answer will be the same
}

//Ptr now contains that 2D array base address, again can be used as an array or a pointer :)

Comments

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.