(arr + 2) is equivalent to *(arr + 2) . How?
Clash Royale CLAN TAG#URR8PPP
up vote
8
down vote
favorite
I am studying how to display elements of 2D array with the help of pointers. Here is the code I tried:
#include<stdio.h>
int main()
int arr[3][2] =
7, 8,
6,3,
3,4
;
printf("%un", (arr + 2));
printf("%un", *(arr + 2));
Output:
6487616
6487616
I am expecting output of *(arr + 2)
to be 3
. How is it the same as (arr + 2)
?
c arrays pointers
 |Â
show 5 more comments
up vote
8
down vote
favorite
I am studying how to display elements of 2D array with the help of pointers. Here is the code I tried:
#include<stdio.h>
int main()
int arr[3][2] =
7, 8,
6,3,
3,4
;
printf("%un", (arr + 2));
printf("%un", *(arr + 2));
Output:
6487616
6487616
I am expecting output of *(arr + 2)
to be 3
. How is it the same as (arr + 2)
?
c arrays pointers
3
You need to dereference it twice, since it's a 2D array:*(*(arr+2))
– Govind Parmar
Aug 28 at 16:42
4
arr[2]
and*(arr + 2)
are the same by definition in the language (C11 §6.5.2.1 Array subscripting ¶2). And you get odd results because you're printing an address, not the value of a cell in the array. That's officially undefined behaviour; you pass an address toprintf()
but tell it that it's got an unsigned integer to work on. You might be OK on a 32-bit platform, sort of, more or less. Results are not remotely reliable on a 64-bit platform.
– Jonathan Leffler
Aug 28 at 16:45
1
technically you're getting UB since%u
is not for printing pointers. You have to use%zu
– phuclv
Aug 28 at 16:50
7
@phuclv: You're right that%u
is UB, but so is using%zu
(that's for printingsize_t
). You should either use%p
and cast the pointer to avoid *
, or use<inttypes.h>
andPRIuPTR
(orPRIXPTR
for upper-case hex) plus a cast touintptr_t
.
– Jonathan Leffler
Aug 28 at 16:52
1
@phuclv : False.%zu
requires asize_t
argument. Any incompatible type will trigger undefined behavior. Pointer arguments will trigger undefined behavior.
– AnT
Aug 28 at 17:04
 |Â
show 5 more comments
up vote
8
down vote
favorite
up vote
8
down vote
favorite
I am studying how to display elements of 2D array with the help of pointers. Here is the code I tried:
#include<stdio.h>
int main()
int arr[3][2] =
7, 8,
6,3,
3,4
;
printf("%un", (arr + 2));
printf("%un", *(arr + 2));
Output:
6487616
6487616
I am expecting output of *(arr + 2)
to be 3
. How is it the same as (arr + 2)
?
c arrays pointers
I am studying how to display elements of 2D array with the help of pointers. Here is the code I tried:
#include<stdio.h>
int main()
int arr[3][2] =
7, 8,
6,3,
3,4
;
printf("%un", (arr + 2));
printf("%un", *(arr + 2));
Output:
6487616
6487616
I am expecting output of *(arr + 2)
to be 3
. How is it the same as (arr + 2)
?
c arrays pointers
edited Aug 28 at 16:42
John Kugelman
231k51389441
231k51389441
asked Aug 28 at 16:40
dave
785
785
3
You need to dereference it twice, since it's a 2D array:*(*(arr+2))
– Govind Parmar
Aug 28 at 16:42
4
arr[2]
and*(arr + 2)
are the same by definition in the language (C11 §6.5.2.1 Array subscripting ¶2). And you get odd results because you're printing an address, not the value of a cell in the array. That's officially undefined behaviour; you pass an address toprintf()
but tell it that it's got an unsigned integer to work on. You might be OK on a 32-bit platform, sort of, more or less. Results are not remotely reliable on a 64-bit platform.
– Jonathan Leffler
Aug 28 at 16:45
1
technically you're getting UB since%u
is not for printing pointers. You have to use%zu
– phuclv
Aug 28 at 16:50
7
@phuclv: You're right that%u
is UB, but so is using%zu
(that's for printingsize_t
). You should either use%p
and cast the pointer to avoid *
, or use<inttypes.h>
andPRIuPTR
(orPRIXPTR
for upper-case hex) plus a cast touintptr_t
.
– Jonathan Leffler
Aug 28 at 16:52
1
@phuclv : False.%zu
requires asize_t
argument. Any incompatible type will trigger undefined behavior. Pointer arguments will trigger undefined behavior.
– AnT
Aug 28 at 17:04
 |Â
