Objective-C Programming_ The Big Nerd Ranch Guide - Aaron Hillegass [83]
Figure 33.7 Left-shifting by 2
Left-shift is done with the << operator. Add a shift of two places to main.c:
unsigned char g = a << 2;
printf("Hex: %x shifted left two places is %x\n", a, g);
printf("Decimal: %d shifted left two places is %d\n", a, g);
return 0;
}
When this code runs, you will see:
Hex: 3c shifted left two places is f0
Decimal: 60 shifted left two places is 240
Every time you left-shift a number one place, you double its value.
Right-shift
The right-shift operator should not be much of a surprise. Add code to main.m:
unsigned char h = a >> 1;
printf("Hex: %x shifted right one place is %x\n", a, h);
printf("Decimal: %d shifted right one place is %d\n", a, h);
return 0;
}
When run:
Hex: 3c shifted right one places is 1e
Decimal: 60 shifted right two places is 30
Figure 33.8 Right-shifting by 1
Every time you right-shift a number one place, you half its value. (If it is odd, round down.)
Using enum to define bit masks
Often you will want to define a list of constants, each representing an integer with one bit turned on. Then, these integers can be bitwise-ORed together and tested for using bitwise-AND, as described above.
The elegant way to do this is to define an enum that uses the left-shift operator to define the values. Here is how the constants for the UIDataDetector are defined:
enum {
UIDataDetectorTypePhoneNumber = 1 << 0,
UIDataDetectorTypeLink = 1 << 1,
UIDataDetectorTypeAddress = 1 << 2,
UIDataDetectorTypeCalendarEvent = 1 << 3,
UIDataDetectorTypeNone = 0,
UIDataDetectorTypeAll = NSUIntegerMax
};
More bytes
In this chapter, we worked with unsigned char, which is one 8-bit byte. Any unsigned integer type will work the same way. For example, NSTextCheckingTypePhoneNumber is actually declared uint64_t, a 64-bit unsigned number.
Challenge
Write a program that creates an unsigned 64-bit integer such that every other bit is turned on. (There are actually two possible resulting numbers: one is even, the other is odd. Create the odd one.) Display the number.
34
C Strings
Given the choice, an Objective-C programmer will always choose to work with NSString objects rather than C strings. However, sometimes we don’t have a choice. The most common reason we end up using C strings? When we access a C library from within our Objective-C code. For example, there is a library of C functions that lets your program talk to a PostgreSQL database server. The functions in that library use C strings, not instances of NSString.
char
In the last section, we talked about how a byte could be treated as a number. We can also treat a byte as a character. As mentioned earlier, there are many different string encodings. The oldest and most famous is ASCII. ASCII (American Standard Code for Information Interchange) defines a different character for each byte. For example, 0x4b is the character ‘K’.
Create a new C Command Line Tool and name it yostring. In this program, you are going to list some of the characters in the ASCII standard. Edit main.c:
#include int main (int argc, const char * argv[]) { char x = 0x21; // The character '!' while (x <= 0x7e) { // The character '~' printf("%x is %c\n", x, x); x++; } return 0; } You may be wondering “Hey, a byte can hold any one of 256 numbers. You just printed out 94 characters. What happened to the to the rest?” It is important to realize that ASCII was written to drive old teletype-style terminals that printed to paper instead of to a screen. For example, the number 7 in ASCII makes the terminal bell ring. In fact, the characters 0 - 31 in ASCII are unprintable control codes. Number 32 is the space character. Number 127 is the delete – it causes the previous character to disappear. What about characters 128 – 255? ASCII only uses 7 bits. There is no ASCII character for the number 128. You can use ASCII characters