Well if you consider they are all holding addresses ...then
What is the difference?
Difference is suppose I have 10 bytes of memory
---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | |
---+---+---+---+---+---+---+---+---+---+
1 2 3 4 5 6 7 8 9 10
Now suppose a char is of size 1 bye and int of 4 byte.
Now if someone asks you to give the integer starting from address 1 what you will do?
You know that size of int is 4 bytes so you get it and show it.
Similar for char you just get 1 locations value and show it.
Now a pointer similarly needs to know how much it should consider when it is asked to ( dereferenced)...
That's where int* and char* differ. Otherwise both of them hold addresse. And using a char* you can get all byes of an integer but that is overhead on part of user.
Formally....
The pointer to type basically tells the pointer how much it should move in memory from it's current location and how much is bytes staring from it's pointing address needs to be considered when dereferrenced.
Doubt-1 why don't we need &"Hello"?
char *d= "Hello" will place "Hello" in the read-only parts of the memory, and making d a pointer to that makes any writing operation on this memory illegal.
ALSO IN C "hello" has type char[].
And an array can be converted to address of the first element automatically
dpoints to the first one. Pointers are just addresses, but the data at that address is to be interpreted as a specific type.