| Chapter 4 - ASSIGNMENT & LOGICAL COMPARES |  |  |  |
Throughout this chapter, references are given to various ranges of variables.
This refers to the range of values that can be stored in any given variable.
Your compiler may use a different range for some of the variables since
the ANSI standard does not define specific limits for all data types. Consult
the documentation for your compiler for the exact range of each of the
variable types.
INTEGER ASSIGNMENT STATEMENTS
Example program ------> INTASIGN.C
Load the file named INTASIGN.C and display it for an example of assignment
statements. Three variables are defined for use in the program and the
remainder of the program is merely a series of illustrations of various
kinds of assignment statements. All three variables are defined on one
line and have unknown values stored in them initially.
The first two lines of the assignment statements, lines 8 and 10, assign
numerical values to the variables named a and b, and the
next five lines illustrate the five basic arithmetic functions and how
to use them. The fifth is the modulo operator and gives the remainder if
the two variables were divided. It can only be applied to integral type
variables, which will be defined later. Lines 15 and 16 illustrate how
to combine some of the variables in relatively complex math expressions.
All of the above examples should require no comment except to say that
none of the equations are meant to be particularly useful except as illustrations.
Precedence of operators is a very important topic that you will need
to study in detail at some point, but for now we will only need a few rules.
When you have mixed arithmetic expressions, the multiplication and division
operations are completed before the addition and subtraction operations
when they are all at the same logical level. Therefore when evaluating
a * b + c / d, the multiplication and division are done first, then
the addition is performed. However in the expression a * (b + c / d),
the addition follows the division, but preceeds the multiplication because
the operations are at two different logical levels as defined by the parentheses.
The expressions in lines 17 and 18 are perfectly acceptable as given,
but we will see later in this chapter that there is another way to write
these for more compact code.
VERY STRANGE LOOKING CODE
This brings us to lines 20 and 21 which may appear to you as being very
strange. The C compiler scans the assignment statement from right to left,
(which may seem a bit odd since we do not read that way), resulting in
a very useful construct, namely the one given here. The compiler finds
the value 20, assigns it to c, then continues to the left finding
that the latest result of a calculation should be assigned to b.
Thinking that the latest calculation resulted in a 20, it assigns that
value to b also, and continues the leftward scan assigning the value
20 to a also. This is a very useful construct when you are initializing
a group of variables. The statement in line 21 illustrates that it is possible
to actually do some calculations to arrive at the value which will be assigned
to all three variables. The values of a, b, and c,
prior to the beginning of the statement in line 21 are used to calculate
a value, which is then assigned to each of the three variables.
As an aid to understanding, line 23 is given which contains parentheses
to group the terms together in a meaningful way. Lines 20 and 23 are identical
statements.
The program has no output, so compiling and executing this program will
be very uninteresting. Since you have already learned how to display some
integer results using the printf() function, it would be to your
advantage to add some output statements to this program to see if the various
statements do what you think they should do. You will need to add #include
<stdio.h> to the beginning of the program if you are going to add
printf() statements to the program.
You can add your own assignment statements also to gain experience with
them.
DEFINITIONS FIRST THEN EXECUTABLE STATEMENTS
This would be a good time for a preliminary definition of a rule to
be followed in C. The variable definitions are always given before any
executable statements in any program block. This is why the variables are
defined at the beginning of a block in this program and in every C program.
If you try to define a new variable after some executable statements, your
compiler will issue an error. A program block is any unit of one or more
statements surrounded by braces. Actually, the block can even be empty
but then there is no real need for it, except as a placeholder in early
phases of code development. More will be said about blocks later.
ADDITIONAL DATA TYPES
Example program ------> MORTYPES.C
Loading and editing MORTYPES.C will illustrate how some additional data
types can be used. Once again we have defined a few integer type variables
which you should be fairly familiar with by now, but we have added two
new types, the char, and the float.
The char type of data is nearly the same as the integer except
that it can only be assigned numerical values between -128 and 127 on most
microcomputer implementations of C, since it is usually stored in one byte
of memory. Some implementations of C use a larger memory element for a
char and will therefore cover a wider range of usable values. The
char type of data is usually used for ASCII data, more commonly
known as text. The text you are reading was originally written on a computer
with a word processor that stored the words in the computer one character
per byte. In contrast, the int data type is stored in two bytes
of computer memory on nearly all microcomputers, but can be larger on some
machines. In fact, most modern microcomputers are 32 bit machines that
store an int in four bytes.
Keep in mind that, even though the char type variable was designed
to hold a representation of an ASCII character, it can be used very effectively
to store a very small value if desired. Much more will be discussed on
this topic in chapter 7 when we discuss strings.
DATA TYPE MIXING
It would be profitable at this time to discuss the way C handles the
two types char and int. Most operations in C that are designed
to operate with integer type variables will work equally well with character
type variables because they are an integral variable, which means that
they have no fractional part. Those operations, when called on to use a
char type variable, will actually promote the char data into
integer data before using it. For this reason, it is possible to mix char
and int type variables in nearly any way you desire. The compiler
will not get confused, but you might. It is good not to rely on this too
much, but to carefully use only the proper types of data where they should
be used.
The second new data type is the float type of data, commonly
called floating point data. This is a data type which usually has a very
large range, a relatively large number of significant digits, and a large
number of computer words are required to store it. The float data
type has a decimal point associated with it and several bytes of memory
are required to store a single float type variable.
HOW TO USE THE NEW DATA TYPES
The first three lines of the program assign values to all nine of the
defined variables so we can manipulate some of the data between the different
types.
Since, as mentioned above, a char data type is in reality an
integral data type which is automatically promoted to int when necessary,
no special considerations need be taken to promote a char to an
int, and a char type data field can be assigned to an int
variable. When going the other way, an int type variable can
be assigned to a char type variable and will translate correctly
to a char type variable if the value is within the range of the
char, possibly -128 to 127. If the value is outside of the range
of char, most C compilers simply truncate the most significant bits
and use the least significant bits.
Line 16 illustrates the simplicity of translating an int into
a float. Simply assign it the new value and the system will do the
proper conversion. When converting from float to int however,
there is an added complication. Since there may be a fractional part of
the floating point number, the system must decide what to do with it. By
definition, it will truncate it and throw away the fractional part.
This program produces no output, and we haven't covered a way to print
out char and float type variables, so you can't really get
in to this program and play with the results. The next program will cover
these topics for you.
Be sure to compile and run this program after you are sure you understand
it completely. Note that the compiler may issue warnings about type conversions
when compiling this program. They can be ignored because of the small values
we are using to illustrate the various type conversions.
SOME TYPICAL SIZES
This list gives you some typical values for the various types available
in C. Your compiler may offer different limits and sizes since there is
a lot of latitude in what a compiler may offer. The values in this list
are for Microsoft Visual C++ version 1.5 (16 bits) and Visual C++ version
2.0 (32 bits).
Type Name Bytes Range
------------- 16 bit system -------------
char 1 -128 to 127
signed char 1 -128 to 127
unsigned char 1 0 to 255
short 2 -32,768 to 32,767
unsigned short 2 0 to 65,535
int 2 -32,768 to 32,767
unsigned int 2 0 to 65,535
long 4 -2,147,483,648 to 2,147,483,647
unsigned long 4 0 to 4,294,967,295
float 4 3.4E+/-38 (7 digits)
double 8 1.7E+/-308 (15 digits)
long double 10 1.2E+/-4932 (19 digits)
------------- 32 bit system -------------
char 1 -128 to 127
signed char 1 -128 to 127
unsigned char 1 0 to 255
short 2 -32,768 to 32,767
unsigned short 2 0 to 65,535
int 4 -2,147,483,648 to 2,147,483,647
unsigned int 4 0 to 4,294,967,295
long 4 -2,147,483,648 to 2,147,483,647
unsigned long 4 0 to 4,294,967,295
float 4 3.4E+/-38 (7 digits)
double 8 1.7E+/-308 (15 digits)
long double 10 1.2E+/-4932 (19 digits)
The diligent student will notice that the only difference in these two
lists are in the sizes and ranges of the
int type variables, both
signed and unsigned. The ANSI-C standard says that an
int type has
the "natural size suggested by the architecture of the execution environment",
so the ranges for the compiler listed above matches the standard exactly.
One other point about the above table must be made at this time. The
unadorned char is permitted to be either signed or unsigned at the
discretion of the compiler writer. The writers of the Microsoft compiler
chose to make char default to a signed char, as do most compiler
writers, but you have a choice since most compilers provide a switch to
select the default to unsigned char.
Some useful constants are available for your use in determining the
range limits of the standard types. For example, the names INT_MIN and
INT_MAX are available in the file "limits.h" as constants which can be
used in your code. INT_MAX is the largest possible number that can be stored
in an int type variable using the compiler that you are currently
using. When you switch to a new compiler, which you will almost certainly
do someday, INT_MAX will refer to the largest value that can be stored
with that compiler. Even if you switch to a new operating system with 64
bits or even 128 bits, INT_MAX will still refer to the largest int available
on your new system. The file "limits.h" contains a large number of such
limits, all of which are available for your use simply by including the
file in your program. It is a text file which can be opened in any editor
and studied, a highly recommended exercise for you at this time.
LOTS OF VARIABLE TYPES
Example program ------> LOTTYPES.C
Load the file LOTTYPES.C and display it on your screen. This file contains
most of the standard simple data types available in the programming language
C. Consult your compiler documentaion for a complete list of all types
avialable with your compiler. There are other types, but they are the compound
types (ie - arrays and structures) that we will cover in due time in this
tutorial.
Observe the file. First we define a simple int, followed by a
long int . Next we have a short int which has a range that
may be identical to that for the int variable. The unsigned is
next and is defined as the same size as the int but with no sign.
It should be pointed out that when the long, short, or unsigned
is desired, the int is optional and is left out by most experienced
programmers. Your compiler may differ significantly from the ranges given
in the above table, so you should check the documentation for your compiler
for the exact ranges for each type.
The double is a floating point number but covers a greater range
than the float and has more significant digits for more precise
calculations. It also requires more memory to store a value than the simple
float. The long double will cover a much larger range and
store more significant digits, but it will also take longer to do calculations
because of the increased size of data being used.
Another diversion is in order at this point. Your compiler probably
has no provision for floating point math, only double floating point
math. It will promote a float to a double before doing calculations
and therefore only one math library will be needed. Of course, this is
transparent to you, so you don't need to worry about it. Because of this,
you may think that it would be best to simply define every floating point
variable as double, since they are promoted before use in any calculations,
but that may not be a good idea. A float variable may require only
4 bytes of storage and a double may require 8 bytes of storage,
so if you have a large volume of floating point data to store, the double
will obviously require much more memory. If you don't need the additional
range or significant digits, you should use the float type rather
than the double. The compiler makes all floating point literals,
such as the value 3.14159 in line 19, double constants by default.
Some compilers will then issue a warning about line 19 because we are assigning
a double to a float. You can safely ignore the warning at
this time.
After defining the data types in the program under consideration, a
numerical value is assigned to each of the defined variables in order to
demonstrate the means of outputting each to the monitor.
SOME LATE ADDITIONS
As any programming language evolves, additional constructs are added
to fill some previously overlooked need. Two new keywords have been added
to C with the release of the ANSI-C standard. They are not illustrated
in example programs, but they will be discussed here. The two new keywords
are const and volatile and are used to tell the compiler
that variables of these types will need special consideration. A constant
is declared with the const keyword and declares a value that cannot
be changed by the program. If you inadvertently try to modify an entity
defined as a const, the compiler will generate an error. This is
an indication to you that something is wrong. Declaring an entity as const
allows the optimizer to do a better job which could make your program
run a little faster. Since constants can never have a value assigned to
them in the executable part of the program, they must always be initialized.
If volatile is used, it declares a value that may be changed by
the program but it may also be changed by some outside influence such as
a clock update pulse incrementing the stored value. This prevents the optimizer
from getting too ambitious and optimizing away something that it thinks
will never be changed.
Examples of use in declaring constants of these two types are given
as;
const int index1 = 2;
const index2 = 6;
const float big_value = 126.4;
volatile const int index3 = 12;
volatile int index4;
THE CONVERSION CHARACTERS
Following is a list of some of the conversion characters and the way
they are used in the printf() statement. A complete list of all
of the conversion characters should be included with the documentation
for your compiler. You do not need to understand all of these at this time,
but you should know that there is a lot of flexibility available when you
are ready to use it.
d decimal notation
i decimal notation (new ANSI standard extension)
o octal notation
x hexadecimal notation
u unsigned notation
c character notation
s string notation
f floating point notation
Each of these is used following a percent sign to indicate the type of
output conversion desired. The following fields may be added between those
two characters.
- left justification in its field
(n) a number specifying minimum field width
. to separate n from m
(m) significant fractional digits for a float
l to indicate a long
These are all used in the examples which are included in the program named
LOTTYPES.C, with the exception of the string notation which will be covered
later in this tutorial. Lines 33 through 35 illustrate how to set the field
width to a desired width, and lines 39 and 40 illustrate how to set the
field width under program control. The field width for the float type output
in lines 43 through 47 should be self explanatory. Compile and run this
program to see what effect the various fields have on the output.
You now have the ability to display any of the data fields in the previous
programs and it would be to your advantage to go back and see if you can
display some of the fields anyway you desire.
COMBINING THE VARIOUS TYPES
Example program ------> COMBINE.C
Examine the file named COMBINE.C for examples of combining variables
of the various types in a program. Many times it is necessary to multiply
an int type variable times a float type variable and C allows
this by providing a strict set of rules it will follow in order to do such
combinations.
Five variables of three different types are declared in lines 4 through
6, and three of them are initialized so we have some data to work with.
Line 8 gives an example of adding an int variable to a float
variable and assigning the result to a char type variable. The
cast is used to control the type of addition and is indicated by defining
the desired type within parentheses in front of the variable as shown.
This forces each of the two variables to the char type prior to
doing the addition. In some cases, when the cast is used, the actual bit
patterns must be modified internally in order to do the type coercion.
Lines 9 through 11 perform the same addition by using different kinds of
type casting to achieve the final result. Note that the addition is not
the same in all three cases because the addition is done using different
types, so could conceivably result in different answers.
Lines 13 through 15 illustrate the use of the cast to multiply two float
variables. In two of the cases the intermediate results are cast to
the int type, with the result being cast back to the float type.
The observant student will notice that these three lines will not necessarily
produce the same result.
Be sure to compile and execute this program. When you do, you may get
a lot of type conversion warnings which can be ignored at this point. In
this program, we are illustrating things that can be done with no regard
to whether it is good to do so in a production program. Note that all of
the warnings can be eliminated by including the proper cast when we use
different types.
LOGICAL COMPARES
Example program ------> COMPARES.C
Load and view the file named COMPARES.C for many examples of compare
statements in C. We begin by defining and initializing nine variables to
use in the following compare statements.
The first group of compare statements represents the simplest kinds
of compares because they simply compare two variables. Either variable
could be replaced with a constant and still be a valid compare, but using
two variables for the compare is the general case. The first compare checks
to see if the value of x is equal to the value of y and it
uses the double equal sign for the comparison. Since x is equal
to y, the variable z will be assigned the value of -13. A
single equal sign could be used here but it would have a different meaning
as we will see shortly. The second comparison checks to see if the current
value of x is greater than the current value of z.
The third compare introduces the not operator, the exclamation, which
can be used to invert the result of any logical compare. The fourth checks
for the value of b less than or equal to the value of c,
and the last checks for the value of r not equal to the value of
s. As we learned in the last chapter, if the result of the compare
is true, the statement following the if clause will be executed
and the results are given in the comments.
Note that "less than" and "greater than or equal to" are also available,
but are not illustrated here.
It would be well to mention the different format used for the if
statement in this example program. A carriage return is not required
as a statement separator and by putting the conditional clause on the same
line as the if, it adds to the readability of the overall program
in this case.
MORE COMPARES
The compares in the second group are a bit more involved. Starting with
the first compare, we find a rather strange looking set of conditions in
the parentheses. To understand this we must understand just what a true
or false is in the C language. A false is defined as a value of zero, and
true is defined as any non-zero value. Any integer or character type of
variable can be used for the result of a true/false test, or the result
can be an implied integer or character.
Look at the first compare of the second group of compare statements.
The conditional expression "r != s" will evaluate as a true since
the value of r was set to 0.0 in line 13, so the result of the compare
will be a non-zero value. With all ANSI-C compilers, it will be set to
a 1. Good programming practice would be to not use the resulting 1 in any
calculations, but only for logical control. Even though the two variables
that are compared are float variables, the logical result will be
of type int. There is no explicit variable to which it will be assigned
so the result of the compare is an implied int. Finally, the resulting
number, is assigned to the integer variable x. If double equal signs
were used, the phantom value, namely 1, would be compared to the value
of x, but since the single equal sign is used, the value 1 is simply
assigned to the variable named x, as though the statement were not
in parentheses. Finally, since the result of the assignment in the parentheses
was non-zero, the entire expression is evaluated as true, and z is
assigned the value of 1000. Thus we accomplished two things in this statement,
we assigned x a new value, and we assigned z the value of
1000. We covered a lot in this statement so you may wish to review it before
going on. The important things to remember are the values that define true
and false, and the fact that several things can be assigned in a conditional
statement. The value assigned to the variable x was probably a 1,
but remember that the only requirement is that it is nonzero. The ANSI-C
standard says that the result of a comparison operation, ( >, >=, <,
or <=) must be 1 or 0, but does not state the result of an equality
operation. If you assume 0 or 1 will be returned, and only use it for control,
you will not get into trouble.
The example in line 20 should help clear up some of the above in your
mind. In this example, x is assigned the value of y, and
since the result is 11, the condition is non-zero, which is true, and the
variable z is assigned 222.
The third example of the second group in line 21, compares the value
of x to zero. If the result is true, meaning that if x is
not zero, then z is assigned the value of 333, which it will be.
The last example in this group illustrates the same concept, since the
result will be true if x is non-zero. The compare to zero in line
21 is not actually needed and the result of the compare is true. The third
and fourth examples of this group are therefore logically identical. Of
course we assign a different value to z in each case.
ADDITIONAL COMPARE CONCEPTS
The third group of compares will introduce some additional concepts,
namely the logical "and" and the logical "or" operators. We assign the
value of 77 to the three integer variables simply to get started again
with some defined values. The first compare of the third group contains
the new control &&, which is the logical "and" which results in
a true if both sides of the "and" are true. The entire statement reads,
if x equals y and if x equals 77 then the result is
true. Since this is true, the variable z is set equal to 33. Note
that only integral types can be "anded", so float and double
types cannot be used here.
The next compare in this group introduces the || operator which is the
logical "or" operator which results in a true if either side of the "or"
is true. The statement reads, if x is greater than y or if
z is greater than 12 then the result is true. Since z is
greater than 12, it doesn't matter if x is greater than y,
because only one of the two conditions must be true for the result to be
true. The result is true, therefore z will be assigned the value
of 22. Once again, float and double cannot be "ored".
LOGICAL EVALUATION (SHORT CIRCUIT)
When a compound expression is evaluated, the evaluation proceeds from
left to right and as soon as the result of the outcome is assured, evaluation
stops. Therefore, in the case of an "and" evaluation, when one of the terms
evaluates to false, evaluation is discontinued because additional true
terms cannot make the result ever become true. In the case of an "or" evaluation,
if any of the terms is found to be true, evaluation stops because it will
be impossible for additional terms to cause the result to be false. In
the case of additionally nested terms, the above rules will be applied
to each of the nested levels. This is called short-circuit evaluation since
the remaining terms are not evaluated.
Going on to the next example in group three in line 29, we find three
simple variables used in the conditional part of the compare. Since all
three are non-zero, all three are true, and therefore the "and" of the
three variables is true, leading to the result being true, and z is
assigned the value of 11. Note that since the variables, r, s,
and t are float type variables, they could not be used this
way.
Continuing on to line 30 we find three assignment statements in the
compare part of the if statement. If you understood the above discussion,
you should have no difficulty understanding that the three variables are
assigned their respective new values, and the result of all three are non-zero,
leading to a resulting value of true.
THIS IS A TRICK, BE CAREFUL
The last example of the third group contains a bit of a trick, but since
we have covered it above, it is nothing new to you. Notice that the first
part of the compare evaluates to false since x is not currently
2. The remaining parts of the compare are not evaluated, because it is
a logical "and" so it will definitely be resolved as a false because the
first term is false. If the program was dependent on the value of y
being set to 3 in the next part of the compare, it will fail because
evaluation will cease following the false found in the first term. Likewise,
the variable named z will not be set to 4, and the variable r
will not be changed. This is because C uses short circuit evaluation
as discussed earlier.
POTENTIAL PROBLEM AREAS
The last group of compares illustrate three possibilities for getting
into a bit of trouble. All three have the common result that the variable
z will not be handled properly, but for different reasons. In line
37, the compare evaluates as true, but the semicolon following the second
parentheses terminates the if clause, and the assignment statement
involving z is always executed as the next statement. The if
therefore has no effect because of the misplaced semicolon. This is
actually a null statement and is legal in C, but the programmer probably
did not intend to include the extra semicolon.
The statement in line 38 is much more straightforward because the variable
x will always be equal to itself, therefore the inequality will
never be true, and the entire statement will never do a thing, but is wasted
effort. The statement in line 39 will always assign 0 to x and the
compare will therefore always be false, never executing the conditional
part of the if statement.
The conditional statement is extremely important and must be thoroughly
understood to write efficient C programs. If any part of this discussion
is unclear in your mind, restudy it until you are confident that you understand
it thoroughly before proceeding onward. Compile and run this program. You
may gets lots of conversion warnings which you can either ignore or fix
up the code with casts to eliminate. Add some printout to see the results
of some of the operations.
THE CRYPTIC PART OF C
Example program ------> CRYPTIC.C
There are three constructs used in C that make no sense at all when
first encountered because they are not intuitive, but they may increase
the efficiency of the compiled code and are used extensively by experienced
C programmers. You should therefore be exposed to them and learn to use
them because they will appear in most, if not all, of the programs you
see in the publications. Load and examine the file named CRYPTIC.C for
examples of the three new constructs.
In this program, some variables are defined and initialized in the same
statements for use later. The statement in line 8 simply adds 1 to the
value of x, and should come as no surprise to you. The next two
statements also add one to the value of x, but it is not intuitive
that this is what happens. It is simply by definition that this is true.
Therefore, by definition of the C language, a double plus sign either before
or after a variable increments that variable by 1. Additionally, if the
plus signs are before the variable, the variable is incremented before
it is used, and if the plus signs are after the variable, the variable
is used, then incremented. In line 11, the value of y is assigned
to the variable z, then y is incremented because the plus
signs are after the variable y. In the last statement of the incrementing
group of example statements, line 12, the value of y is incremented
then its value is assigned to the variable z. To use the proper
terminology, line 9 uses the postincrement operator and line 10 uses the
preincrement operator.
The next group of statements illustrate decrementing a variable by one.
The definition works exactly the same way for decrementing as it does for
incrementing. If the minus signs are before the variable, the variable
is decremented, then used, and if the minus signs are after the variable,
the variable is used, then decremented. The proper terminology is the postdecrement
operator and the predecrement operator.
You will use this construct a lot in your C programs.
THE CRYPTIC ARITHMETIC OPERATOR
Another useful but cryptic operator is the arithmetic operator. This
operator is used to modify any variable by some constant value. The statement
in line 23 adds 12 to the value of the variable a. The statement
in line 24 does the same, but once again, it is not intuitive that they
are the same. Any of the four basic functions of arithmetic, +, -, *, or
/, can be handled in this way, by putting the operation desired in front
of the equal sign and eliminating the second reference to the variable
name. It should be noted that the expression on the right side of the arithmetic
operator can be any valid expression, the examples are kept simple for
your introduction to this new operator.
Just like the incrementing and decrementing operators, the arithmetic
operator is used extensively by experienced C programmers and it would
pay you well to understand it thoroughly.
THE CONDITIONAL EXPRESSION
The conditional expression is just as cryptic as the last two, but once
again it is very useful so it would pay you to understand it. It consists
of three expressions separated by a question mark and a colon. The expression
prior to the question mark is evaluated to determine if it is true or false.
If it is true, the expression between the question mark and the colon is
evaluated, and if the compare expression is not true, the expression following
the colon is evaluated. The result of one of the evaluations is used for
the assignment as illustrated in line 30. The final result is identical
to that of an if statement with an else clause. This is illustrated
by the example in lines 32 through 35 of this group of statements. The
conditional expression has the advantage of more compact code that may
compile to fewer machine instructions in the final program.
Lines 37 and 38 of this example program are given to illustrate a very
compact way to assign the greater of the two variables a or b
to the variable c, and to assign the lessor of the same two
variables to the variable c. Notice how efficient the code is in
these two examples.
TO BE CRYPTIC OR NOT TO BE CRYPTIC
Several students of C have stated that they didn't like these three
cryptic constructs and that they would simply never use them. This would
be fine if they never have to read anybody else's program, or use any other
programs within their own. You will find many functions that you wish to
use within a program but need a small modification to use it, requiring
you to understand another person's code. It would therefore be to your
advantage to learn these new constructs, and use them. They will be used
in the remainder of this tutorial, so you will be exposed to them.
This has been a long chapter but it contained important material to
get you started in using C. In the next chapter, we will go on to the building
blocks of C, the functions. At that point, you will have enough of the
basic materials to allow you to begin writing meaningful programs.
STYLE ISSUES
We have no specific issues of style in this chapter other than some
of the coding styles illustrated in the example programs. Most of these
programs are very nontypical of real C programs because there is never
a need to list all of the possible compares in a real program, for example.
You can use the example programs as a guide to good style even though they
are not real programs.
WHAT IS AN l-value AND AN r-value?
You will sometimes see a reference to an l-value or a r-value in writings
about C or in the documentation for your C compiler. Every variable has
an r-value which is defined as the actual value stored in the variable,
and it also has an l-value which is defined as the name of the variable.
Therefore, the variable depicted graphically in figure 4-1 has an l-value
of index, and an r-value of 137 since 137 is the value stored in
the variable at this time.
The definition for this variable would be given as follows;
int index = 137;
PROGRAMMING EXERCISES
-
Write a program that will count from 1 to 12 and print the count, and its
square, for each count.
-
Write a program that counts from 1 to 12 and prints the count and its inversion
to 5 decimal places for each count. This will require a floating point
number.
-
Write a program that will count from 1 to 100 and print only those values
between 32 and 39, one to a line. Use the incrementing operator for this
program.