06 Moar Functions, Local, Static, Global Variables

We've had some great discussion, so let's review the high points. A whole lot
of C programming howtos are outdated or just plain wrong; there is a lot of
reeking rubbish out there. I have read dozens of C programming howto books
(yes, dozens, and for that alone you should worship me; it was painful and
horrid) and I have finally found one that I can recommend enthusiastically, and
that is "C Programming: A Modern Approach, 2nd edition" by K.N. King. It costs
anywhere from $70-$100, but it's worth it. I've wasted several times that on
inferior books. King has a clear, logical writing style, uses and explains
correct terminology, and has four fabulously helpful appendices: a table of C
operators, comparison of C99 vs. C89, comparison of C89 vs. K&R, and a table
of standard C library functions.

====DON'T LET THE BUZZARDS DISCOURAGE YOU====

One of the best ways to learn is to try new things, and share your code for
other people to review. The downside of this is the Internet is full of
nitpicky annoying jerks who are full of opinions and rudeness, and who will
criticize and put down pretty much everything and anyone.

Just keep in mind they do not matter. If they offer useful knowledge, take it
and ignore the rest. Don't let them shake your self-confidence, because right
or wrong you're trying to learn, and that means making mistakes. It's also
worth remembering that there are often multiple valid ways to do something,
and there are not always clear rights or wrongs. A trick I use is to post
under a pseudonym-- this creates some psychological distance so the asshats
are giving my pseudonym a hard time, not me. I haven't experienced all that
much hostility in coding discussions, so don't expect to get flamed a lot. Just
don't let it derail you if it does happen.

Another trick I use is to be wrong on purpose. It seems to be a constant of
human nature, that when you ask for help you may or may not get some. But if
you are wrong you'll get people competing to correct you. It can sting the
ego, but it works!

====C STANDARDS AND REVISIONS====

The K&R book, "C Programming Language" by Brian Kernighan and Dennis Ritchie,
is still revered and a big seller. And it is very outdated. It won't hurt
anyone to study it and learn about the C language from its inventors, and to
better understand the differences between old and new. "C Programming: A Modern
Approach" doesn't teach K&R C, but rather C89 and C99.

There are four main C language standards:

K&R C
ANSI/ISO C
C99
C11

K&R was a de-facto standard. The ISO adopted ANSI C as the standard in 1990,
so sometimes you'll see it called C90. ANSI/ISO/C89/C90 are all the same
thing.

C99 was ratified in 1999.

C11 was ratified in 2011. This is most current C language revision. The world
is still catching up to C99, so many of the changes in C11 were made optional.
In this course I doubt we'll talk about C11, though you never know. If you
want to know more about these do please feel free to research them and share
any interesting bits you find.

Every compiler has different levels of standards support, and support for non-
standard features. Some libraries are not standards-compliant. If you want to
write portable code then standards are very important. The gcc manuals will
help with this http://gcc.gnu.org/onlinedocs/

=====OLD CODER'S TALES=====

One of the biggest and most persistent fallacies concerns optimizing your
code, using fancy compiler option and coding tricks to make it faster.
Innocent newbs get trapped in this all the time. Once upon a time it made
sense to try to manually optimize your C code, but not so much anymore as
compilers have become sophisticated at optimizing it for you. Your attempts at
optimization may even have the opposite effect. Jacinta and Akkana give
excellent advice:

==========

" > 1. The first rule of Optimization Club is, you do not Optimize.
> 2. The second rule of Optimization Club is, you do not Optimize without
> measuring.
> 3. If your code doesn't do what you want it to do, you have no business
> optimizing it.
> 4. If your app is running faster than the underlying transport protocol,
the
> optimization is over.
> 5. One factor at a time.
> 6. Testing will go on as long as it has to.
> 7. If this is your first night at Optimization Club, you have to write a
test
> case.

And this all applies no matter what language you're using.
We talk about it more in the C world, but if you find yourself
writing Python or Perl or Ruby and wanting to optimize something
before you even have the code working ... think of Optimization Club.

Note: this doesn't mean you should write obviously huge
bloated inefficient code, either. It just means write simple,
straightforward code at first, and leave the tricky hard-to-read
optimizations for after you get things working and measured."

==========

Jacinta, Akkana, Kai, and Kathryn have all contributed excellent comments on
coding style, program design, and good practices. If you have not read them
you might take a few minutes to go back and review them. (If I missed someone,
sorry! Speak up!)

====MOAR FUNCTION STUFF====

We're not done with functions. I think it is fair to say that C programming is
all about functions. Even if you never write a program with anything other
than main, you will still use functions. Take a look inside stdio.h: it's
cram-full of functions.

In last week's lesson I talked about five different ways functions can be
written. Number Five is "Return multiple values." As Akkana noted this is
complex to implement and error-prone, and Chris pointed out that, strictly
speaking, return statements only return single values, so I'll drop it and
limit the list to the first four. I gave examples of the first three, so here is
one way to demonstrate the fourth, No arguments but returns a value:

========================
//fourthtype, demonstrating the
//fourth function type of
//no arguments, returns a value

#include

int getnumber (void);

int main(void)
{
int a = getnumber();
printf("Thank you, the number you entered is %d.\n", a);
return 0;
}

int getnumber(void)
{
int num = 0;
printf("Enter a number smaller than 100: \n");
scanf("%d",&num);
return(num);
}

