tags:

views:

312

answers:

7

Below are 2 programs

First

#include<stdio.h>

void main()
{
    int a[5]={1,2,3,4,5};
    int *p;
    p=&a;
    printf("%u %u",p,p+1);
}

Second

#include<stdio.h>

void main()
{
    int a[5]={1,2,3,4,5};
    printf("%u %u",&a,&a+1);
}

Now, in the two programs..I have printed the values of &a using p in first code and directly in the second..

Why are the results different?

the answer i m getting are.

for first  3219048884  3219048888
for second 3219048884  3219048904
A: 

You should use p = a and not p = &a. An array like a is already assumed a constant pointer. You do not need to dereference it with the & operator.

Frank
`a` is not a pointer. Never ever.
GMan
@GMan Why then can you say `*a = 2` with the same meaning as `a[0] = 2`?
Frank
@Frank: Because arrays have an implicit conversion to pointer. But arrays are not pointers.
GMan
+3  A: 

In both programs, you are printing the memory addresses of the array.

This can vary each time you run the program. The memory that the OS chooses to give you can be different.

When your program declares an array of 5 integers, The OS promises to give you 5 consecutive integers, it does NOT promise what memory you will get, or that you will get the same memory every time.

abelenky
+14  A: 

The type of &a is int (*) [5]. Therefore &a+1 is a pointer that's 5 ints further on than a. However the type of p is int *, therefore p+1 is a pointer that's 1 int further on than p.

Oli Charlesworth
Sneaky! I approve.
Andres Jaan Tack
Yes, but that's irrelevant with the question except for the last value of the serie
kriss
@kriss: How is this irrelevant? It's the last value in each sequence that differ, and this is why.
Oli Charlesworth
@Oli Charlesworth: with your compiler may be, with mine every set of value is different at each run. The C standard does not guarantee the stability of stack addresses. As the OP exhibited two programs the two outputs can potentially be totally different at each run (they are on my system). Your answer is fine if we combine both programs in one.
kriss
@kriss: Oh I see. That's a fair point. However, given the OP's example output, I think it's clear he's referring to the differing last values only.
Oli Charlesworth
+8  A: 

When I run that, I get this:

1245036 1245040 1245036 1245040
1245036 1245040 1245036 1245056

with the only difference being in the last position, p+1 vs &a+1

p is a pointer to an integer, so p+1 is the address of the next integer. (i.e 4 byte further in memeory)

a is an array of 5 integers, so &a+1 is the address of the next array of 5 integers. (i.e., 20 bytes further in memeory)

James Curran
A: 

Only the fourth item differs -- and it's different because of how pointer arithmetic works. When you write &a+1 gcc translates that to &a + sizeof(int); when you write p+1 it translates into p + sizeof(int *). An int is 4 bytes, while an int * is 8 bytes -- so you're adding different amounts to each.

The take-away lesson? Don't do pointer arithmetic unless you understand pointers.

Doches
AndreyT
Actually this isn't true. The size of int* depends on the architecture of your processor. On my 32bit processor, sizeof(int*) == 4.
Wade Tandy
"take-away lesson" icing on the cake here.
+1  A: 

Your first program is invalid. It is illegal to assign p = &a, since p has type int * and &a has type int (*)[5]. These types are not compatible. If your compiler is loose enough to allow this kind of assignment (did it at least warn you?), it probably interpreted it as p = (int *) &a, i.e. it forcefully reinterprets the value of &a as an int * pointer. Thus, all pointer arithmetic in your first program is int * arithmetic. This is why the first program produces the same output for a+1 and p+1 values.

In the second program the value of &a is not reinterpreted. It keeps its original type `int (*)[5] and it follows the rules of normal pointer arithmetic for type int (*)[5], meaning that when you do &a + 1, the pointer is moved sizeof(int[5]) bytes, as it should. This is why the result is different from the first program.

AndreyT
+2  A: 

You have two programs with different stack frames, no surprise the addresses of local variables are different. Il may change each time you run the program (that's what it does when I try it, code compiled with gcc on Linux).

But you'll get the same values with the program below one except for the last value of the serie (except for the last one, because of the way pointer arithmetic works).

#include<stdio.h>

void main()  
{ 
    int a[5]={1,2,3,4,5};  
    int *p; 
    p=&a; 
    printf("%u %u %u %u ",a,a+1,p,p+1);
    printf("%u %u %u %u",a,a+1,&a,&a+1);
}

For a (quite) complete explanation of difference between pointers and arrays you can look at my answer here

kriss