show 5 more comments
3
You need to dereference it twice, since it's a 2D array:*(*(arr+2))
– Govind Parmar
Aug 28 at 16:42
4
arr[2]
and*(arr + 2)
are the same by definition in the language (C11 §6.5.2.1 Array subscripting ¶2). And you get odd results because you're printing an address, not the value of a cell in the array. That's officially undefined behaviour; you pass an address toprintf()
but tell it that it's got an unsigned integer to work on. You might be OK on a 32-bit platform, sort of, more or less. Results are not remotely reliable on a 64-bit platform.
– Jonathan Leffler
Aug 28 at 16:45
1
technically you're getting UB since%u
is not for printing pointers. You have to use%zu
– phuclv
Aug 28 at 16:50
7
@phuclv: You're right that%u
is UB, but so is using%zu
(that's for printingsize_t
). You should either use%p
and cast the pointer to avoid *
, or use<inttypes.h>
andPRIuPTR
(orPRIXPTR
for upper-case hex) plus a cast touintptr_t
.
– Jonathan Leffler
Aug 28 at 16:52
1
@phuclv : False.%zu
requires asize_t
argument. Any incompatible type will trigger undefined behavior. Pointer arguments will trigger undefined behavior.
– AnT
Aug 28 at 17:04
3
3
You need to dereference it twice, since it's a 2D array:
*(*(arr+2))
– Govind Parmar
Aug 28 at 16:42
You need to dereference it twice, since it's a 2D array:
*(*(arr+2))
– Govind Parmar
Aug 28 at 16:42
4
4
arr[2]
and *(arr + 2)
are the same by definition in the language (C11 §6.5.2.1 Array subscripting ¶2). And you get odd results because you're printing an address, not the value of a cell in the array. That's officially undefined behaviour; you pass an address to printf()
but tell it that it's got an unsigned integer to work on. You might be OK on a 32-bit platform, sort of, more or less. Results are not remotely reliable on a 64-bit platform.– Jonathan Leffler
Aug 28 at 16:45
arr[2]
and *(arr + 2)
are the same by definition in the language (C11 §6.5.2.1 Array subscripting ¶2). And you get odd results because you're printing an address, not the value of a cell in the array. That's officially undefined behaviour; you pass an address to printf()
but tell it that it's got an unsigned integer to work on. You might be OK on a 32-bit platform, sort of, more or less. Results are not remotely reliable on a 64-bit platform.– Jonathan Leffler
Aug 28 at 16:45
1
1
technically you're getting UB since
%u
is not for printing pointers. You have to use %zu
– phuclv
Aug 28 at 16:50
technically you're getting UB since
%u
is not for printing pointers. You have to use %zu
– phuclv
Aug 28 at 16:50
7
7
@phuclv: You're right that
%u
is UB, but so is using %zu
(that's for printing size_t
). You should either use %p
and cast the pointer to a void *
, or use <inttypes.h>
and PRIuPTR
(or PRIXPTR
for upper-case hex) plus a cast to uintptr_t
.– Jonathan Leffler
Aug 28 at 16:52
@phuclv: You're right that
%u
is UB, but so is using %zu
(that's for printing size_t
). You should either use %p
and cast the pointer to a void *
, or use <inttypes.h>
and PRIuPTR
(or PRIXPTR
for upper-case hex) plus a cast to uintptr_t
.– Jonathan Leffler
Aug 28 at 16:52
1
1
@phuclv : False.
%zu
requires a size_t
argument. Any incompatible type will trigger undefined behavior. Pointer arguments will trigger undefined behavior.– AnT
Aug 28 at 17:04
@phuclv : False.
%zu
requires a size_t
argument. Any incompatible type will trigger undefined behavior. Pointer arguments will trigger undefined behavior.– AnT
Aug 28 at 17:04
 |Â
