Basically, you're right. However an unsigned integer is (usually) 32 bits long (on a 32 bit system).
So you're not only flipping the last two bits but the 30 bits before as well.
To solve this, you'll just have to mask the bits you're interested in:
#include <stdio.h>
int main(int argc, char **argv)
{
unsigned int a = 0x2; //= 10b
unsigned int b = ~a & 0x3; //= 01b (0x3 = 11b)
printf("%04x : %04x\n", a, b);
}