Kernighan & Ritchie 2nd ed. says:

> 
> The correspondence between indexing and pointer arithmetic is very close. By definition, the value of a variable or expression of type array is the address of element zero of the array. Thus after the assignment  
> 
> `pa = &a[0];`
> 
> 
> `pa` and `a` have identical values. Since the name of an array is a synonym for the location of the initial element, the assignment `pa=&a[0]` can also be written as  
> 
> `pa = a;`
> 
> 
> Rather more surprising, at least at first sight, is the fact that a reference to `a[i]` can also be written as `*(a+i).` In evaluating `a[i]`, C converts it to `a[i]` immediately; the two forms are equivalent. Applying the operator & to both parts of this equivalence, it follows that `and` are also identical: `a+i` is the address of the `i`-th element beyond a. As the other side of this coin, if `pa` is a pointer, expressions may use it with a subscript; `pa[i]` is identical to `*(pa+i)`. In short, **an array-and-index expression is equivalent to one written as a pointer and offset**.
> 
> 
> 

And after reading this, I expect this two programs work identically:

```
/* Program 1 */
#include <stdio.h>

int main()
{
    char arr[] = "hello";
    arr[0] = 'H';
    printf("%s\n", arr);

}

/* Program 2 */
#include <stdio.h>

int main()
{
    char *arr = "hello";
    arr[0] = 'H';
    printf("%s\n", arr);

}

```

But only the first one is actually works. With the second one I get segmentation fault.

Why? Reference to an authoritative source would be much appreciated.