Do you believe in C? Do you believe in anything that has to do with me?
- Most of your iOS programming will be in the Objective-C language, and Objective-C is a superset of C. This means that Objective-C presupposes C; everything that is true of C trickles up to Objective-C. A common mistake is to forget that “Objective-C is C” and to neglect a basic understanding of C.
- Some of the iOS API involves C rather than Objective-C. Even in Objective-C code, you often need to use C data structures and C function calls. For example, a rectangle is represented as a CGRect, which is a C struct, and to create a CGRect from four numbers you call CGRectMake, which is a C function. The iOS API documentation will very often show you C expressions and expect you to understand them.
The best way to learn C is to read The C Programming Language (PTR Prentice Hall, 1988) by Brian W. Kernighan and Dennis M. Ritchie, commonly called K&R (Ritchie was the creator of C). It is one of the best computer books ever written: brief, dense, and stunningly precise and clear. K&R is so important for effective iOS (and Mac OS X) programming that I keep a physical copy beside me at all times while coding, and I recommend that you do the same. Another useful manual is The C Book, by Mike Banahan, Declan Brady and Mark Doran, available online at http://publications.gbdirect.co.uk/c_book/.
You don’t have to know all about C in order to use Objective-C effectively, though; and that’s a good thing. C is not a large or difficult language, but it has some tricky corners and can be extremely subtle, powerful, and low-level. Also, it would be impossible, and unnecessary, for me to describe all of C in a single chapter. C is described far more fully and correctly in K&R, The C Book, and elsewhere than I could possibly do it. Sooner or later, you’re probably going to have technical questions about C that this chapter doesn’t (and shouldn’t) make any attempt to answer. So I emphasize that you really, really ought to have K&R or something similar at hand and resort to it as needed.
What I can do, and what this chapter will attempt to do, is tell you what aspects of C are important to understand at the outset, before you even start using Objective-C for iOS programming. That’s why this chapter is “Just Enough C”: it’s just enough to get you going, comfortably and safely.
If you know no C at all, I suggest that, as an accompaniment to this chapter, you also read parts of K&R (think of this as “C: The Good Parts Version”). Here’s my proposed K&R syllabus:
- Quickly skim K&R Chapter 1, the tutorial.
- Carefully read K&R Chapters 2 through 4.
Read the first three sections of K&R Chapter 5 on pointers and arrays. You don’t need to read the rest of Chapter 5 because you won’t typically be doing any pointer arithmetic, but you do need to understand clearly what a pointer is, as Objective-C is all about objects and every reference to an object is a pointer; you’ll be seeing and using that
- Read also the first section of K&R Chapter 6, on structures (structs); as a beginner, you probably won’t define any structs, but you will use them quite a lot, so you’ll need to know the notation (for example, as I’ve already said, a CGRect is a struct).
- Glance over K&R Appendix B, which covers the standard library, because you may find yourself making certain standard library calls, such as the mathematical functions; forgetting that the library exists is a typical beginner mistake.
Just to make things a little more confusing, the C defined in K&R is not precisely the C that forms the basis of Objective-C. Developments subsequent to K&R have resulted in further C standards (ANSI C, C89, C99), and the Xcode compiler extends the C language in its own ways. By default, Xcode projects are treated as C99 (though you could specify another C standard if you really wanted to). Fortunately, the most important differences between K&R’s C and Xcode’s C are small, convenient improvements that are easily remembered, so K&R remains the best and most reliable C reference.
C is a compiled language. You write your program as text; to run the program, things proceed in two stages. First your text is compiled into machine instructions; then those machine instructions are executed. Thus, as with any compiled language, you can make two kinds of mistake:
- Any purely syntactic errors (meaning that you spoke the C language incorrectly) will be caught by the compiler, and the program won’t even begin to run.
- If your program gets past the compiler, then it will run, but there is no guarantee that you haven’t made some other sort of mistake, which can be detected only by noticing that the program doesn’t behave as intended.
The C compiler is fussy, but you should accept its interference with good grace. The compiler is your friend: learn to love it. It may emit what looks like an irrelevant or incomprehensible error message, but when it does, the fact is that you’ve done something wrong and the compiler has helpfully caught it for you. Also, the compiler can warn you if something seems like a possible mistake, even though it isn’t strictly illegal; these warnings, which differ from outright errors, are also helpful and should not be ignored.
I have said that running a program requires a preceding stage: compilation. But in fact there is a third stage that precedes compilation: preprocessing. (It doesn’t really matter whether you think of preprocessing as a stage preceding compilation or as the first stage of compilation.) Preprocessing modifies your text, so when your text is handed to the compiler, it is not identical to the text you wrote. Preprocessing might sound tricky and intrusive, but in fact it proceeds only according to your instructions and is helpful for making your code clearer and more compact.
C is a statement-based language; every statement ends in a semicolon. (Forgetting the semicolon is a common beginner’s mistake and is liable to get you a completely irrelevant and incomprehensible error message from the compiler.) For readability, programs are mostly written with one statement per line, but this is by no means a hard and fast rule: long statements (which, unfortunately, arise very commonly because of Objective-C’s verbosity) are commonly split over multiple lines, and extremely short statements are sometimes written two or three to a line. You cannot split a line just anywhere, however; for example, a literal string can’t contain a return character. Indentation is linguistically meaningless and is purely a matter of convention (and C programmers argue over those conventions with near-religious fervor); Xcode helps “intelligently” by indenting automatically, and you can use its automatic indentation both to keep your code readable and to confirm that you’re not making any basic syntactic mistakes.
Comments are delimited in K&R C by
/* ... */; the material between the delimiters can consist of multiple lines (K&R 1.2). In modern versions of C, a comment also can be denoted by two slashes (
//); the rule is that if two slashes appear, they and everything after them on the same line are ignored:
int lower = 0; // lower limit of temperature table
These are sometimes called C++-style comments and are much more convenient for brief comments than the K&R comment syntax.
Throughout the C language (and therefore, throughout Objective-C as well), capitalization matters. All names are case-sensitive. There is no such data type as Int; it’s lowercase “int.” If you declare an int called
lower and then try to speak of the same variable as
Lower, the compiler will complain. By convention, variable names tend to start with a lowercase letter.