Well, there's the performance factor for the first part. Imagine, if every time you want to pass data to a function, you have to pass it by value. That is, copy it. Imagine that you have a HUGE array and you want to pass it to a function, and it copies it directly.
Pointers are just ways to access data that might or might not be outside the function's stack frame. Or, in the case that it's dynamically allocated, it'll be on the heap.
Either way, your programs use pointers constantly. It's the way things work. Data is located somewhere in memory, and to get it, you need the memory's address(Or to write to it, for that matter).
This code
Code:
#include <stdio.h>
int add(int b)
{
b++;
return b;
}
int main(void)
{
int crap = 2;
add(crap); // Variable won't be modified, just an example.
}
disassembles to this code on my machine(Vista, Mingw)
Code:
0x004012f0 <add+0>: push ebp
0x004012f1 <add+1>: mov ebp,esp
0x004012f3 <add+3>: inc DWORD PTR [ebp+0x8] ;; DEREFERENCING A POINTER
0x004012f6 <add+6>: mov eax,DWORD PTR [ebp+0x8] ;; Return value is always in eax
0x004012f9 <add+9>: pop ebp
0x004012fa <add+10>: ret
As you can see, it deferences a pointer to the variable and adds to it.