I have a few questions. This isn't homework. I just want to understand better.

So if I have

`int * b = &k;`

1. Then `k` must be an integer, and `b` is a pointer to `k`'s position in memory, correct?
2. What is the underlying "data type" of `b`? When I output it, it returns things like `0x22fe4c`, which I assume is hexadecimal for memory position `2293324`, correct?
3. Where exactly is memory position '2293324'? The "heap"? How can I output the values at, for example, memory positions `0`, `1`, `2`, etc?
4. If I output `*b`, this is the same as outputting `k` directly, because `*` somehow means the value pointed to by `b`. But this seems different than the declaration of `b`, which was declared `int * b = k`, so if `*` means "value of" then doesn't mean this "declare `b` to the value of `k`? I know it doesn't but I still want to understand exactly what this means language wise.
5. If I output `&b`, this is actually returning the address of the pointer itself, and has nothing to do with `k`, correct?
6. I can also do `int & a = k;` which seems to be the same as doing `int a = k;`. Is it generally not necessary to use `&` in this way?