0

I have this program. And I have some doubts. You can run it in your compiler. I am using gcc compiler in linux

#include<stdio.h>
int main()
{
    int j=4,*add;
    int i=2;
    int a[i][j];
    for (i=0;i<=1;i++)
    {
        for(j=0;j<=3;j++)
        {
            scanf("%d",&a[i][j],"%d",&a[i][j]);
        }
    }
    for(i=0;i<=1;i++)
    {
        for (j=0;j<=3;j++)
        {
            add=&(a[i][j]);
            printf("\nSize of %d is %d and address is: %u that should be equal to: %d",a[i][j],sizeof(a[i][j]),&(a[i][j]),add);//Address are not equal while add is having the value of &(a[i][j])
            printf("\nSize of %d is %d and value is: %d that should be equal to: %d",a[i][j],sizeof(a[i][j]),*(&(a[i][j])),*add);//Here value at both addresses are same
        }
     }

    printf("\n initial address of the array is: %u that should be equal to address given by &a[0][0]",&a); //And it's equal

return 0;
}

In this code add occupies the address value of each array elements and prints that address one by one through loop. But address value given by add is not equal to the one given by &(a[i][j]) while the values give by these two are equal. That is, *add is equal to *(&(a[i][j])) for each array element. Can some one explain me why this is so?

I printed the size of each element so as to confirm the sequence of data arrangement in memory. As my compiler 32-bit based, it printed the addresses by the gap of 4 bits in case of both add and &(a[i][j]).

In the last I print the initial address of array. This gives the address same as &a[0][0]. So the question is which method is correct, add=&(a[i][j]; or direct out putting the a[i][j]?

johnsyweb
  • 136,902
  • 23
  • 188
  • 247
Ashish Tomer
  • 55
  • 1
  • 8
  • 7
    Neither of `%d` or `%u` is for pointers. Use `%p` (and cast to `void *`) for that purpose. –  Oct 10 '13 at 15:40
  • Also one is `%d`, the other is `%u`. – dornhege Oct 10 '13 at 15:44
  • 3
    The same address, but different representations. – masoud Oct 10 '13 at 15:47
  • I like the address of operator followed by a dereference – clcto Oct 10 '13 at 15:49
  • Also, what is up with `scanf("%d",&a[i][j],"%d",&a[i][j]);`? – Raymond Chen Oct 10 '13 at 15:50
  • This is not a C++ program. In C++ you would use std::cout and would not have issue with data and specifier mismatch that you have in printf – Slava Oct 10 '13 at 15:51
  • Thank you so much all. I used %u for both and addresses came equal. @H2CO3 %u is used for pointers. I am reading a book- Let Us C. Very good book. And use of %u is described in that book. – Ashish Tomer Oct 11 '13 at 14:22
  • @MM. How these addresses are same? Please tell me. I really would like to know about representation of addresses. :) – Ashish Tomer Oct 11 '13 at 14:23
  • @RaymondChen That is right. %d is used to input in **integer value stored at the address given by &a[i][j]** – Ashish Tomer Oct 11 '13 at 14:24
  • @Slava Obviously it's not c++. It's C. – Ashish Tomer Oct 11 '13 at 14:24
  • @AshishTomer that's actually a pretty bad book. Using `%u` for printing pointers invokes **undefined behavior.** Don't do that. It'a wrong. Just wrong. Write `%p` instead. –  Oct 11 '13 at 14:46
  • @H2CO3 using %u and %p do different things. both gives the addresses of pointer. but one give address in integer form other gives in 0axtu23i90 something like this. so using %u we can add/subtract addresses. – Ashish Tomer Oct 11 '13 at 16:01
  • @ashishtomer Don't teach me C. The fact that `%p` usually prints in hexadeximal and `%u` in hexadecimal is completely irtelevant. Not sure what you mean by "so with %u we can add and subtract addresses", I don't see why that would be impossible in hexadecimal. I can only repeat myself: `%u` is not suitable for printing a pointer, regardless of with how high level of stubbornness you insist, it results in undefined behavior, and as such it is wrong. Read the relevant part of the C standard and the documentation of `printf()` if, for some reason, you still don't believe me. –  Oct 11 '13 at 16:34
  • @AshishTomer Also, ask someone around here and you will get the same answer. Don't think that, just because you as a beginner **assume** that something works, it does -- because it doesn't. While you're a beginner, you'd be better off listening to the people who actually know what they are talking about - there are things going on that you don't even know of. So be litle more humble and accept the facts that thosw tell you who actually know and have worked with the C language. –  Oct 11 '13 at 16:38
  • @H2CO3 I am really sorry. I will accept the facts but I was just saying the book I am reading right now is using %u for pointers. I know if I want to learn then I'll have to accept that I don't know anything. And yes I will start reading the documentation from now on. Thanks for suggestion. :) – Ashish Tomer Oct 11 '13 at 17:04
  • @AshishTomer I was asking specifically why you passed `"%d", &a[i][j]` twice. What is the second `"%d", &a[i][j]` trying to do? – Raymond Chen Oct 11 '13 at 17:16
  • Your book assumes that `sizeof(int) == sizeof(void*)` and that your CPU does not have separate address and data registers. If you have an LLP64 or LP32 system, your program will print garbage for the second pointer due to the size mismatch. Try it on a 68000 and you will get garbage for *both* pointers. You probably should consider getting a different book. – Raymond Chen Oct 11 '13 at 17:29
  • @RaymondChen Ehhh! Okay. All I can say is my level is quite low to understand what all you said, but gradually I'll learn more, that's how people learn. And I also have Complete Reference C++ by Herbert Schildt. I'll read that book after I complete this one. – Ashish Tomer Oct 12 '13 at 14:08
  • Schildt is not the best author. His Annotated C Standard is truly awful, filled with errors and lies. That he assumes `sizeof(int)==sizeof(void*)` doesn't surprise me. He basically assumes your target processor is VAX-like. – Raymond Chen Oct 12 '13 at 14:20
  • Which one would you recommend for me. If there is any book better to best tell me. – Ashish Tomer Oct 13 '13 at 03:41
  • K&R is the classic choice. – Raymond Chen Oct 13 '13 at 08:00

1 Answers1

0

they are the same address. It might be the sign that makes you think they are different. Use %p to print the pointer or use %u for both.

tristan
  • 4,235
  • 2
  • 21
  • 45
  • Thank you so much Tristan. :) You are right. I used %u for **add** also. And address comes equal for both. But now the question is why %d gives -ve address. I know it's used for integer variables not for integer pointers. Well thank you again. :) – Ashish Tomer Oct 11 '13 at 14:12
  • Thank you so much I used %u for both and addresses came equal. – Ashish Tomer Oct 11 '13 at 14:28
  • using %u and %p do different things. both gives the addresses of pointer. but one give address in integer form other gives in 0axtu23i90 something like this. so using %u we can add/subtract addresses. – Ashish Tomer Oct 11 '13 at 16:00