It distinguishes based on the type of the object being added. If it's a pointer, then the address is increased by the number you specify multiplied by the size of the object the pointer is specified to point at.
IOW, given some type T, and an addition like:
T *result = base + increment;
...it's basically equivalent to something like this:
char *raw_address = (char *)base_address;
raw_address += increment * sizeof(T);
result = (T *)raw_address;
Note, however, that in quite a few cases the CPU may be able to handle the scaling for at least some types (e.g., 1, 2, 4, or 8-byte types) in a single instruction (e.g., Intel x86/x64 and compabibles can combine scaling and addition like this).