0

I'm new in C programming and currently learning about array and strings. I'm quite confuse in this topic. Coming to my question-

  1. Since an array (for ex- a[]={20,44,4,8}), the name in an expression decays into pointer constant,so whenever if i try to do pointer arithmetic for example- a=a+1 or anything like this the compiler shows error but when the same thing I write in printf() function it is showing the address of the first element rather than showing error. Why?
  2. In an expression for example *(a+1)=2 first (a+1) will be evaluated and then * will dereference it. My question is that if a is a pointer constant then how it can point to any other memory location in an array and how this expression is perfectly legal?

I tried to search about this but couldn't get the accurate result.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 4
    Well, `a` is an array and is not a pointer. You cannot assign to a variable whose type is an array. What would that mean? – David Heffernan Dec 15 '14 at 13:32
  • Possible dup of http://stackoverflow.com/questions/19130236/array-increment-operator-in-c – Peter M Dec 15 '14 at 13:35
  • This question has two parts. While the first part is adequately covered by the dupe, the second one is not. I am voting to reopen this question so that OP could get an answer to the second part of his question. – Sergey Kalinichenko Dec 15 '14 at 13:39

3 Answers3

2

Although an array name evaluates to a pointer in some expressions, your a = a+1 assignment tries to assign to an array, which is not allowed.

On the other hand, a+1 expression is allowed, and it evaluates to another pointer. When you pass this value to printf, the function happily prints it. Do not forget to cast the result to void* when you print:

printf("%p\n", (void*)(a+1));

if a is a pointer constant then how it can point to any other memory location in an array and how is *(a+1) expression perfectly legal?

For the same reason that 2+3, a combination of two constants, produces a value that is neither a 2 nor a 3. In your example, a+1 expression does not modify a. Instead, the expression uses it as a "starting point", computes a different value (which happens to be of type pointer), and leaves a unchanged.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • so what does a+1 mean actually? –  Dec 15 '14 at 13:57
  • @user3788135 According to C pointer arithmetic rules `a+1` means exactly the same thing as `&a[1]`. – Sergey Kalinichenko Dec 15 '14 at 14:06
  • As far as i understand from you answer and comment is that pointer arthematic in pointer and array are little different.Right? Will you please give me some advice so that i can be a good programmer.if you like to. :) –  Dec 15 '14 at 14:15
  • 1
    @user3788135: pointer arithemtic is the same for pointers and array expressions. For any pointer `p` to type `T`, the expression `p + 1` will give the address of the next object of type `T`. For example, if `T` is `char` and `p` is `0x8000`, then `p + 1` will evaluate to `0x8001` because the next `char` object starts at the next byte. If `T` is a 32-bit `int`, then `p + 1` will evaluate to `0x8004` because the next `int` object starts 4 bytes from the current byte. – John Bode Dec 15 '14 at 16:04
0

The name of the array a is not quite the same as a pointer constant. It merely acts like a pointer constant in some circumstances. In other circumstances it will act quite differently; for example, sizeof(a) may have a much larger value than sizeof(b) where b is truly a pointer.

This code is legal:

int a[] = {20,44,4,8};
int *b;
b = a;
b = b + 1;

because a is enough like a pointer that you can set b to point to the same address but, unlike a, b really is a pointer and it can be modified.

The last line of code could just as well be:

b = a + 1;

because the right-hand side here is not trying to modify a; it is merely using the address of the first element of a to compute a new address.

The expression *(a + 1) is effectively another way of writing a[1]. You know what will happen when you write a[1] = 2, right? It will change what is stored in the second element of a. (The first element is always a[0] whether you do anything with it or not.) Storing a new value in a[1] doesn't change the location of the array a.

David K
  • 3,147
  • 2
  • 13
  • 19
0

When array decays in to pointer, the resulting value is a rvalue. It's an value that cannot be assigned to.

So int[4] will become int*const, constant pointer to integer.

Q1:

Types in expression a = a + 1 are:

int[4] = int[4] + int

If we focus on addition first, array decays to pointer:

int[4] = int*const + int
int[4] = int*const        // After addition

But now there is a problem:

int*const = int*const

In memory a is an array with 4 ints, and nothing more. There is no place where you could possibly store address with type int*. Compiler will show an error.

Q2:

Types in expression *(a+1)=2 are:

*(int[4] + int) = int

Again, array decays to pointer and addition happens:

*(int*const + int) = int
*(int*const) = int        // int* is now equal to &a[1]

Dereferencing int*const is legal. While pointer is constant, value it points to is not:

int = int  // Ok, equal types

Types are now perfectly compatible.

user694733
  • 15,208
  • 2
  • 42
  • 68