macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Go with the Flow
Pages: 1, 2

Now We're Writing in Code

Some people are all about shortening the code they write. This can be an admirable goal: less code can mean a faster operation and a simpler more maintainable codebase. Sometimes brevity can make your code much cleaner. Toward these goals C includes an operator that performs one of the tasks that an if/else block is often called in to perform: setting a variable to two different values based on some boolean logic. This operator, called the ternary operator, turns this code:

int integerForSeedValue(int seedNumber) {
	int retval = 0;
	
	if (seedNumber == 8) {
		retval = seedNumber - 3;
	} else {
		retval = seedNumber * 3;
	}
	
	return retval;
}

Into this code:

int integerForSeedValue(int seedNumber) {
	return (seedNumber == 8) ? (seedNumber - 3) : (seedNumber * 3);
}

That's quite a savings of space, but the second snippet looks like quantum physics. Let's take this line apart token by token.

We start with return, which we know and love from our last lesson. Then we've got a bit in parentheses that is boolean logic. This is the condition we're used to in a normal if/else block, expressed in exactly the same way. If we put a semicolon here, the result of the condition would be returned. Instead we have a question mark, which tells the computer that it just read a condition for a ternary operator, and the other parts are next. The next bit in parentheses is what we want the ternary operator to evaluate to if the condition is true. This is first, just like the true condition is first in a normal if/else block. Then we have a colon, which tells the computer that we're done with the true case and moving on to the false case. Here we put what we want the ternary operator to evaluate to if the condition is false.

So you can read the question mark as "if the following is true, evaluate this" and the colon as "but if the condition was false, evaluate this instead." But note that you can only evaluate the cases, meaning multiple lines isn't an option, and each case must evaluate to be the proper type or you'll get a warning.

Another thing to note is that we've introduced a new operator, "==", the equality conditional. This checks to see if the thing on the left is equal to the thing on the right, and if they are it evaluates to TRUE, otherwise to FALSE. Why isn't it a single equals sign? Because we already use that token to set the value of variables and that means we can't use it here.

Flip the Switch

When you're dealing with code that must decide between a few options, if is the way to go. But if you need to use one input to decide amongst a lot of things, Then it's much simpler to just use a switch:

int integerForSeedValue(int seedNumber) {
	int retval = 0;
	
	switch (seedNumber) {
		case 1:
			printf("The Seed was one, not many.\n");
			retval = seedNumber;
			break;
		case 8:
			printf("We have an eightfold seed.\n");
			retval = seedNumber * 2;
			break;
	}
	
	return retval;
}

In this section, too, we will examine many different incarnations of the integerForSeedValue function, and you should run your program with each of them.

Let's pull the code apart. We start with the token switch, then something in parentheses. After that is a block. But the stuff in parentheses isn't a condition, it's the switch variable. This is the variable whose value determines what gets done inside the switch block.

Once we know this variable, we move through the switch block looking for case lines with the same value, and ignoring all the other code until we find one. When we do find one, we execute the code after it until we hit a break statement, which pops us out of the block. Note that hitting another case statement will not end the block: a break is the only thing that will stop it. That seems odd until you consider the following:

int integerForSeedValue(int seedNumber) {
	int retval = 0;
	
	switch (seedNumber) {
		case 1:
			printf("Surreptitiously, a singular seed..\n");
			retval = seedNumber;
			break;
		case 6:
		case 7:
		case 8:
			printf("Our seed is 6, 7, or maybe even 8!\n");
			retval = seedNumber * 2;
			break;
	}
	
	return retval;
}

Which means that if seedNumber is 6, 7, or 8, retval will be set to seedNumber * 2. In other words, you can group cases together if you want them all to do the same code.

But note that each case here is a constant integer. This is a very important limitation in the way switch works: its cases can only be constants and can't be boolean expressions, like if/else blocks' conditions.

The switch syntax also provides a way to catch anything you didn't account for. The following snippet is an example:

int integerForSeedValue(int seedNumber) {
	int retval = 0;
	
	switch (seedNumber) {
		case 1:
			printf("He is The One.\n");
			retval = seedNumber;
			break;
		case 8:
			printf("And the number of the seed shall be eight.\n");
			retval = seedNumber * 2;
		default:
			printf("What a seed it is!\n");
			retval++;
	}
	
	return retval;
}

We added a default case. The code here will be executed if no matching case is found, or if no break is found beforehand. Note that we took away the break in case 8. This allows the default to be executed when seedNumber is 8, which it is in our program as written in Lesson 2.

But you might have noticed that the code in our default case is something we haven't seen before. The "++" is yet another operator, the increment operator. It takes whatever is in retval and adds one. It's sister the decrement operator, "--", subtracts one.

Run all the different switch examples and see the results. Try to trace where the control flows.

A Conditional Ending

We've learned three ways of changing how our program control flows, each of which is useful for different situations. We can now change code execution based on boolean logic, we can set variables based on the same logic, and our code can change how it works based on the value of variables.

But there's more. As useful as these structures are, they don't let you do the same thing over and over, which is the exclusive domain of loops, which we will cover in our next lesson.

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.


Return to MacDevCenter.com