This is where a pen-and-paper analysis would help you understand the details.
Code:
/*
num = 1101 // binary
p = 3 // position
>> num ^= (1 << p);
Right side:
0001 << 3 - 1 // minus one because we start at 1, so we shift one less time
0010 // shift one
0100 // shift two ... now our set bit is in the third position
Now we do the XOR:
1101 // num
0100 // mask
----
1001 // result
A zero in the mask will not change the value:
0 xor 0 = 0
0 xor 1 = 1
A one in the mask will change the value:
1 xor 0 = 1
1 xor 1 = 0
*/
See how I subtracted one of the position variable? And do you understand why?