1) If you want a function to change its argument, that argument must be passed as a pointer.
Code:
#include <stdio.h>
void try_A(int i)
{
i = 42;
}
void try_B(int *i)
{
*i = 10;
}
int main()
{
int x = 2, y = 3;
try_A(x);
try_B(&y);
printf("x = %d, y = %d\n", x, y);
}
If you run this code, it will report x has a value of 2 (as the change made by try_A() is invisible to main()) and y has a value of 10 (since try_B() changed it in a manner visible to main()).
2) Pointers are a building block that allows a program to dynamically allocate and manage memory. Imagine you know you need an array, but the size can only be determined by data obtained by the program when run, and the function which allocates that array needs to provide that array to its caller.
3) [Note this is a slightly more advanced reason]. In general, a pointer is an abstraction that can be used to iterate over memory. They can be used to iterate over elements of an array. They also make it much easier to implement certain data structures, such as linked lists.