I guess i would say that it does come up, you will run into it, so why not learn it now? I wouldn't want it to totally flummox you and put you off programming for good, but it's certainly not the hardest concept I've run into, so it may be worth working through it now.
The real difficulty is that to know what's going on you need to have an understanding of binary numbers. I'll avoid floating point for now, as it's unnecessary and i rarely see bitwise operators used against floats or doubles.
The integer types in C/objective-C are stored in 2's complement. Reading up on this may come in handy, later, too:
http://en.wikipedia.org/wiki/Two's_complement
Most basically, binary is a number system like base 10/decimal that you are used to dealing with. Instead of 10 possible values for each place/-it (digit in decimal), there are only 2. Each place is called a bit (bi- for two, dig- for ten). Instead of a 1s place, 10s place, 100s place like in decimal, there is a 1s place, a 2s place, a 4s place, an 8s place, etc. Since there are only two possible values for each bit, each place is either "on" (1) or "off" (0). For a positive number, it's pretty easy to just look at a value and convert it to base 10. For example:
0101
8's place is 0. +0
4's place is 1. +4
2's place is 0. +0
1's place is 1. +1
Decimal: 5
There's no 4-bit datatype in C, but i'll stick to that width for simplicities sake. The bitwise or, |, checks the bits at each place and if either is 1, the result is 1. It's table looks like this:
Code:
_|[U] 0 [/U]|[U] 1 [/U]|
[U]0| 0 | 1 |[/U]
1| 1 | 1 |
To read the table, just pick one of your bits on the top of the table, and one from the left side, and look in the square they meet. This will be the result for that bit. So:
0010 | 1010 = 1010
1000 | 1011 = 1011
0101 | 1010 = 1111
Each bit is computed separately (hence the term bit-wise).
Here is the table for and, &:
Code:
_|[U] 0 [/U]|[U] 1 [/U]|
[U]0| 0 | 0 |[/U]
1| 0 | 1 |
0010 & 1010 = 0010
1000 & 1011 = 1000
0101 & 1010 = 0000
And here is the table for exclusive or, ^,which means exactly one of the bits being compared is 1. This is, in my opinion, the best operator.
Code:
_|[U] 0 [/U]|[U] 1 [/U]|
[U]0| 0 | 1 |[/U]
1| 1 | 0 |
0010 ^ 1010 = 1000
1000 ^ 1011 = 0011
0101 ^ 1010 = 1111
Generally these operations are used to store "a lot" of options in a small space. For example, in a short int you have 16 bits available, so you can represent 16 different options being "on" or "off". In an int you have 32 such options. Normally there will be things #define'd, etc. that are set to a constant with one such bit set for each option, and perhaps another set to turn an option off, with all bits but that set. I'll keep using binary and psuedocode:
Code:
#define optAon 0001
#define optBon 0010
#define optCon 0100
#define optDon 1000
#define optAoff 1110
#define optBoff 1101
#define optCoff 1011
#define optDoff 0111
//...
x=x|optAon; //x is now the same as before, but the bit defined for option A is set, whether or not it was before
//..
x=x&optBoff; //x is now the same, but with option B's bit off, whether or not it was before
//..
x=optAon|optBon; //x now has option A and option B set, and C and D off, regardless of its previous value
Code like this is often used to modify options for a function, etc. when there are a small set of "on/off" options. Some have been mentioned above.
There are certainly more exotic things that can be done with these operators and the bitshift operators << and >>, but hopefully this helps a bit with where you are now.
-Lee