show 5 more comments
3 Answers
3
active
oldest
votes
up vote
14
down vote
accepted
A 2D array is really an array of arrays.
The expression arr + 2
has type int (*)[2]
, while *(arr + 2)
has type int [2]
. When printing the former, you have a pointer so that value of the pointer is printed. In the latter case, you have an array which decays to a pointer to the first element. So *(arr + 2)
decays into arr + 2
, which is the same as the first expression.
Going into more detail on arr + 2
, arr
has type int [3][2]
. When you add an integer value to it, it decays to a pointer to the first member, so arr
decays to type int (*)[2]
, and arr + 2
also has that type, and points to the subarray containing 3, 4
.
Also note that pointers should be printed with the %p
format specifier, and that the pointer must be casted to void *
, otherwise you invoke undefined behavior. In this case you were "lucky" that they happened to print the same thing.
To get the output of 3 you were expecting, you need to dereference one more time:
*(*(arr + 2))
*(*(arr + 2));
throws[Error] expected ')' before ';' token
but*(*(arr + 1) + 1));
prints3
– dave
Aug 29 at 5:18
1
@dave*(*(arr + 2))
works properly for me. You're probably missing a closing brace for yourprintf
call. Also,*(*(arr + 1) + 1))
is choosing a different array element which happens to have the same value as the one you're attempting to print.arr[2][0]
andarr[1][1]
both contain the value 3.
– dbush
Aug 29 at 11:21
add a comment |Â
up vote
3
down vote
arr
is an array of arrays of int
. On almost any use an array is converted to a pointer to its first element. So arr
gets converted to a pointer to an array of int
.
OK, arr
gets converted to a pointer to an array of int
, so (arr+2)
is of the same type, that is, a pointer to an array of int
.
Now *(arr+2)
is the thing (arr+2)
points to. That is, an array of int
.
Now since it's an array of int
, it gets converted to a pointer to its first element. So *(arr+2)
gets converted to a pointer to int
. Note it is not an int
and is unlikely to be equal to 3
.
Now how come (arr+2)
and *(arr+2)
dosplay the same? They are a pointer to an array and a pointer to its first element. Although these pointets are of different types, they represent the same address, because the address of any array is the same as the address of its first element.
add a comment |Â
up vote
1
down vote
arr
is the pointer to the first array of the type int[2]
.(arr + 2)
is the pointer to the third such array.
Whereas *(arr + 2)
is the pointer to the first element of the (arr +2)
array.
Both of these will hence have the same address since they are pointing to the same position.The only difference being in their type.(arr+2)
is of the type int(*)[2]
whereas *(arr + 2)
is of the type int *
.
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
14
down vote
accepted
A 2D array is really an array of arrays.
The expression arr + 2
has type int (*)[2]
, while *(arr + 2)
has type int [2]
. When printing the former, you have a pointer so that value of the pointer is printed. In the latter case, you have an array which decays to a pointer to the first element. So *(arr + 2)
decays into arr + 2
, which is the same as the first expression.
Going into more detail on arr + 2
, arr
has type int [3][2]
. When you add an integer value to it, it decays to a pointer to the first member, so arr
decays to type int (*)[2]
, and arr + 2
also has that type, and points to the subarray containing 3, 4
.
Also note that pointers should be printed with the %p
format specifier, and that the pointer must be casted to void *
, otherwise you invoke undefined behavior. In this case you were "lucky" that they happened to print the same thing.
To get the output of 3 you were expecting, you need to dereference one more time:
*(*(arr + 2))
*(*(arr + 2));
throws[Error] expected ')' before ';' token
but*(*(arr + 1) + 1));
prints3
– dave
Aug 29 at 5:18
1
@dave*(*(arr + 2))
works properly for me. You're probably missing a closing brace for yourprintf
call. Also,*(*(arr + 1) + 1))
is choosing a different array element which happens to have the same value as the one you're attempting to print.arr[2][0]
andarr[1][1]
both contain the value 3.
– dbush
Aug 29 at 11:21
add a comment |Â
up vote
14
down vote
accepted
A 2D array is really an array of arrays.
The expression arr + 2
has type int (*)[2]
, while *(arr + 2)
has type int [2]
. When printing the former, you have a pointer so that value of the pointer is printed. In the latter case, you have an array which decays to a pointer to the first element. So *(arr + 2)
decays into arr + 2
, which is the same as the first expression.
Going into more detail on arr + 2
, arr
has type int [3][2]
. When you add an integer value to it, it decays to a pointer to the first member, so arr
decays to type int (*)[2]
, and arr + 2
also has that type, and points to the subarray containing 3, 4
.
Also note that pointers should be printed with the %p
format specifier, and that the pointer must be casted to void *
, otherwise you invoke undefined behavior. In this case you were "lucky" that they happened to print the same thing.
To get the output of 3 you were expecting, you need to dereference one more time:
*(*(arr + 2))
*(*(arr + 2));
throws[Error] expected ')' before ';' token
but*(*(arr + 1) + 1));
prints3
– dave
Aug 29 at 5:18
1
@dave*(*(arr + 2))
works properly for me. You're probably missing a closing brace for yourprintf
call. Also,*(*(arr + 1) + 1))
is choosing a different array element which happens to have the same value as the one you're attempting to print.arr[2][0]
andarr[1][1]
both contain the value 3.
– dbush
Aug 29 at 11:21
add a comment |Â
up vote
14
down vote
accepted
up vote
14
down vote
accepted
A 2D array is really an array of arrays.
The expression arr + 2
has type int (*)[2]
, while *(arr + 2)
has type int [2]
. When printing the former, you have a pointer so that value of the pointer is printed. In the latter case, you have an array which decays to a pointer to the first element. So *(arr + 2)
decays into arr + 2
, which is the same as the first expression.
Going into more detail on arr + 2
, arr
has type int [3][2]
. When you add an integer value to it, it decays to a pointer to the first member, so arr
decays to type int (*)[2]
, and arr + 2
also has that type, and points to the subarray containing 3, 4
.
Also note that pointers should be printed with the %p
format specifier, and that the pointer must be casted to void *
, otherwise you invoke undefined behavior. In this case you were "lucky" that they happened to print the same thing.
To get the output of 3 you were expecting, you need to dereference one more time:
*(*(arr + 2))
A 2D array is really an array of arrays.
The expression arr + 2
has type int (*)[2]
, while *(arr + 2)
has type int [2]
. When printing the former, you have a pointer so that value of the pointer is printed. In the latter case, you have an array which decays to a pointer to the first element. So *(arr + 2)
decays into arr + 2
, which is the same as the first expression.
Going into more detail on arr + 2
, arr
has type int [3][2]
. When you add an integer value to it, it decays to a pointer to the first member, so arr
decays to type int (*)[2]
, and arr + 2
also has that type, and points to the subarray containing 3, 4
.
Also note that pointers should be printed with the %p
format specifier, and that the pointer must be casted to void *
, otherwise you invoke undefined behavior. In this case you were "lucky" that they happened to print the same thing.
To get the output of 3 you were expecting, you need to dereference one more time:
*(*(arr + 2))
edited Aug 28 at 17:06
answered Aug 28 at 16:48
dbush
82.1k1088119
82.1k1088119
*(*(arr + 2));
throws[Error] expected ')' before ';' token
but*(*(arr + 1) + 1));
prints3
– dave
Aug 29 at 5:18
1
@dave*(*(arr + 2))
works properly for me. You're probably missing a closing brace for yourprintf
call. Also,*(*(arr + 1) + 1))
is choosing a different array element which happens to have the same value as the one you're attempting to print.arr[2][0]
andarr[1][1]
both contain the value 3.
– dbush
Aug 29 at 11:21
add a comment |Â
*(*(arr + 2));
throws[Error] expected ')' before ';' token
but*(*(arr + 1) + 1));
prints3
– dave
Aug 29 at 5:18
1
@dave*(*(arr + 2))
works properly for me. You're probably missing a closing brace for yourprintf
call. Also,*(*(arr + 1) + 1))
is choosing a different array element which happens to have the same value as the one you're attempting to print.arr[2][0]
andarr[1][1]
both contain the value 3.
– dbush
Aug 29 at 11:21
*(*(arr + 2));
throws [Error] expected ')' before ';' token
but *(*(arr + 1) + 1));
prints 3
– dave
Aug 29 at 5:18
*(*(arr + 2));
throws [Error] expected ')' before ';' token
but *(*(arr + 1) + 1));
prints 3
– dave
Aug 29 at 5:18
1
1
@dave
*(*(arr + 2))
works properly for me. You're probably missing a closing brace for your printf
call. Also, *(*(arr + 1) + 1))
is choosing a different array element which happens to have the same value as the one you're attempting to print. arr[2][0]
and arr[1][1]
both contain the value 3.– dbush
Aug 29 at 11:21
@dave
*(*(arr + 2))
works properly for me. You're probably missing a closing brace for your printf
call. Also, *(*(arr + 1) + 1))
is choosing a different array element which happens to have the same value as the one you're attempting to print. arr[2][0]
and arr[1][1]
both contain the value 3.– dbush
Aug 29 at 11:21
add a comment |Â
up vote
3
down vote
arr
is an array of arrays of int
. On almost any use an array is converted to a pointer to its first element. So arr
gets converted to a pointer to an array of int
.
OK, arr
gets converted to a pointer to an array of int
, so (arr+2)
is of the same type, that is, a pointer to an array of int
.
Now *(arr+2)
is the thing (arr+2)
points to. That is, an array of int
.
Now since it's an array of int
, it gets converted to a pointer to its first element. So *(arr+2)
gets converted to a pointer to int
. Note it is not an int
and is unlikely to be equal to 3
.
Now how come (arr+2)
and *(arr+2)
dosplay the same? They are a pointer to an array and a pointer to its first element. Although these pointets are of different types, they represent the same address, because the address of any array is the same as the address of its first element.
add a comment |Â
up vote
3
down vote
arr
is an array of arrays of int
. On almost any use an array is converted to a pointer to its first element. So arr
gets converted to a pointer to an array of int
.
OK, arr
gets converted to a pointer to an array of int
, so (arr+2)
is of the same type, that is, a pointer to an array of int
.
Now *(arr+2)
is the thing (arr+2)
points to. That is, an array of int
.
Now since it's an array of int
, it gets converted to a pointer to its first element. So *(arr+2)
gets converted to a pointer to int
. Note it is not an int
and is unlikely to be equal to 3
.
Now how come (arr+2)
and *(arr+2)
dosplay the same? They are a pointer to an array and a pointer to its first element. Although these pointets are of different types, they represent the same address, because the address of any array is the same as the address of its first element.
add a comment |Â
up vote
3
down vote
up vote
3
down vote
arr
is an array of arrays of int
. On almost any use an array is converted to a pointer to its first element. So arr
gets converted to a pointer to an array of int
.
OK, arr
gets converted to a pointer to an array of int
, so (arr+2)
is of the same type, that is, a pointer to an array of int
.
Now *(arr+2)
is the thing (arr+2)
points to. That is, an array of int
.
Now since it's an array of int
, it gets converted to a pointer to its first element. So *(arr+2)
gets converted to a pointer to int
. Note it is not an int
and is unlikely to be equal to 3
.
Now how come (arr+2)
and *(arr+2)
dosplay the same? They are a pointer to an array and a pointer to its first element. Although these pointets are of different types, they represent the same address, because the address of any array is the same as the address of its first element.
arr
is an array of arrays of int
. On almost any use an array is converted to a pointer to its first element. So arr
gets converted to a pointer to an array of int
.
OK, arr
gets converted to a pointer to an array of int
, so (arr+2)
is of the same type, that is, a pointer to an array of int
.
Now *(arr+2)
is the thing (arr+2)
points to. That is, an array of int
.
Now since it's an array of int
, it gets converted to a pointer to its first element. So *(arr+2)
gets converted to a pointer to int
. Note it is not an int
and is unlikely to be equal to 3
.
Now how come (arr+2)
and *(arr+2)
dosplay the same? They are a pointer to an array and a pointer to its first element. Although these pointets are of different types, they represent the same address, because the address of any array is the same as the address of its first element.
answered Aug 28 at 16:54


