2

I've been facing difficulties to understand the fourth line of code after the first curly brace,

#include<stdio.h>
 int main()
 {
     int arr[] = {10,20,36,72,45,36};
     int *j,*k;

     j = &arr[4];
     k = (arr+4);
     if(j==k)
        printf("The two pointers are pointing at the same location");
     else
        printf("The two pointers are not pointing at the same location");

  }

I just wanted to know what the fourth line of code after the first curly brace i.e. k = (arr+4); does?

Since k was a pointer it was supposed to point at something that had an "address of operator" ? I can still understand that if it doesn't have the "address of operator" then whatever does the part of the code k = (arr+4) do?

Cong Ma
  • 10,692
  • 3
  • 31
  • 47
kep
  • 21
  • 3
  • Ever heard of [pointer arithmetic](https://stackoverflow.com/questions/394767/pointer-arithmetic) ? Now you have. An array identifier, used in an expression as you've done here, converts to a pointer-to-type, pointing to the first element (slot 0) and then the arithmetic takes over. – WhozCraig Feb 09 '18 at 10:14
  • The 'arr' array is treated as a pointer in most cases. The whole [] is just syntactic sugar. arr[4] is the same as *(arr + 4). Just to confuse you a bit, it's even possible, and legal, to write 4[arr]. The brackets just means p + offset, and the order doesn't matter. – Bjorn A. Feb 09 '18 at 10:15
  • @WhozCraig Yeah thats what the name of the topic that I'm reading is! – kep Feb 09 '18 at 10:16
  • This is a valid question but I took the liberty to change the title to be more descriptive. – Cong Ma Feb 09 '18 at 10:18
  • 1
    Thanks @CongMa I hope the downvotes don't kill my confidence to ask here ! – kep Feb 09 '18 at 10:19
  • @WhozCraig Could you please give me any link to any online data or tutorial that could teach me the same stuff with an even more descriptive manner? – kep Feb 09 '18 at 10:27
  • The blue text in @WhozCraig's comment is a link to online data. – Jongware Feb 09 '18 at 10:32
  • @usr2564301 okay thanks – kep Feb 09 '18 at 10:33

5 Answers5

2

For any array or pointer arr and index i, the expression arr[i] is exactly equal to *(arr + i).

Now considering that arrays naturally can decay to pointers to their first element, arr + i is a pointer to element i.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Could you please explain the origin of this expression since it is nowhere mentioned in the infamous textbook that I'm reading these days. – kep Feb 09 '18 at 10:21
  • @kep This can be found for example in the [K & R book](https://en.wikipedia.org/wiki/The_C_Programming_Language), 2nd ed, Chapter 5 Sections 5.3 and 5.4. To quote: "The correspondence between indexing and pointer arithmetic is very close." :) – Cong Ma Feb 09 '18 at 10:24
  • @kep It's part of the C specification. It's in ISO/IES 9899:2011 §6.5.2.1/2: "A postfix expression followed by an expression in square brackets **`[]`** is a subscripted designation of an element of an array object. The definition of the subscript operator **`[]`** is that **`E1[E2]`** is identical to **`(*((E1)+(E2)))`**. – Some programmer dude Feb 09 '18 at 10:42
1

Without & or the sizeof operator an array converts to a pointer to the first element of the array.In your case array will convert to a pointer to int and will point to the first element.arr + 1 will point to the second element,arr + 2 will point to the third element etc..arr+1 means increment arr with sizeof(int).

This is simplified diagram of the first 2 elements of the array.Let's assume int is 4 bytes long.

|       first element    |      second element   |
 -------------------------------------------------
|     |     |      |     |     |     |      |     |
|     |     |      |     |     |     |      |     |
 -------------------------------------------------
 0x00   0x01  0x02   0x03 0x04   0x05  0x06   0x07

arr will contain 0x00

arr + 1 will contain 0x04

*arr will mean take the value from adress 0x00.It's equivalent to *(arr+0), *(0+arr), arr[0] and 0[arr].Since arr is of type int* it will take a four bytes long value.

With int* k = array k will contain the same address with array.

k = (arr + 4) will contain the address of the 5th element.

j = &arr[4]; will also store the address of the 5th element

Martin Chekurov
  • 733
  • 4
  • 15
0

As k is defined as pointer, it can be use to store address as value and can point to a location. Here (arr+4) will return address of arr and plus 4. If int takes 4 bytes then it will point to 2nd element in arr, so it depends on system(32bit/64 bit), that how much it takes to store int.

Akshay
  • 559
  • 2
  • 11
  • Here, the array element that is `arr[4];` and `(arr+4);` have been shown to be the same, I hope you could run the program for yourself, it says they both point at the fifth element of the array thats `arr[4];` – kep Feb 09 '18 at 10:32
0

Something that you should aware of (C Standards#6.3.2.1p3):

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

The statement:

int arr[] = {10,20,36,72,45,36};

arr is an array of int.

The expression arr[i], can also be written as:

*(arr+i)

So, &a[i] can be written as:

&(*(arr+i)) 

The operator & is used to get the address and the operator * is used for dereferencing. These operators cancel the effect of each other when used one after another. Hence, &(*(arr+i)) is equivalent to arr+i.

I just wanted to know what the fourth line of code after the first curly brace i.e. k = (arr+4); does?

In the statement:

k = (arr+4);

none of the operators - sizeof, _Alignof and unary & is used. So, arr will convert to a pointer to type int. That means, arr+4 will give the address of the four element past the object (i.e. int) pointed to by arr, which is nothing but &a[4].

&arr[4] --> &(*(arr+4)) --> (arr+4)
H.S.
  • 11,654
  • 2
  • 15
  • 32
0

You need to understand pointer arithmetic here.

arr[i] is interpreted as *(arr + i),

where * is 'dereferencing' or 'value at' operator and arr always represents the address of first element of the array i.e. the address of array itself, which literally means,

valueat(starting address of arr + i)

Now suppose address of arr is 100 and you are adding i elements of type arr in address of array and not the value of i, that is,

valueat(100 + i)

Now according to your code, here you are assigning address of 4th element to pointer j ,

j = &arr[4];
j = &(valueat(100+ 4 elements of type int)); j = &(valueat(100+ 16)); -> j = &(valueat(116)); -> j = &(45) that is j = 116

Now when you do

k = (arr+4);

k = (starting address of arr + 4 elements of type int);

k = (100 + 16); that is k = 116, and that is why the output,

The two pointers are pointing at the same location

Hope this helps.

Mithilesh Tipkari
  • 697
  • 1
  • 10
  • 16