=========================

In real life you won't be concerned with The Four Types of Functions like it's
some kind of big deal list. The value in this exercise is it helps to
understand the different parts of a function and how they work. Remember our
function diagram from last week:

return_type function_name (argument_data_type arg1, argument_data_type arg2)
{
statement 1;
statement 2;
howevermanymore statements;
}

And our function prototypes:

return_type function_name (argument_data_type, argument_data_type);

Function prototypes end in semi-colons, and function declarations do not.
Perhaps I am being too repetitious, but people get mixed up on function basics
all the time.

====LOCAL, STATIC, AND GLOBAL VARIABLES====

We've been using variables almost from the beginning. Variables, of course,
are essential to any type of programming.

We can control the reach of our variables by making them local, static, or
global. A local variable is declared inside the body of a function, and it has
'local' or 'block scope', which means it exists only inside that function. We
can easily test this:

======================

//modifying fourthtype to
//demonstrate local variable

int getnumber (void);

int main(void)
{
int a = getnumber();
printf("Thank you, the number you entered is %d.\n", a);
printf("The value of num is %d.\n", num);
return 0;
}

int getnumber(void)
{
int num = 0;
printf("Enter a number smaller than 100: \n");
scanf("%d",&num);
return(num);
}

=====================

When you run it you'll get a compiler error, because num is not available to
main. A local variable has 'automatic storage duration', or 'extent.' This
means memory storage for the variable is automatically allocated when the
function is called, and deallocated when the function returns. It does not
retain its value, so when the function is called again it starts over.

A static variable also has local scope, but it retains its value throughout
the execution of your program, which is called 'static storage duration'. So
if the function is called again, a static variable retains its value from the
previous function run. The following example program shows this in action:

======================

//staticdemo, showing the difference between
//local and static variables

#include

int staticdemo (void);

int main(void)
{
int a = 0;
for (a = 0; a < 10; a++)
staticdemo ();
return 0;
}

int staticdemo (void)
{
int autovariable = 2;
static int staticvariable = 2;
printf ("The auto local variable value is %d, and the static variable value
is %d\n", autovariable, staticvariable);
autovariable++;
staticvariable++;
return 0;
}

======================

This is what happens when it runs:

$ staticdemo
The auto local variable value is 2, and the static variable value is 2
The auto local variable value is 2, and the static variable value is 3
The auto local variable value is 2, and the static variable value is 4
The auto local variable value is 2, and the static variable value is 5
The auto local variable value is 2, and the static variable value is 6
The auto local variable value is 2, and the static variable value is 7
The auto local variable value is 2, and the static variable value is 8
The auto local variable value is 2, and the static variable value is 9
The auto local variable value is 2, and the static variable value is 10
The auto local variable value is 2, and the static variable value is 11

You'll notice a new operator in this examples, and that is the increment
operator, ++. The increment operator adds one to the operand and stores the
new value back in the operand, so you could spell it out this way:

variable = variable + 1

We've played with for loops before, and staticdemo shows how to snag the value
computed by a function and use it in a for loop in main.

Static variables are useful when you need to keep a running count in a
repetitive operation. Like the steady upward progress of the total in your
bank account. (Hey we can dream.)

Global variables, also called external variables, are declared outside the
body of any function, including main. Global variables have static storage
duration, just like static local variables. Global variables have 'file scope';
they are available to all other functions in the same file. We can easily
demonstrate this by modifying our fourthtype program:

================
//fourthtype, modified with
//a global variable

#include

int num = 0;

int getnumber (void);

int main(void)
{
int a = getnumber();
printf("Thank you, the number you entered is %d.\n", a);
printf("The value of num is %d.\n", num);
return 0;
}

int getnumber(void)
{
// static int num = 0;
printf("Enter a number smaller than 100: \n");
scanf("%d",&num);
return(num);
}

===================

$ fourthtype
Enter a number smaller than 100:
23
Thank you, the number you entered is 23.
The value of num is 23.

Here we are at the end of lesson 6, I hope you learned something useful. I'm
on vacation this week so there will be no lesson next Sunday, but I will check
email to check your homework and participate in the discussion.

====HOMEWORK====

Go back to some of the programs you have written for this course and modify
them to use static and global variables, and share some of them on the list.

Modify staticdemo with different values for all the variables and see what
happens, and explain how it works. Replace a++ in the for loop with a=a+3 or
some other number. The for loop in my example is supposed to stop when a is no
longer less than 10-- but staticvariable stops at 11. Why?

We've tried for loops, if/else/while, doing stuff with user input, and simple
functions, so we have enough tools to write programs that can perform a few
different tasks. All programming starts with a clear design; just like building
a house you must start with a plan. Jacinta shared a lesson she uses with her
students: write a program to make coffee. So start first with the program design
and lay out all the steps:

1. Assemble everything (cup, spoon, coffee, kettle, milk, water etc)
2. Put water in the kettle and boil [*]
3. Put coffee in cup
4. Pour hot water into cup [*]
5. Add milk (if desired) [*]
6. Stir [*]

Then write the program. Write this one, write your own program for planning a
party (hi Leslie!), planting a garden, building a new PC, creating a simple
book catalogue-- anything you want. Show your steps and then your program. If
you only have time for one of the homework assignments consider doing this
one, because it will be a good exercise in putting everything we've covered so
far together. Simple is fine; you don't have to be K&R.