n.m.
68.3k779164
68.3k779164
add a comment |Â
add a comment |Â
up vote
1
down vote
arr
is the pointer to the first array of the type int[2]
.(arr + 2)
is the pointer to the third such array.
Whereas *(arr + 2)
is the pointer to the first element of the (arr +2)
array.
Both of these will hence have the same address since they are pointing to the same position.The only difference being in their type.(arr+2)
is of the type int(*)[2]
whereas *(arr + 2)
is of the type int *
.
add a comment |Â
up vote
1
down vote
arr
is the pointer to the first array of the type int[2]
.(arr + 2)
is the pointer to the third such array.
Whereas *(arr + 2)
is the pointer to the first element of the (arr +2)
array.
Both of these will hence have the same address since they are pointing to the same position.The only difference being in their type.(arr+2)
is of the type int(*)[2]
whereas *(arr + 2)
is of the type int *
.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
arr
is the pointer to the first array of the type int[2]
.(arr + 2)
is the pointer to the third such array.
Whereas *(arr + 2)
is the pointer to the first element of the (arr +2)
array.
Both of these will hence have the same address since they are pointing to the same position.The only difference being in their type.(arr+2)
is of the type int(*)[2]
whereas *(arr + 2)
is of the type int *
.
arr
is the pointer to the first array of the type int[2]
.(arr + 2)
is the pointer to the third such array.
Whereas *(arr + 2)
is the pointer to the first element of the (arr +2)
array.
Both of these will hence have the same address since they are pointing to the same position.The only difference being in their type.(arr+2)
is of the type int(*)[2]
whereas *(arr + 2)
is of the type int *
.
answered Aug 28 at 17:00


