25
Constants

We have spent a lot of time discussing variables, which, as the name indicates, change their values as the program runs. There are, however, pieces of information that do not change value. For example, the mathematical constant π never changes. We call these things constants, and there are two common ways that Objective-C programmers define them: #define and global variables.

In Xcode, create a new Foundation Command Line Tool called Constants.

In the standard C libraries, constants are defined using the #define preprocessor directive. The math part of the standard C library is declared in the file math.h. One of the constants defined there is M_PI. Use it in main.m:

#​i​m​p​o​r​t​ ​<​F​o​u​n​d​a​t​i​o​n​/​F​o​u​n​d​a​t​i​o​n​.​h​>​

i​n​t​ ​m​a​i​n​ ​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​@​a​u​t​o​r​e​l​e​a​s​e​p​o​o​l​ ​{​

 ​ ​ ​ ​ ​ ​ ​ ​N​S​L​o​g​(​@​"​​u​0​3​c​0​ ​i​s​ ​%​f​"​,​ ​M​_​P​I​)​;​

 ​ ​ ​ ​}​
 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

When you build and run it, you should see:

π​ ​i​s​ ​3​.​1​4​1​5​9​3​

To the definition for the M_PI constant, press the Command key and then click on M_PI in your code.

Figure 25.1  Definition for M_PI

Definition for M_PI

Where are you? If you look at the navigation bar at the top of the editor area, you will see that you are now in math.h.

Command-clicking is useful whenever you need to see how something is defined. You can use it with constants, functions, classes, methods, types, and more.

To get back to main.m, click the Definition for M_PI button to the left of the navigation bar at the top of the editor area. Or select main.m in the project navigator.

You may be wondering why you did not have to explicitly include math.h in main.m to use M_PI. When you created a new Foundation command-line tool, the template imported Foundation/Foundation.h for you. Foundation/Foundation.h includes CoreFoundation/CoreFoundation.h, which includes math.h.

Preprocessor directives

Compiling a file of C, C++, or Objective-C code is done in two passes. First, the preprocessor runs through the file. The output from the preprocessor then goes into the real compiler. Preprocessor directives start with #, and the three most popular are #include, #import, and #define.

#include and #import

#include and #import do essentially the same thing: request that the preprocessor read a file and add it to its output. Usually, you are including a file of declarations (a .h file), and those declarations are used by the compiler to understand the code it is compiling.

What is the difference between #include and #import? #import ensures that the preprocessor only includes a file once. #include will allow you to include the same file many times. C programmers tend to use #include. Objective-C programmers tend to use #import.

When specifying the name of the file to be imported, you can wrap the filename in quotes or angle brackets. Quotes indicate that the header is in your project directory. Angle brackets indicate that the header is in one of the standard locations that the preprocessor knows about. (<math.h>, for example, is /Applications/​Xcode46-DP3.app/​Contents/​Developer/​Platforms/​MacOSX.platform/​Developer/​SDKs/​MacOSX10.8.sdk/​usr/​include/​math.h.) Here are two examples of #import directives:

/​/​ ​I​n​c​l​u​d​e​ ​t​h​e​ ​h​e​a​d​e​r​s​ ​I​ ​w​r​o​t​e​ ​f​o​r​ ​P​e​t​ ​S​t​o​r​e​ ​o​p​e​r​a​t​i​o​n​s​
#​i​m​p​o​r​t​ ​"​P​e​t​S​t​o​r​e​.​h​"​

/​/​ ​I​n​c​l​u​d​e​ ​t​h​e​ ​h​e​a​d​e​r​s​ ​f​o​r​ ​t​h​e​ ​O​p​e​n​L​D​A​P​ ​l​i​b​r​a​r​i​e​s​
#​i​m​p​o​r​t​ ​<​l​d​a​p​.​h​>​

In a project, it used to be pretty common to include a collection of headers in every file of code. This led to clutter at the beginning of your file and made compiles take longer. To make life easier and compiles faster, most Xcode projects have a file that lists headers to be precompiled and included in every file. In your Constants project, this file is called Constants-Prefix.pch.

So, how did a constant from math.h get included when main.m was compiled? Your main.m file has the following line:

#​i​m​p​o​r​t​ ​<​F​o​u​n​d​a​t​i​o​n​/​F​o​u​n​d​a​t​i​o​n​.​h​>​

The file Foundation.h has this line:

#​i​n​c​l​u​d​e​ ​<​C​o​r​e​F​o​u​n​d​a​t​i​o​n​/​C​o​r​e​F​o​u​n​d​a​t​i​o​n​.​h​>​

And the file CoreFoundation.h has this line:

#​i​n​c​l​u​d​e​ ​<​m​a​t​h​.​h​>​

#define

#define tells the preprocessor, Whenever you encounter A, replace it with B before the compiler sees it. Look at the line from math.h again:

#​d​e​f​i​n​e​ ​M​_​P​I​ ​ ​ ​ ​ ​ ​ ​ ​3​.​1​4​1​5​9​2​6​5​3​5​8​9​7​9​3​2​3​8​4​6​2​6​4​3​3​8​3​2​7​9​5​0​2​8​8​

In the #define directive, you just separate the two parts (the token and its replacement) with whitespace.

#define can be used to make something like a function. In main.m, print the larger of two numbers:

#​i​m​p​o​r​t​ ​<​F​o​u​n​d​a​t​i​o​n​/​F​o​u​n​d​a​t​i​o​n​.​h​>​

i​n​t​ ​m​a​i​n​ ​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​@​a​u​t​o​r​e​l​e​a​s​e​p​o​o​l​ ​{​

 ​ ​ ​ ​ ​ ​ ​ ​N​S​L​o​g​(​@​"​​u​0​3​c​0​ ​i​s​ ​%​f​"​,​ ​M​_​P​I​)​;​
 ​ ​ ​ ​ ​ ​ ​ ​N​S​L​o​g​(​@​"​%​d​ ​i​s​ ​l​a​r​g​e​r​"​,​ ​M​A​X​(​1​0​,​ ​1​2​)​)​;​

 ​ ​ ​ ​}​
 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

MAX is not a function; it is a #define. The most basic C version of MAX is:

#​d​e​f​i​n​e​ ​M​A​X​(​A​,​B​)​ ​ ​ ​ ​(​(​A​)​ ​>​ ​(​B​)​ ​?​ ​(​A​)​ ​:​ ​(​B​)​)​

So, by the time the compiler saw the line you just added, it looked like this:

N​S​L​o​g​(​@​"​%​d​ ​i​s​ ​l​a​r​g​e​r​"​,​ ​(​(​1​0​)​ ​>​ ​(​1​2​)​ ​?​ ​(​1​0​)​ ​:​ ​(​1​2​)​)​)​;​

When you use #define to do function-like stuff instead of simply substituting a value, you are creating a macro.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset