Build and Run

So before we play around with this code that we just read through, let's give it a whirl.

Up at the top of the window, in the toolbar, there is an icon that looks like this if you're running Project Builder:

And like this if you're running Xcode:

This is the "Build and Run" button, which will compile the project that you're working on (make the code into language the computer can execute), and then run the program you made. If you click this now, you will build and run the code contained in this project, which is just the main function we've examined. Do this now, and watch the computer execute the code, printing the message into the window (in Xcode, you have to go to the Debug menu and select Show Run Log to see the message). If you get an error, make sure that everything is copied exactly.

So that's what you can do without writing a single line of code. But we already have a few lines of code sitting around from our last lesson, so let's pull those out and give them a whirl. Delete the comment and the call to printf, and paste in our code. Now your main.c file should contain this:

And again, click the Build and Run button (remember that if you're in Xcode, you have to select Show Run Log from the Debug menu). Now, instead of "Hello, World!", what prints is "My favorite number is 8!" And you made it print that.

But what else can you make it do? We'll explore our boundaries a little bit by defining our own function. So below the main function, put the following snippet of code:

int integerForSeedValue(int seedNumber) {
//code goes here
}

This is another function definition, so called because it defines exactly what the function does. There are a few things to notice here, the first being that the name of the function follows the same style we use for variables: take all of the words that make up what you're describing, smash them together with each word capitalized, and make the first letter lowercase.

Notice also that our function has one argument, and that argument is described in the parentheses. Our code defines its type, which is an int, and we give it a name, seedNumber, which again follows our variable-naming scheme. Every time we want to call this function, we must pass one integer into it, or the compiler will complain and the program will crash.

Note where the curly brackets are placed. This method is the traditional C style, with the opening bracket on the same line as the function name. Objective-C uses this same style, but C++ puts the opening bracket on the next line, all alone. Since C ignores whitespace, both are perfectly legal, and since a lot of people use C++ a lot, they're more used to it down there on the next line. So don't be alarmed if you see it move around a bit.

Lastly, we're returning an integer, but we have no code that says what we're returning. This is obviously a problem, but before we fix our function up, let's hit the Build button and see what the Developer Tools think. We want to build and not run for right now, because our code is not correct, and we need to see how the Developer Tools inform us of this fact. The Build button looks like this in Project Builder:

And like this in Xcode:

When you hit the Build button, the project window moves around a bit to make it obvious it's doing something. In Project Builder, an area opens up to tell you about how the build is going. In Xcode, the Errors and Warnings item on the left will open up. In either case, you will see the message warning: control reaches end of non-void function.

What's this? It's a warning. Warnings tell you that while the compiler was trying to understand your code, something seemed a little odd, and it decided to tell you about it. This warning tells you that you have made a function whose definition claims the function returns a value (an int, in our case), but the function body doesn't ever return anything. That would be just fine in a void function (which we'll get to later), but it's a little odd here, so the compiler gives you a warning. An error is a more serious problem that means that your code cannot be compiled as written, and you need to fix the problem before you can run. Both show up in the same places, but warnings will allow you to run your program, although they often foretell errors that will crash your program at run time. Click on the text and the developer tools will helpfully take you to the offending piece of code. For now, it's obvious that our new function is the culprit, but in huge projects, this click-and-go is a lifesaver.

For now we have a simple fix to our problem. We simply add a line into our function, so it looks like this:

Click Build again, and you will see that the warning disappears. It is a good practice to write code that has neither warnings nor errors, and we will strive to do this as we complete more complex code.

Spice Up the Function (Just for Fun)

But for now you may wonder about our little fix. Our function ignores the input we give it, doesn't do anything useful, and always returns the same thing. What is this, a Windows error dialog?

So let's spice up our function a little. Change the function to the following:

int integerForSeedValue(int seedNumber) {
return seedNumber - 3;
}

Now we're doing some work in our function, and we're returning something that changes, based on what we're given. We return the variable seedNumber, minus the constant 3. But you might be wondering how we can use the variable seedNumber without first issuing a variable declaration, and that is a very good question. The answer is that we did a variable definition, it's just not as visible as the others we have done. This definition is inside of the parentheses, in the argument list. There, when we note what arguments this function takes, we are also declaring these arguments to exist.

So now that we have a function, we need to call it. Up in our main function, replace the line

favoriteNumber = favoriteNumber + 2;

with the slightly altered line:

favoriteNumber = integerForSeedValue(favoriteNumber + 2);

Now we're calling our integerForSeedValue function from our main function. When the computer executes that line of code, it will look into our integerForSeedValue function and run all of the code in its code block before moving on to the next line of code in main. Note that while the computer is executing the lines in integerForSeedValue, the variable seedNumber will have the evaluated value of favoriteNumber + 2, which is 8. So integerForSeedValue will return 8-3, or 5. Let's build our program and see. Hit the Build button, to make sure we don't have any warnings or errors.

Well, what do you know? We do. The warning we got this time is warning: implicit declaration of function `integerForSeedValue'. What does that mean? Well, we know what a variable declaration is, and we know that we can't use variables until we declare them. And if we click on this warning, it takes us to where we're using our function, so it's a pretty logical step to think that functions need to be declared before use, too, and that's exactly right.

So we add in one line above main, to declare our function. Now our file looks like this:

Looks familiar, doesn't it? What we've done is take the function, knock it's block off, and present it here with a semicolon. That is enough for the compiler; this simple line is the function declaration we needed, and another Build confirms it when the compiler doesn't complain. Run the program, and you see that our favorite number is now 5, just like it should be!

Wrapping Up

Wow, we've made some progress in this lesson! We learned about the tools we'll need to use every day we're developing, we compiled and ran "Hello World!", we took a few lines of code and made it into a program, we learned how to recognize, implement, declare, and call functions, and we learned how to get information from the Developer Tools about problems with our code, and fix them before they're problems with our programs.

But we still have a long ways to go. Next time, we'll dive into
flow control, which affect the way our code gets executed, so we
can do more complex things than the "list of things to do" approach we
have been taking. That will give us a lot of the tools we need to make
more complex programs with the knowledge we've gained.

Seth Roby
graduated in May of 2003 with a double major in English and Computer Science, the Macintosh part of a three-person Macintosh, Linux, and Windows graduating triumvirate.