Ali
184116
184116
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52062706%2farr-2-is-equivalent-to-arr-2-how%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
3
You need to dereference it twice, since it's a 2D array:
*(*(arr+2))
– Govind Parmar
Aug 28 at 16:42
4
arr[2]
and*(arr + 2)
are the same by definition in the language (C11 §6.5.2.1 Array subscripting ¶2). And you get odd results because you're printing an address, not the value of a cell in the array. That's officially undefined behaviour; you pass an address toprintf()
but tell it that it's got an unsigned integer to work on. You might be OK on a 32-bit platform, sort of, more or less. Results are not remotely reliable on a 64-bit platform.– Jonathan Leffler
Aug 28 at 16:45
1
technically you're getting UB since
%u
is not for printing pointers. You have to use%zu
– phuclv
Aug 28 at 16:50
7
@phuclv: You're right that
%u
is UB, but so is using%zu
(that's for printingsize_t
). You should either use%p
and cast the pointer to avoid *
, or use<inttypes.h>
andPRIuPTR
(orPRIXPTR
for upper-case hex) plus a cast touintptr_t
.– Jonathan Leffler
Aug 28 at 16:52
1
@phuclv : False.
%zu
requires asize_t
argument. Any incompatible type will trigger undefined behavior. Pointer arguments will trigger undefined behavior.– AnT
Aug 28 at 17:04