A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
arr and &arr print the same address. They are not the same type. arr decays to int*, a pointer to the first element. &arr is int (*)[N], a pointer to the entire array. The address is identical. The type is different. The difference manifests in pointer arithmetic: arr + 1 advances by sizeof(int), while &arr + 1 advances by sizeof(the entire array). This distinction matters in multi-dimensional arrays and when passing arrays to functions that expect a specific pointer type.
#include <stdio.h>int main(void) {int arr[5] = {10, 20, 30, 40, 50};printf("arr = %p\n", (void *)arr);printf("&arr = %p\n", (void *)&arr);printf("&arr[0] = %p\n", (void *)&arr[0]);printf("\narr + 1 = %p (advanced %ld bytes)\n",(void *)(arr + 1),(long)((char *)(arr + 1) - (char *)arr));printf("&arr + 1 = %p (advanced %ld bytes)\n",(void *)(&arr + 1),(long)((char *)(&arr + 1) - (char *)&arr));return 0;}
Same starting address. Different stride. arr + 1 moves 4 bytes (one int). &arr + 1 moves 20 bytes (five ints, the entire array). The type determines the arithmetic. If you are iterating over elements, you want arr + i. If you are skipping past the entire array to the next structure in a packed binary format, you want &arr + 1.
In a 2D array int matrix[3][4], matrix decays to int (*)[4], a pointer to an array of 4 ints. &matrix is int (*)[3][4], a pointer to the entire 3×4 block. matrix + 1 advances by 4 ints (one row). &matrix + 1 advances by 12 ints (the entire matrix). Getting this wrong in a nested loop means you skip rows or read garbage.
The address is the same. The type is different. The arithmetic is different. This is one of those C subtleties that separates people who use pointers from people who understand them. Next: function vs &function, the same class of distinction applied to function pointers.
Finish the lesson once you have worked through the material. This awards ★ 30 XP.