Revision as of 12:01, 13 May 2024 by Admin

Preliminaries

Before learning C syntax and programming constructs, it is important to learn the meaning of a few key terms that are central in understanding C.

Block Structure, Statements, Whitespace, and Scope

Sentences delimited with '/*' and '*/' are comments, and the compiler ignores them. They are described in Programming Structure and Style

Next we'll discuss the basic structure of a C program. If you're familiar with PASCAL, you may have heard it referred to as a block-structured language. C does not have complete block structure (and you'll find out why when you go over functions in detail) but it is still very important to understand what blocks are and how to use them.

So what is in a block? Generally, a block consists of executable statements.

But before we delve into blocks, let's examine statements. One way to describe statements is they are the text (and surrounding whitespace) the compiler will attempt to turn into executable instructions. A simpler definition is statements are bits of code that do things. For example:


int i = 6;

This declares an integer variable, which can be accessed with the identifier 'i', and initializes it to the value 6. The various data types are introduced in the chapter Variables.

You might have noticed the semicolon at the end of the statement. Statements in C always end with a semicolon (;). Leaving off the semicolon is a common mistake many people make, beginners and experts alike! So until it becomes second nature, be sure to double check your statements!

Since C is a "free-format" language, several statements can share a single line in the source file, like this:

/* this declares the variables 'i', 'test', 'foo', and 'bar'
    note that ONLY the variable named 'bar' is initialized to six! */
int i, test, foo, bar = 6;

There are several kinds of statements. You've already seen some of them, such as the assignment (i = 6;). A substantial portion of this book deals with statement construction.

Back to our discussion of blocks. In C, blocks begin with an opening brace "{" and end with a closing brace "}". Blocks can contain other blocks which can contain their own blocks, and so on.

Let's look at a block example.

int main(void)
{
    /* this is a 'block' */
    int i = 5;

    {
        /* this is also a 'block', nested inside the outer block */
        int j = 6;
    }

    return 0;
}

You can use blocks with the preceding statements, such as the main function declaration (and other statements we've not yet covered), but you can also use blocks by themselves.

Whitespace refers to the tab, space and newline characters that separate the text characters that make up the source code.
Like many things in life, it's hard to appreciate whitespace until it's gone. To a C compiler, the source code

    printf("Hello world"); return 0;

is the same as

    printf("Hello world");
    return 0;

which is also the same as

    printf (
    "Hello world") ;



    return 0;

The compiler simply ignores most whitespace (except, for example, when it separates return from 0). However, it is common practice to use spaces (or tabs) to organize source code for human readability.

Most of the time we do not want other functions or other programmer's routines accessing data we are currently manipulating, which is why it is important to understand the concept of scope.

Scope describes the level at which a piece of data or a function is visible. There are two types of scope in C, local and global. When we speak of global scope, we're referring to something that can be seen or manipulated from anywhere in the program. Local scope applies to a program element that can be seen or manipulated only within the block in which it was declared.

Let's look at some examples to get a better idea of scope.

int i = 5; /* this is a 'global' variable, it can be accessed from anywhere in the program */

/* this is a function, all variables inside of it
    are "local" to the function. */
int main(void)
{
    int i = 6; /* "local" 'i' is set to 6 */
    printf("%d\n", i); /* prints a '6' to the screen, instead of the global variable of 'i', which is 5 */

    return 0;
}

That shows an example of local and global. But what about different scopes inside of functions?
(you'll learn more about functions later, for now, just focus on the "main" part.)

/* the main function */
int main(void)
{
    /* this is the beginning of a 'block', you read about those above */

    int i = 6; /* this is the first variable of this 'block', 'i' */

    {
        /* this is a new 'block', and because it's a different block, it has its own scope */

        /* this is also a variable called 'i', but in a different 'block',
            because it's in a different 'block' than the first variable named 'i', it doesn't affect the first one! */
        int i = 5;
        printf("%d\n", i); /* prints a '5' onto the screen */
    }
    /* now we're back into the first block */

    printf("%d\n", i); /* prints a '6' onto the screen */

    return 0;
}

Basics of Using Functions

Functions are a big part of programming. A function is a special kind of block that performs a well-defined task. If a function is well-designed, it can enable a programmer to perform a task without knowing anything about how the function works. The act of requesting a function to perform its task is called a function call. Many functions require a function call to hand it certain pieces of data needed to perform its task; these are called arguments. Many functions also return a value to the function call when they're finished; this is called a return value (the return value in the above program is 0).

The things you need to know before calling a function are:

  • What the function does
  • The data type (discussed later) of the arguments and what they mean
  • The data type of the return value and what it means

Many functions use the return value for the result of a computation. Some functions use the return value to indicate whether they successfully completed their work. As you have seen in the intro exercise, the main function uses a return value to provide an exit status to the operating system.

All code other than global data definitions and declarations needs to be a part of a function.

Usually, you're free to call a function whenever you wish to. The only restriction is that every executable program needs to have one, and only one, main function, which is where the program begins executing.

We will discuss functions in more detail in a later chapter, C Programming/Procedures and functions.

The Standard Library

In 1983, when C was in the process of becoming standardized, the American National Standards Institute (ANSI) formed a committee to establish a standard specification of C known as "ANSI C". That standard specification created a basic set of functions common to each implementation of C, which is referred to as the Standard Library. The Standard Library provides functions for tasks such as input/output, string manipulation, mathematics, files, and memory allocation. The Standard Library does not provide functions that are dependent on specific hardware or operating systems, like graphics, sound, or networking. In the "Hello, World" program, a Standard Library function is used (printf) which outputs lines of text to the standard output stream.