0

I'm new in programming and learning pointers in array in C. Have a look at the below programmes.

1st program

  #include<stdio.h>
  int fun();
  int main()
  {
   int num[3][3]={21,325,524,52,0,6514,61,33,85};
   fun(num);
   printf("%d",*(*(num+1)+1));
   *(*(num+1)+1)=0;
   printf("%d",*(*(num+1)+1));
   return 0;
   }
   int fun(int **p)
   {
    *(*(p+1)+1)=2135;
    return 0;
     }

2nd program

   #include<stdio.h>
  int fun();
  int main()
  {
   int num[3][3]={21,325,524,52,0,6514,61,33,85};
   fun(num);
   printf("%d",*(*(num+1)+1));
   *(*(num+1)+1)=0;
   printf("%d",*(*(num+1)+1));
   return 0;
   }
   int fun(int *p)
   {
    *((p+1)+1)=2135;
    return 0;
   }

3rd program

     #include<stdio.h>
  int fun();
  int main()
  {
   int num[3][3]={21,325,524,52,0,6514,61,33,85};
   fun(num);
   printf("%d",*(*(num+1)+1));
   *(*(num+1)+1)=0;
   printf("%d",*(*(num+1)+1));
   return 0;
   }
   int fun(int (*p)[3])
   {
    *(*(p+1)+1)=2135;
    return 0;
     }
  1. In the first program **p is used in the fun() function which I think it should be correct and in that function I've written *(*(p+1)+1) to change the first element of first array. But on compiling this program it's showing error: invalid type argument of unary '*' (have 'int'). As far as I know num is a pointer to array and it is holding the address of num[1] which is again holding the address of num[1][0].
  2. On compiling the second program compiler is showing no error. And *((p+1)+1)=0 is changing the value of 2nd element of first array. Why it is changing the value of 2nd element of zeroth array not the value of first element of first array? and How? It should be *(*(p+1)+1)=0.
  3. In the third program the compler is showing no error and it is showing the correct result. How?. What does *(p)[3] mean?

I had searched about this but couldn't found the satisfactory result.

glglgl
  • 89,107
  • 13
  • 149
  • 217
  • 1
    Please remove all occurences of "+0" and then all unnecessary braces. They have no use and cause severe headache. – fjf2002 Dec 03 '14 at 21:32
  • The name of an array is a pointer to the first element of the array. Maybe internally it is not really the same but you can use it as pointer. – Gren Dec 03 '14 at 21:40
  • `int *(p)[3]` is the same as `int *p[3]` but different to `int (*p)[3]`. You probably meant the latter – M.M Dec 03 '14 at 21:51
  • @joachim *can be converted to*, not *is* . – M.M Dec 03 '14 at 22:32
  • Is it the same teacher as in [this](http://stackoverflow.com/q/27271379/296974) question? – glglgl Dec 25 '14 at 07:38

2 Answers2

1

All of your programs are ill-formed. Your compiler must produce warning or error messages, and the output of any executable produced is meaningless.

They are ill-formed because int[3][3] is not compatible with int **, nor with int *, nor with int *[3].

To pass int[3][3] to a function, the function must accept int (*)[3] and nothing else (well, except for void *).

This is because arrays can be converted to a pointer to the first element of the array. (In C syntax, num can be used to mean &num[0]).

In C, there are only truly one-dimensional arrays; an array of type int[3][3] is considered to be an array of 3 elements, each of which is an array of 3 ints.

So a pointer to the first element of num is a pointer to an array of 3 ints, which is written as int (*p)[3]. You could write:

int (*p)[3] = &num[0];

or the shorthand for the same thing:

int (*p)[3] = num;

NB. You continually write *(*(num+1)+1)) which is difficult to read. Instead of this, num[1][1] seems much clearer.

In C, x[y] is always exactly equivalent to *(x+y).

M.M
  • 138,810
  • 21
  • 208
  • 365
  • i know i can do that but since i'm learning pointer i want to write all the codes in pointer –  Dec 03 '14 at 22:06
0

I think you are asking: What's the difference between

int fun(int *p)

and

int fun(int (*p)[3])

The first one expects a pointer to an int. The second one expects a pointer to an array of 3 ints.

You are able to call to both these functions using num since you declared the function as

int fun();

If you declare the functions like they are defined, you will get compiler error/warning for the first version.

Here's an updated version of your code and the resulting compiler warning, using gcc and compiler flag -Wall.

#include <stdio.h>

int fun(int *p);

int main()
{
   int num[3][3]={21,325,524,52,0,6514,61,33,85};
   fun(num);
   return 0;
}

int fun(int *p)
{
   *(p+0)=2135;
   return 0;
}
test.c: In function ‘main’:
test.c:7:4: warning: missing braces around initializer [-Wmissing-braces]
test.c:7:4: warning: (near initialization for ‘num[0]’) [-Wmissing-braces]
test.c:8:4: warning: passing argument 1 of ‘fun’ from incompatible pointer type [enabled by default]
test.c:3:5: note: expected ‘int *’ but argument is of type ‘int (*)[3]’
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • thankyou for your answer. :) But what if i write **p in the function ? –  Dec 03 '14 at 21:51
  • @user3788135, you could use `**p` for the second version but not the first version. In the first version, `*p` is of type `int`. `**p` is not a valid type. – R Sahu Dec 03 '14 at 21:55
  • Sorry sir i did'nt get what you want to explain me.What i want to say is that if num is a pointer to array than can we not write **p ? –  Dec 03 '14 at 22:09
  • @user3788135, in `fun`, there is no knowledge of how `num` was defined in the calling function. It can only use the argument `p`. If `p` is defined as `int *p`, then `**p` is not a valid type. – R Sahu Dec 03 '14 at 22:15
  • Thankyou for your reply sir.Sir can u explain me what is the difference between pointer to pointer and pointer to array.As it will really help me to understand this. –  Dec 03 '14 at 22:20
  • See: http://stackoverflow.com/questions/19746173/c-c-pointer-to-an-array-vs-pointer-to-a-pointer. – R Sahu Dec 03 '14 at 22:44