5

I'm trying something very simple, well supposed to be simple but it somehow is messing with me...

I am trying to understand the effect of ++ on arrays when treated as pointers and pointers when treated as arrays.

So,

int main()
{
    int a[4] = { 1, 4, 7, 9 };
    *a = 3;
    *(a+1) = 4;
    *++a = 4; //compiler error
}

1: So at *(a+1)=4 we set a[1]=4; //Happy But when *++a = 4;, I'd expect pointer a to be incremented one since ++ is precedent to * and then * kicks in and we make it equal to 4. But this code just does not work... Why is that?

Another problem:

int main()
{

    int* p = (int *)malloc(8);
    *p = 5;
    printf("%d", p[0]);

    *++p = 9; //now this works!
    printf("%d", p[1]); //garbage
    printf("%d", p[0]); //prints 9

}

2: Now *++p = 9; works fine but it's not really behaving like an array. How are two different? This is just incrementing p, and making it equal to 9. If I print p[0], it now prints 9 and I see that though can't access it via p[0] anymore, *(p-1) shows 5 is still there. So indexing a pointer with [0], where exactly does it point to? What has changed?

Thanks a lot all experts!

shadowyman
  • 215
  • 3
  • 11
  • 1
    An array is not a pointer. You can't increment it. Also, don't cast the return value of malloc. But these have been discussed hundreds of times already. Why don't you do any research before asking? –  Oct 13 '13 at 06:28
  • @H2CO3 you don't have to cast malloc's return in C but you do in C++. – Adam Oct 13 '13 at 06:30
  • 1
    @Adam You don't, because you don't use `malloc()` in `C++` at all. –  Oct 13 '13 at 06:31
  • Possible duplicate of [What happens if I increment an array variable?](http://stackoverflow.com/questions/7334627/what-happens-if-i-increment-an-array-variable) – phuclv Mar 11 '17 at 01:29

2 Answers2

9

The array names is not modifiable lvalue so operation ++ is not applied hence ++a that try to modify a is compilation time error (where a is array name).

Note *(a + 1) and *a++ are not same, a + 1 is a valid instruction as it just add 1 but doesn't modify a itself, Whereas ++a (that is equvilent to a = a + 1) try to modify a hence error.

Note 'array names' are not pointer. Pointers are variable but array names are not. Of-course when you assign array name to a pointer then in most expressions array names decays into address of first element. e.g.

int *p = a;

Note p points to first element of array (a[0]).

Read some exceptions where array name not decaying into a pointer to first element?

An expression a[i] is equivalent to *(a + i), where a can be either a pointer or an array name. Hence in your second example p[i] is valid expression.

Additionally, *++p is valid because because p is a pointer (a variable) in second code example.

Community
  • 1
  • 1
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • This is also the error message compiler is giving. But I'm asking isn't the array name also a pointer, pointing to the first element of an array? – shadowyman Oct 13 '13 at 06:30
  • Thanks, can you also please answer the 2nd question? When we dereference a pointer b, to an array a by [0], it prints b[0] as a[1]. So isn't pointer really behaving like an array? – shadowyman Oct 13 '13 at 06:43
  • @shadowyman It's more like the array is behaving like a pointer. [] is a pointer operation, it's defined on pointers not on arrays. – john Oct 13 '13 at 06:58
  • Simplified version: Arrays are basically constant, so in using the de/increment operators you're really trying to modify something that cannot be modified. To achieve the desired effect, make a pointer point to the array and increment that. – Super Cat Aug 28 '15 at 01:19
1
int a[4] = { 1, 4, 7, 9 };
int *pa=a;

There is one difference between an array name and a pointer that must be kept in mind. A pointer is a variable, sopa=a and pa++ are legal. But an array name is not a variable; constructions like a=pa and a++ are illegal


int* p = (int *)malloc(8);

Don't cast result of malloc()

Use index with pointer

p[1]=9; // p[1]==*(p+1)
Community
  • 1
  • 1
Gangadhar
  • 10,248
  • 3
  • 31
  • 50
  • 1
    If we're at it: 1. in standardese parlance, there are no "variables", just objects. So then a pointer isn't a variable either. 2. But if we use the common terminology, then an array is just like any pther normal variable. It's just not assignable. –  Oct 13 '13 at 06:33
  • H2CO3, so the problem here is trying to modify the array name and behaving like a pointer doesn't make it fully a pointer, correct? – shadowyman Oct 13 '13 at 06:38
  • @H2CO3 You misunderstood Here I was mentioned `array name is not a variable` and pointer is a variable means we can modify it. – Gangadhar Oct 13 '13 at 06:39
  • @Gangadhar No, that's not the case. I understood your answer perfectly, and it's incorrect (at best). –  Oct 13 '13 at 06:43
  • @H2CO3 You may be correct in many cases . sorry in this case i can`t agree with you because this same has quoted in dennis ritchie book. – Gangadhar Oct 13 '13 at 06:59
  • 1
    @H2CO3: your first remark is incorrect. In standardese parlance, "a _variable_ is introduced by the declaration of an object. The variable's name denotes the object." `[basic]`. That is to say, a variable is any named object introduced by a declaration. You're still right that it's incorrect to say generally that "a pointer is a variable", since for example `static_cast(NULL)` is an expression whose value is a pointer that is not a variable (because it isn't named and wasn't introduced by a declaration, and for that matter isn't an object since it doesn't have an address). – Steve Jessop Oct 13 '13 at 09:30
  • 1
    However, an array name *is* (the name of) a variable, even though it cannot vary. – Steve Jessop Oct 13 '13 at 09:33
  • 1
    @SteveJessop Right, I retract... I think I have confused the C and the C++ standards. I'll check it. –  Oct 13 '13 at 12:20
  • 1
    @H2CO3: ah, if it is different in C then maybe I'm the one who's looking at the wrong one. As I re-read it, nothing in the question requires C++. – Steve Jessop Oct 13 '13 at 12:29