Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 54

Computer Fundamentals Concept

Computer Fundamentals
Go Ahead And Update Your I.T Skills

Glossary
Overview of Computer System
Computer Components

Overview of Computer System


All physical parts of the computer (or everything that we can touch) is known as
hardware.In general, computers are used to simplify mathematical and scientific
principles. This process similar to how probabilities are used to know the odds of
winning in a game of like free poker. Want to more about computers?. All of the
components of a computer system can be summarised with the simple equations
below...

Software gives "intelligence" to the computer.

Basically all computers, regardless of their size, have the same general design which
consist of the following units: the CPU , memory, and input/output circuitry which
are situated on the printed circuit board, also called the system board or
motherboard (figure of a motherboard).
Figure 2. This diagram describes the relationships between the components of the
computer system
The microprocessor is an integrated circuit that contains transistors, diodes,
resistors, and other components interconnected to form the electronic circuit. The
circuit is mounted in a metal or plastic package and connections are welded to
external pins. The circuit can be accessed only through these pins. This design
produces the following benefits:

a reduction in size, cost, and power consumption; an increase in operating speed; a


higher reliability

Large computer systems can have many processors, so they are called
multiprocessor systems. The microcomputer is a system with a single processor that
fits on a single chip. This processor is called a microprocessor

The RAM and ROM chips provide memory to the computer. One of the most
important characteristics of memory is the amount of information it can hold.

The input/output(I/O) devices are external devices (in relation to the CPU) that are
connected to the computer to provide means of the communication between the user
and the computer.

Disks (floppy, hard, or optical) and tapes are used to store information for long
periods of time.

Peripheral devices are connected to the computer through ports, or sockets, that are
mounted outside. Some peripherals (e.g. disk drives) are located inside the computer
case, so they are connected via expansion slots.
a). The back of the computer showing the ports and sockets

a.)Expansion Slot

Figure 3. How peripheral devices are connected to the computer


COMPUTER COMPONENTS
Common Components
The good news is that all computers have certain common components. What makes
each one different are the specifications of the components, the amount and type of
memory installed, the hard drive capacity, and the additional components installed,
which you decide on, that enhance the function of the computer. Every computer
must have a few essential components.

Main Components
The three main components of a personal computer:
The System Unit

The system unit is the entire computer as a whole. This includes the case and all the
hardware that is installed inside. The rest of these pages will cover what is contained
in the system unit.Powerful electronic circuitry that makes up the computer is
housed inside the case. The case can be opened by unscrewing the case screws and
sliding off the cover. To avoid , the computer must be unplugged from the electrical
outlet. Most system units consist of the computer case with a power supply,
motherboard, memory (RAM), hard drive, floppy disk drive, CD-ROM drive, disk
controller, input/output ports, video adapter, and sound board. The variation of the
components inside the system unit is what makes one personal computer more
powerful than another personal computer.
About Operating System.......

Download windows E-books and make your skills better Download windwos E-
books..click here!

Operating Systems and Basics


OS is system software, which may be viewed as collection of software consisting of
procedures for operating the computer & providing an environment for execution of
programs. It’s an interface between user & computer

Types of Processing:
1. Serial Processing
2. Batch Processing
3. Multiprogramming.

Types of OSs:
1. Batch OS
2. Multiprogramming OS

         Ø Multitasking/Multiprocessing
         Ø Multiuser OS
         Ø Time Sharing OS
         Ø Real Time OS

3. Network OS
4. Distributed OS

OS Structure:

1. Layered Structure
2. Kernel Structure
        Ø Create & Delete process
        Ø Processor scheduling, mem mgmt & I/O mgmt.
        Ø Process synchronization.
        Ø IPC help

3. Virtual Machine
4. Client Server model
Process Managment

Process Status: New, ready to run, running, suspended, sleep, wait, terminate.

Types of Scheduler:
1. Long term/Job Scheduler
2. Medium term/
3. Short term/ CPU Scheduler
Processes can be either CPU bound or I/O bound. Scheduling performance criteria:

CPU utilisation

        Throughput
        Turnaround time
        Waiting time
        Response Time
Scheduling Algorithms:

Preemptive
        First-come-first served

Non-Preemptive
        Shortest-job-first
        Round Robin.
        Priority based scheduling
        Multi-level Queue
Processing the interrupt to switch the CPU to another process requires saving all the
registers for the old process & then loading the registers for new process is known as
Context Switching.
Synchronization & IPC

The shared storage may be in main memory or it may be a shared file. Each process has a
segment of code, critical Section, which accessed shared memory or files. Some way of
making sure that if one process is executing in its critical section, other process will be
excluded from doing the same thing is known as Mutual Exclusion. Hardware support is
available for mutual exclusion called “Test & set instruction”, it is designed to allow only
one process among several concurrent processes to enter in its critical section.
Semaphore: It’s a synchronization tool, it’s a variable which accepts non-negative integer
values and except for initialization may be accessed and manipulated through two
primitive functions wait() & signal().
Disadvantages :

1. Semaphores are unstructured.


2. Semaphores do not support data abstraction.

Alternative to Semaphores:
1. Critical region
2. Conditional critical region
3. Monitors
4. Message Passing

Reason for Deadlock:

1. Mutual exclusion
2. Hold & wait
3. No preemption
4. Circular condition
Memory Management

In a single process, system memory is protected through hardware mechanism such as


dedicated register called Fence register. In a multi programming, memory can be
allocated either Statically or Dynamically. Partition information is stored in partition
Description Table. Two strategies are used to allocate memory to ready process are First
Fit & Best Fit. Loading program into memory by relocating load or linker in a static
allocation is known as Static relocation. In Dynamic method, run time mapping of virtual
address into physical address with support of some hardware mechanism such as base
register & limit registers. Protection is served by using Limit registers to restrict the
program to access memory location, sharing is achieved by using dedicated common
partition. Static allocation does not support data structures like stack & queues. It limits
degree of multi programming. Compaction is a process of collecting free space in to a
single large memory chunk to fit the available process. It is not done, bcoz it occupies lot
of CPU time. It is only supported in Mianframe & SuperComputers Paging is a memory
management technique that permits a program’s memory to be non-contiguous into
physical memory, thus allowing a program to be allocated physical memory whenever is
required. This is done by Virtual Address, later these address are converted to physical
address. Memory is divided into number of fixed size blocks called Frames. The virtual
address space or logical memory of a process is also broken into blocks of the same size
called pages. When a program is to be run, its pages are loaded into any frame from the
disk. Mapping is done thru Page Map Table which contains the base address of each page
in physical memory. Hardware support is given to paging using Page Map Table Register
(PMRT) which will be pointing to beginning of the PMT. Look side memory or Content
addressable memory is used to overcome the problem of PMT. Address translation is
done by Associative Memory which will convert virtual to physical address by page &
offset values by looking into PMT. Segmentation is Memory management scheme its
sophisticated form Address translation. It is done by Segment table, which is a important
component in segmented system. Segment accessing supported by Segment Table Base
register (STBR). Protection is enforced by Segment table Limit register (STLR). Virtual
memory is memory management technique which splits the process into small chunks
called Overlay. First overlay will can next overlay before quitting the CPU, the remaining
overlays will be on Hard disk, the swapping is done by OS. Advantages:

1.         What ever the size program, memory can be allocated easily.
2.          Since the swapping is done between main & secondary memory, the CPU
utilization & throughput will be increased.
3.         It reduces the external fragmentation & Increases the program execution speed. In
Demand paging, pages are loaded only on demand, not in advance, its same as paging
with swapping feature. Page fault occurs due to missing of page in the main memory, it
means that the program is referring the address of the page which is not brought into
memory
File Management

Some systems support a single uniform set of file manipulation features for both file &
I/O device management, this feature is known as Device Independent I/O or Device
Independence. Printer is a one of a such example.

File organization may be

1.         Byte Sequenced in which OS does not impose any structure on the file
organization.
2.         Record Sequenced, it’s a sequence of fixed sized records, arbitrary records read or
written, but records can’t be inserted or deleted in middle of the file.
3.        ISAM files are inserted in disc blocks which will have keys to inserted, its look
like a tree of blocks.,

Responsibility of File Management.

1. Mapping of logical file address to physical disk address


2. Management of disk space & allocation - deallocation.
3. Keeping track of all files in system
4. Support for protection & sharing of files. Method to access the file organized in
hierarchical form. Absolute pathname & relative pathname. File & directory searching is
done using

1. Linear List organization which takes O(n) comparisons to locate a file.


2. Hashing Technique
3. Balanced binary tree which takes O(log n) comparisons to locate file, it always
provides sorted list files which will increase the efficiency. Collection of tracks on all
surfaces that are at the same distance is called a Cylinder.

Disk Space Management Methods:

1. Linked list
2. Bit Map
Disk allocation Methods

1. Contiguous: It supports both Sequential & Direct Accessing. Allocation is done using
First Fit & Best Fit methods.
2. Linked List
Advantages:
        Simple
       No disk Compaction.
Disadvantages

It doesn’t support direct accessing since blocks are scattered over the disk. Slow direct
accessing of any disk block Space requirement for pointers Reliability
3. Indexed Uses Index Block to support direct accessing. Problem with same can be
solved by Multiple Level indexing, indirect blocks, double indirect block.

Advantages
        No external fragmentation
        Efficient random access
        Indexing of free space is done with Bitmap
        Can keep the index of bad blocks.
Disk Scheduling

       1. First come first served (FCFS)


       2. Shortest Seek Time First
       3. Scan Scheduling also called Elevator Algorithm
C: GETTING STARTED

whats special in this section


WHAT IS AN IDENTIFIER?

Before you can do anything in any language, you must know how to name an identifier.
An identifier is used for any variable, function, data definition, etc. In the C programming
language, an identifier is a combination of alphanumeric characters, the first being a letter
of the alphabet or an underline, and the remaining being any letter of the alphabet, any
numeric digit, or the underline.

Two rules must be kept in mind when naming identifiers.

 The case of alphabetic characters is significant. Using INDEX for a variable name
is not the same as using index and neither of them is the same as using InDeX for
a variable name. All three refer to different variables.
 According to the ANSI-C standard, at least 31 significant characters can be used
and will be considered significant by a conforming ANSI-C compiler. If more
than 31 are used, all characters beyond the 31st may be ignored by any given
compiler.

WHAT ABOUT THE UNDERLINE?

The underline can be used as part of a variable name, and adds greatly to the readability
of the resulting code. It is used by some, but not all, experienced C programmers. A few
underlines are used for illustration in this tutorial. Since most compiler writers use the
underline as the first character for variable names internal to the system, you should
refrain from using the underline to begin an identifier to avoid the possibility of a name
clash. To get specific, identifiers with two leading underscores are reserved for the
compiler as well as identifiers beginning with a single underscore and using an upper
case alphabetic character for the second. If you make it a point of style to never use an
identifier with a leading underline, you will not have a naming clash with the system.

It adds greatly to the readability of a program to use descriptive names for variables and it
would be to your advantage to do so. Pascal and Ada programmers tend to use long
descriptive names, but most C programmers tend to use short cryptic names. Most of the
example programs in this tutorial use very short names for that reason, but a few longer
names are used for illustrative purposes.

KEYWORDS

There are 32 words defined as keywords in C. These have predefined uses and cannot be
used for any other purpose in a C program. They are used by the compiler as an aid to
compiling the program. They are always written in lower case. A complete list follows;

       auto      double      int        struct
      break      else        long      switch
      case      enum      register    typedef
      char      extern      return      union
      const      float      short      unsigned
      continue      for      signed      void
      default      goto      sizeof      volatile
        do            if          static      while

In addition to this list of keywords, your compiler may define a few more. If it does, they
will be listed in the documentation that came with your compiler. Each of the above
keywords will be defined, illustrated, and used in this tutorial.

WE NEED DATA AND A PROGRAM

Any computer program has two entities to consider, the data, and the program. They are
highly dependent on one another and careful planning of both will lead to a well planned
and well written program. Unfortunately, it is not possible to study either completely
without a good working knowledge of the other. For that reason, this tutorial will jump
back and forth between teaching methods of program writing and methods of data
definition. Simply follow along and you will have a good understanding of both. Keep in
mind that, even though it seems expedient to sometimes jump right into coding the
program, time spent planning the data structures will be well spent and the quality of the
final program will reflect the original planning.

HOW THIS TUTORIAL IS WRITTEN

As you go through the example programs, you will find that every program is complete.
There are no program fragments that could be confusing. This allows you to see every
requirement that is needed to use any of the features of C as they are presented. Some
tutorials I have seen give very few, and very complex examples. They really serve more
to confuse the student. This tutorial is the complete opposite because it strives to cover
each new aspect of programming in as simple a context as possible.

Throughout this tutorial, keywords, variable names, and function names will be given in
boldface as an aid to clarity. These terms will be completely defined throughout the
tutorial.

HOW THIS TUTORIAL IS WRITTEN

As you go through the example programs, you will find that every program is complete.
There are no program fragments that could be confusing. This allows you to see every
requirement that is needed to use any of the features of C as they are presented. Some
tutorials I have seen give very few, and very complex examples. They really serve more
to confuse the student. This tutorial is the complete opposite because it strives to cover
each new aspect of programming in as simple a context as possible.

Throughout this tutorial, keywords, variable names, and function names will be given in
boldface as an aid to clarity. These terms will be completely defined throughout the
tutorial.

RESULT OF EXECUTION

The result of executing each program will be given in comments at the end of the
program listing after the comment is defined in about the fourth program of chapter 2. If
you feel confident that you completely understand the program, you can simply refer to
the result of execution to see if you understand the result. In this case, it will not be
necessary for you to compile and execute every program. It would be a good exercise for
you to compile and execute some of them however, because all C compilers will not
generate exactly the same results and you need to get familiar with your own compiler.

Example program ------> FIRSTEX.C

At this point, you should compile and execute FIRSTEX.C if you have not yet done so, to
see that your C compiler is properly loaded and operating. Don't worry about what the
program does yet. In due time you will understand it completely.

Note that this program will compile and execute properly with any good compiler.

A WORD ABOUT COMPILERS

All of the example programs in this tutorial will compile and execute correctly with any
good ANSI compatible C compiler. Some compilers have gotten extremely complex and
hard to use for a beginning C programmer, and some only compile and build Microsoft
Windows programs. Fortunately, most of the C compilers available have a means of
compiling a standard C program which is written for the DOS environment and includes
none of the Windows extensions. You should check your documentation for the
capabilities and limitations of your compiler. If you have not yet purchased a C compiler,
you should find one that is ANSI-C compliant, and that also has the ability to generate a
DOS executable if you are planning to use the DOS operating system.

ANSWERS TO PROGRAMMING EXERCISES

There are programming exercises at the end of most of the chapters. You should attempt
to do original work on each of the exercises before referring to the answers in order to
gain your own programming experience. These answers are given for your information in
case you are completely stuck on how to solve a particular problem. These answers are
not meant to be the only answer, since there are many ways to program anything, but they
are meant to illustrate one way to solve the suggested programming problem.

The answers are all in source files named in the format CHnn_m.C where nn is the
chapter number, and m is the exercise number. If more than one answer is required, an A,
B, or C is included following the exercise number.

PROGRAM STRUCTURE

YOUR FIRST C PROGRAM

Example program ------> TRIVIAL.C

The best way to get started with C is to actually study a program, so load the file named
TRIVIAL.C and display it on the monitor. You are looking at the simplest possible C
program. There is no way to simplify this program or to leave anything out.
Unfortunately, the program doesn't do anything.

The word main is very important, and must appear once, and only once in every C
program. This is the point where execution is begun when the program is run. We will
see later that this does not have to be the first statement in the program but it must exist
as the entry point. Following the main program name is a pair of parentheses which are
an indication to the compiler that this is a function. We will cover exactly what a function
is in due time. For now, I suggest that you simply include the pair of parentheses.

The two curly brackets in lines 2 and 3, properly called braces, are used to define the
limits of the program itself. The actual program statements go between the two braces
and in this case, there are no statements because the program does absolutely nothing.
You can compile and run this program, but since it has no executable statements, it does
nothing. Keep in mind, however, that it is a valid C program. When you compile this
program, you may get a warning. You can ignore the warning and we will discuss it later
in this tutorial, or you can modify the program so that it appears as follows;

int main()
{
return 0;
}
This modified program must compile on any good C compiler since it conforms to the
ANSI-C standard. We will explain the difference in these two programs later in this
tutorial.

A PROGRAM THAT DOES SOMETHING

Example program ------> WRTSOME.C

For a much more interesting program, load the program named WRTSOME.C and
display it on your monitor. It is the same as the previous program except that it has one
executable statement between the braces plus the obligatory return statement.

The executable statement is a call to a function supplied as a part of your C library. Once
again, we will not worry about what a function is, but only how to use this one named
printf(). In order to output text to the monitor, the desired text is put within the function
parentheses and bounded by quotation marks. The end result is that whatever text is
included between the quotation marks will be displayed on the monitor when the program
is run.

Notice the semi-colon at the end of line 5. C uses a semi-colon as a statement terminator,
so the semi-colon is required as a signal to the compiler that this line is complete. This
program is also executable, so you can compile and run it to see if it does what you think
it should. It should cause the text between the quotation marks to appear on the monitor
when you execute it.

You can ignore the statements in lines 1 and 7 in this program and similar statements in
each of the remaining programs in this chapter. These will be fully described later in this
tutorial. We will also define why the word int is used at the begining of line 3. We have a
few preliminary topics to cover before we get to these items.

ANOTHER PROGRAM WITH MORE OUTPUT

Example program ------> WRTMORE.C

Load the program WRTMORE.C and display it on your monitor for an example with
more output and another small but important concept. You will see that there are four
executable statements in this program, each one being a call to the function printf(). The
top line will be executed first, then the next, and so on, until the fourth line is complete.
The statements are executed sequentially from top to bottom.

Notice the funny character near the end of the first line, namely the backslash. The
backslash is used in the printf() statement to indicate that a special control character is
following. In this case, the "n" indicates that a newline is requested. This is an indication
to return the cursor to the left side of the monitor and move down one line. Any place
within printed text that you desire, you can put a newline character to start a new line.
You could even put it in the middle of a word and split the word between two lines.

A complete description of this program is now possible. The first printf() outputs a line of
text and returns the carriage. (Of course, there is no carriage, but the cursor is moved to
the next line on the monitor. The terminology carries over from the days of teletypes.)
The second printf() outputs a line of text but does not return the carriage so that the third
line is appended to the end of the second, then followed by two carriage returns, resulting
in a blank line. Finally the fourth printf() outputs a line followed by a carriage return and
the program is complete.

After compiling and executing WRTMORE.C, the following text should be displayed on
your monitor;

This is a line of text to output.


And this is another line of text.

This is a third line.

Compile and execute this program to see if it gives you this output. It would be a good
idea at this time for you to experiment by adding additional lines of printout to see if you
understand how the statements really work. Add a few carriage returns in the middle of a
line to prove to yourself that it works as stated, then compile and execute the modified
program. The more you modify and compile the example programs included with this
tutorial, the more you will learn as you work your way through it.

LET'S PRINT SOME NUMBERS

Example program ------> ONEINT.C

Load the file named ONEINT.C and display it on the monitor for our first example of
how to work with data in a C program. The entry point main() should be clear to you by
now as well as the beginning brace. The first new thing we encounter is line 5 containing
int index; which is used to define an integer variable named index. The word int is a
keyword in C, and can not be used for anything else. It defines a variable that can store a
whole number within a predefined range of values. We will define an actual range later.
The variable name, index, can be any name that follows the rules for an identifier and is
not one of the keywords for C. The final character on the line, the semi-colon, is the
statement terminator as discussed earlier.

Note that, even though we have defined a variable, we have not yet assigned a value to it,
so it contains an undefined value. We will see in a later chapter that additional integers
could also be defined on the same line, but we will not complicate the present situation.

Observing the main body of the program, you will notice that there are three statements
that assign a value to the variable index, but only one at a time. The statement in line 7
assigns the value of 13 to index, and its value is printed out by line 8. (We will see how
shortly. Trust me for the time being.) Later, the value of 27 is assigned to index, and
finally 10 is assigned to it, each value being printed out. It should be intuitively clear that
index is indeed a variable and can store many different values but only one value at a
time of course.

Please note that many times the words "printed out" are used to mean "displayed on the
monitor". You will find that in many cases experienced programmers take this liberty,
probably due to the printf() function being used for monitor display.

HOW DO WE PRINT NUMBERS?


To keep our promise, let's return to the printf() statements for a definition of how they
work. Notice that they are all identical and that they all begin just like the printf()
statements we have seen before. The first difference occurs when we come to the %
character. This is a special character that signals the output routine to stop copying
characters to the output and do something different, usually to output the value of a
variable. The % sign is used to signal the output of many different types of variables, but
we will restrict ourselves to only one for this example. The character following the %
sign is a d, which signals the output routine to get a decimal value and output it. Where
the decimal value comes from will be covered shortly. After the d, we find the familiar \
n, which is a signal to return the video "carriage", and the closing quotation mark.

All of the characters between the quotation marks define the pattern of data to be output
by this statement. Following the output pattern, there is a comma followed by the variable
name index. This is where the printf() statement gets the decimal value which it will
output because of the %d we saw earlier. The system substitutes the current value of the
variable named index for the %d and copies it to the monitor. We could add more %d
output field descriptors anywhere within the brackets and more variables following the
description to cause more data to be printed with one statement. Keep in mind however,
that the number of field descriptors and the number of variable definitions must be the
same or the runtime system will generate something we are not expecting.

Much more will be covered at a later time on all aspects of input and output formatting. A
reasonably good grasp of these fundamentals are necessary in order to understand the
following lessons. It is not necessary to understand everything about output formatting at
this time, only a fair understanding of the basics.

Compile and run ONEINT.C and observe the output. Two programming exercises at the
end of this chapter are based on this program.

HOW DO WE ADD COMMENTS IN C?

Example program ------> COMMENTS.C

Load the file named COMMENTS.C and observe it on your monitor for an example of
how comments can be added to a C program. Comments are added to make a program
more readable to you but represent nonsense to the compiler, so we must tell the compiler
to ignore the comments completely by bracketing them with special characters. The slash
star combination is used in C for comment delimiters, and are illustrated in the program
at hand. Please note that the program does not illustrate good commenting practice, but is
intended to illustrate where comments can go in a program. It is a very sloppy looking
program.

The slash star combination in line 3 introduces the first comment and the star slash at the
end of that line terminates this comment. Note that this comment is prior to the beginning
of the program illustrating that a comment can precede the program itself. Good
programming practice would include a comment prior to the program with a short
introductory description of the program. The comment in line 5 is after the main program
entry point and prior to the opening brace for the program code itself.

The third comment starts after the first executable statement in line 7 and continues for
four lines. This is perfectly legal because a comment can continue for as many lines as
desired until it is terminated. Note carefully that if anything were included in the blank
spaces to the left of the three continuation lines of the comment, it would be part of the
comment and would not be compiled, but totally ignored by the compiler. The last
comment, in line 15, is located following the completion of the program, illustrating that
comments can go nearly anywhere in a C program.

Experiment with this program by adding comments in other places to see what will
happen. Comment out one of the printf() statements by putting comment delimiters both
before and after it and see that it does not get executed and therefore does not produce a
line of printout.

Comments are very important in any programming language because you will soon forget
what you did and why you did it. It will be much easier to modify or fix a well
commented program a year from now than one with few or no comments. You will very
quickly develop your own personal style of commenting.

Some C compilers will allow you to "nest" comments which can be very handy if you
need to "comment out" a section of code during debugging. Since nested comments are
not a part of the ANSI-C standard, none will be used in this tutorial. Check the
documentation for your compiler to see if they are permitted with your implementation of
C. Even though they may be allowed, it is a good idea to refrain from their use, since they
are rarely used by experienced C programmers, and using them may make it difficult to
port your code to another compiler if the need should arise.

GOOD FORMATTING STYLE

Example program ------> GOODFORM.C

Load the file GOODFORM.C and observe it on your monitor. It is an example of a well
formatted program. Even though it is very short and therefore does very little, it is very
easy to see at a glance what it does. With the experience you have already gained in this
tutorial, you should be able to very quickly grasp the meaning of the program in it's
entirety. Your C compiler ignores all extra spaces and all carriage returns giving you
considerable freedom in formatting your program. Indenting and adding spaces is entirely
up to you and is a matter of personal taste. Compile and run the program to see if it does
what you expect it to do.

Example program ------> UGLYFORM.C

Now load and display the program UGLYFORM.C and observe it. How long will it take
you to figure out what this program will do? It doesn't matter to the compiler which
format style you use, but it will matter to you when you try to debug your program.
Compile this program and run it. You may be surprised to find that it is the same program
as the last one, except for the formatting. Don't get too worried about formatting style yet.
You will have plenty of time to develop a style of your own as you learn the C language.
Be observant of styles as you see C programs in magazines and books.

This covers some of the basic concepts of programming in C, but as there are many other
things to learn, we will forge ahead to additional program structure. It will definitely be
to your advantage to do the programming exercises at the end of each chapter. They are
designed to augment your studies and teach you to use your compiler.

PROGRAMMING EXERCISES
 Write a program to display your name on the monitor.
 Modify the program to display your address and phone number on separate lines
by adding two additional printf() statements.
 Remove line 7 from ONEINT.C by commenting it out, then compile and execute
the resulting program to see the value of an uninitialized variable. This can be any
value within the allowable range for that variable. If it happens to have the value
of zero, that is only a coincidence, but then zero is the most probable value to be
in an uninitialized variable because there are lots of zero values floating around in
a computer's memory. It is actually legal for the program to abort if you refer to a
variable that you failed to initialize, but few compilers, if any, will actually do so.
 Add the following two lines just after the last printf() of ONEINT.C to see what it
does. Study it long enough to completely understand the result.

printf("Index is %d\n it still is %d\n it is %d", index, index, index);

PROGRAM CONTROL

THE WHILE LOOP

The C programming language has several structures for looping and conditional
branching. We will cover them all in this chapter and we will begin with the while loop.

The while loop continues to loop while some condition is true. When the condition
becomes false, the looping is discontinued. It therefore does just what it says it does, the
name of the loop being very descriptive.

Example program ------> WHILE.C

Load the program WHILE.C and display it for an example of a while loop. We begin
with a comment and the program entry point main(), then go on to define an integer
variable named count within the body of the program. The variable is set to zero and we
come to the while loop itself. The syntax of a while loop is just as shown here. The
keyword while is followed by an expression of something in parentheses, followed by a
compound statement bracketed by braces. As long as the expression in the parenthesis is
true, all statements within the braces will be repeatedly executed. In this case, since the
variable count is incremented by one every time the statements are executed, it will
eventually reach 6. At that time the statement will not be executed because count is not
less than 6, and the loop will be terminated. The program control will resume at the
statement following the statements in braces.

We will cover the compare expression, the one in parentheses, in the next chapter. Until
then, simply accept the expressions for what you think they should do and you will be
correct for these simple cases.

Several things must be pointed out regarding the while loop. First, if the variable count
were initially set to any number greater than 5, the statements within the loop would not
be executed at all, so it is possible to have a while loop that never is executed. Secondly,
if the variable were not incremented in the loop, then in this case, the loop would never
terminate, and the program would never complete. Finally, if there is only one statement
to be executed within the loop, it does not need delimiting braces but can stand alone.

Compile and run this program after you have studied it enough to assure yourself that you
understand its operation completely. Note that the result of execution is given for this
program, (and will be given for all of the remaining example programs in this tutorial) so
you do not need to compile and execute every program to see the results. Be sure to
compile and execute some of the programs however, to gain experience with your
compiler.

You should make some modifications to any programs that are not completely clear to
you and compile them until you understand them completely. The best way to learn is to
try various modifications yourself.

We will continue to ignore the #include statement and the return statement in the example
programs in this chapter. We will define them completely later in this tutorial.

THE DO-WHILE LOOP

Example program ------> DOWHILE.C

A variation of the while loop is illustrated in the program DOWHILE.C, which you
should load and display. This program is nearly identical to the last one except that the
loop begins with the keyword do, followed by a compound statement in braces, then the
keyword while, and finally an expression in parentheses. The statements in the braces are
executed repeatedly as long as the expression in the parentheses is true. When the
expression in parentheses becomes false, execution is terminated, and control passes to
the statements following this statement.

Several things must be pointed out regarding the do-while loop. Since the test is done at
the end of the loop, the statements in the braces will always be executed at least once.
Secondly, if the variable i were not changed within the loop, the loop would never
terminate, and hence the program would never terminate.

It should come as no surprise to you that these loops can be nested. That is, one loop can
be included within the compound statement of another loop, and the nesting level has no
limit. This will be illustrated later.

Compile and run this program to see if it does what you think it should do.

THE FOR LOOP

Example program ------> FORLOOP.C

Load and display the file named FORLOOP.C on your monitor for an example of a
program with a for loop. The for loop consists of the keyword for followed by a rather
large expression in parentheses. This expression is really composed of three fields
separated by semi-colons. The first field contains the expression "index = 0" and is an
initializing field. Any expressions in this field are executed prior to the first pass through
the loop. There is essentially no limit as to what can go here, but good programming
practice would require it to be kept simple. Several initializing statements can be placed
in this field, separated by commas.

The second field, in this case containing "index < 6", is the test which is done at the
beginning of each pass through the loop. It can be any expression which will evaluate to a
true or false. (More will be said about the actual value of true and false in the next
chapter.)

The expression contained in the third field is executed each time the loop is exercised but
it is not executed until after those statements in the main body of the loop are executed.
This field, like the first, can also be composed of several operations separated by
commas.

Following the for() expression is any single or compound statement which will be
executed as the body of the loop. A compound statement is any group of valid C
statements enclosed in braces. In nearly any context in C, a simple statement can be
replaced by a compound statement that will be treated as if it were a single statement as
far as program control goes. Compile and run this program.

The while is convenient to use for a loop when you don't have any idea how many times
the loop will be executed, and the for loop is usually used in those cases when you are
doing a fixed number of iterations. The for loop is also convenient because it moves all of
the control information for a loop into one place, between the parentheses, rather than at
both ends of the code. It is your choice as to which you would rather use. Depending on
how they are used, it is possible with each of these two loops to never execute the code
within the loop at all. This is because the test is done at the beginning of the loop, and the
test may fail during the first iteration. The do-while loop however, due to the fact that the
code within the loop is executed prior to the test, will always execute the code at least
once.

THE IF STATEMENT

Example program ------> IFELSE.C

Load and display the file IFELSE.C for an example of our first conditional branching
statement, the if. Notice first, that there is a for loop with a compound statement as its
executable part containing two if statements. This is an example of how statements can
be nested. It should be clear to you that each of the if statements will be executed 10
times.

Consider the first if statement. It starts with the keyword if followed by an expression in
parentheses. If the expression is evaluated and found to be true, the single statement
following the if is executed, and if false, the following statement is skipped. Here too, the
single statement can be replaced by a compound statement composed of several
statements bounded by braces. The expression "data == 2" is simply asking if the value of
data is equal to 2. This will be explained in detail in the next chapter. (Simply suffice for
now that if "data = 2" were used in this context, it would mean a completely different
thing. You must use the double equal sign for comparing values.)

NOW FOR THE IF-ELSE

The second if is similar to the first with the addition of a new keyword, the else in line
17. This simply says that if the expression in the parentheses evaluates as true, the first
expression is executed, otherwise the expression following the else is executed. Thus, one
of the two expressions will always be executed, whereas in the first example the single
expression was either executed or skipped. Both will find many uses in your C
programming efforts. Compile and run this program to see if it does what you expect.

THE BREAK AND CONTINUE

Example program ------> BREAKCON.C

Load the file named BREAKCON.C for an example of two new statements. Notice that
in the first for loop, there is an if statement that calls a break if xx equals 8. The break
will jump out of the loop you are in and begin executing statements immediately
following the loop, effectively terminating the loop. This is a valuable statement when
you need to jump out of a loop depending on the value of some results calculated in the
loop. In this case, when xx reaches the value of 8, the loop is terminated and the last
value printed will be the previous value, namely 7. The break always jumps out of the
loop just past the terminating brace.

The next for loop starting in line 15, contains a continue statement which does not cause
termination of the loop but jumps out of the present iteration. When the value of xx
reaches 8 in this case, the program will jump to the end of the loop and continue
executing the loop, effectively eliminating the printf() statement during the pass through
the loop when xx is eight. The continue statement always jumps to the end of the loop
just prior to the terminating brace. At that time the loop is terminated or continues based
on the result of the loop test.

Be sure to compile and execute this program.

THE SWITCH STATEMENT

Example program ------> SWITCH.C

Load and display the file SWITCH.C for an example of the biggest construct yet in the C
language, the switch. The switch is not difficult, so don't let it intimidate you. It begins
with the keyword switch followed by a variable in parentheses which is the switching
variable, in this case truck. As many cases as needed are then enclosed within a pair of
braces. The reserved word case is used to begin each case, followed by the value of the
variable for that case, then a colon, and the statements to be executed.

In this example, if the variable named truck contains the value 3 during this pass of the
switch statement, the printf() in line 13 will cause "The value is three\n" to be displayed,
and the break statement will cause us to jump out of the switch. The break statement here
works in much the same manner as the loop, it jumps out just past the closing brace.

Once an entry point is found, statements will be executed until a break is found or until
the program drops through the bottom of the switch braces. If the variable truck has the
value 5, the statements will begin executing at line 17 where "case 5 :" is found, but the
first statements found are where the case 8 statements are. These are executed and the
break statement in line 21 will direct the execution out of the bottom of the switch just
past the closing brace. The various case values can be in any order and if a value is not
found, the default portion of the switch will be executed.

It should be clear that any of the above constructs can be nested within each other or
placed in succession, depending on the needs of the particular programming project at
hand. Note that the switch is not used as frequently as the loop and the if statements. In
fact, the switch is used infrequently but should be completely understood by the serious C
programmer. Be sure to compile and run SWITCH.C and examine the results.

THE EVIL GOTO STATEMENT

Example program ------> GOTOEX.C

Load and display the file GOTOEX.C for an example of a file with some goto statements
in it. To use a goto statement, you simply use the reserved word goto followed by the
symbolic name to which you wish to jump. The name is then placed anywhere in the
program followed by a colon. You can jump nearly anywhere within a function, but you
are not permitted to jump into a loop, although you are allowed to jump out of a loop.

This particular program is really a mess but it is a good example of why software writers
are trying to eliminate the use of the goto statement as much as possible. The only place
in this program where it is reasonable to use the goto is the one in line 23 where the
program jumps out of the three nested loops in one jump. In this case it would be rather
messy to set up a variable and jump successively out of each of the three nested loops but
one goto statement gets you out of all three in a very concise manner.

Some persons say the goto statement should never be used under any circumstances, but
this is narrow minded thinking. If there is a place where a goto will clearly do a neater
control flow than some other construct, feel free to use

PARAMETER PASSING

After teaching C programming for several years, I found that there are certain concepts
that are difficult to understand and are often misunderstood by new programmers. This is
even true of some programmers that have been using C for several years. This document
will define how parameters are passed to functions. A detailed knowledge of how this is
done in C and C++ will allow you to write more efficient and more robust programs.

HOW IS DATA PASSED TO A FUNCTION?

Consider the very simple program given in the listing immediately below. This program
makes a single call to the function named product(), and it passes two parameters to that
function. We can also see that the function returns a single value which is of type int.

Because this is a trivial program, and we wish to keep it simple, a prototype for the
function is not included. A real program should also do something with the returned
result named area which we simply ignore in this example.

int length = 12;


int width = 5;
int main()
{
int area;

area = product(length, width); /* The call to the function */


}

int product(int side1, int side2) /* The function header */ {


return side1 * side2;
}

This is a trivial program, but it will be the starting point for our study of how parameters
are passed to a function. If we consider the two lines that are commented on in the
example code, we can extract the following two statements, which are executed each time
the function named product() is called.

int side1 = length;


int side2 = width;
Even though these two statements are not explicitly given in the code, they are
nevertheless executed with each call to product() because of the way C is defined. The
first statement is saying, "create a variable for use within the function that is of type int,
named side1, and initialize it to the value of length from the calling program". Anytime
we refer to the variable named side1 within the function, we are referring to the local
copy of the variable, and if we change the value stored in side1, we do not affect the
value of length back in the calling program because we are working only with side1. The
same is true of the second parameter. We are telling the system to create a variable
named side2 which is of type int, and initialize it to the value of width from the main
program.

When we return from the function, the two new variables are no longer needed so they
are deleted. When we say they are deleted, they are not set equal to zero, or any other
value, they actually cease to exist. They are deallocated by the C runtime system.

A GRAPHICAL REPRESENTATION OF THIS OPERATION

If you have not already done so, read the Memory Diagram document which defines
some of the terms given below including the graphical diagramming conventions used by
this author

A picture is said to be worth a thousand words, so let's draw a picture. Figure 1 is a


diagram of the memory space of the computer just prior to making the call to the
function. (This is actually a greatly simplified diagram, but it will help us get started in
understanding just what is happening. We will fill in more details later.) The function
main() and the function product() are stored somewhere in the global memory space of
the computer, and the stack is allocated by the C runtime system for use by our program.
The two boxes represent storage for each of the two global variables named length and
width. The storage for each of these two variables will be created just large enough to
store an int type variable on our system. The stack is currently empty. You will notice
that each of the variables has a value as a result of the initialization in the code. (I am
purposely ignoring the variable named area for the time being. We will explain where it
is stored later in this document.)
                

When the call to the function is made, the system creates a variable named side1 of type
int and copies the value of length from the main program into it. This variable is created
on the stack and can be used within the function. Likewise, another variable is created on
the stack named side2 of type int and the value of width is copied into it. Neither of these
two variables is available for use within the calling program, but are only available to the
function named product(). The memory space now looks like figure 2, and the code in the
function named product() is executed with full access to the two parameters on the stack.
Because the variables named length and width are global, they are also available for use
or modification within the function named product().

                

When execution of the function code is complete, the value of the product of the two
variables is returned to the calling program, which can do whatever it wishes to do with
it. The two variables are removed from the stack and discarded or, to be a little more
proper, they are deallocated. We will say more about the returned value later in this
document. When we return to the calling program, the memory space can be diagrammed
as shown in figure 3. You will notice that figure 3 is identical to figure 1.
                

Based on what we have said so far, the following facts should be clear to you;
 A copy of the input parameters is made for use within the function. This is often
referred to as pass by value.
 Since the function is working with a copy of the data, it cannot change the value
of the variable passed from the calling program.

We can define a generalized assignment for each parameter that is passed to a function,

formal_type formal_parameter = actual_parameter;


We are still not worried about the return value or the variable named area. We will define
them completely later, but I am more interested in defining the parameter passing scheme
at this time.

LET'S REFINE THE MODEL SOME

We will repeat the first program with a slight modification and we will be a little more
correct since we will not ignore any of the variables. We will move the two global
variables into the main program so that they are local variables, and if you studied C
diligently, you will recall that they are also called automatic variables. They are called
automatic variables because they are automatically allocated when they are needed. If
you guess that they are allocated on the stack, you are right. The new code is given as
follows;

int main()
{
int length = 12;
int width = 5;
int area;

area = product(length, width); /* The call to the function */


}
int product(int side1, int side2) /* The function header */
{
return side1 * side2;
}

                

Now we have a slightly different memory layout. The automatic variables are all
allocated on the stack as they are encountered in the main program, so that when we
arrive at the function call in the main program, the memory layout is as depicted in figure
4. The three variables on the stack can be accessed by the main() program. I promised
earlier that I would show you where the variable area is stored, and you can see that it is
on the stack because it is an automatic variable. It is a little different from the other two
variables however, because it has not been initialized. Local variables are not
automatically initialized by the system, but contain whatever bit pattern happened to be in
that memory location. At this time therefore, the variable named area contains any value
imaginable that is legal for an int type variable. The variables named width and length are
explicitly initialized in the code.

                

During the call to the function, the system allocates the two parameters on the stack as it
did in the last program, initializes them to the required values as illustrated above, and we
have the resulting memory layout given in figure 5 just prior to executing the return
statement.

The stack now contains 5 variables. Three are available exclusively to the main()
function, and two are available exclusively to the product() function. The word
exclusively is essential in the preceding statement. The variables cannot be seen by any
address space within the memory other than where they are defined because of the way C
is defined. Since we moved the two global variables into the main() function, they are no
longer visible when we are executing code within the product() function. Execution of the
return statement in the function, causes the two variables for the function to be
deallocated from the stack, and control returns to the main() function. At this time, the
memory space will look very much like figure 4 again but with a meaningful value stored
in area.
We can make up two more rules of argument passing and stack operations;
 When a function is entered, all formal parameters are created on the stack and
they are initialized to the values of their corresponding actual parameters,

 then all local variables within the function are created on the stack and they are
initialized only if initialization values are explicitly given in the code.

WHAT ABOUT THE ORDER OF CREATION

In the case of function parameters, the default for C is to create the variables on
the stack in the reverse order from their listed order so that side2 would go on the
stack prior to side1. We will not be concerned about this because we are only
trying to understand the method of passing variables. If we were writing a
compiler, we would be very interested in this issue, and for some kinds of
advanced programming we also would need to pay attention to the creation order.

THE WRONG NUMBER OF PARAMETERS

Let's repeat the code from above but with another little change. This time we will
make two calls to the function, one with too few actual parameters, and one with
too many actual parameters. The new code is given as follows;

int main()
{
int length = 12;
int width = 5;
int height = 6;
int area;

area = product(length); /* Too few */


area = product(length, width, height); /* Too many */
}

int product(int side1, int side2) /* The function header */


{
return side1 * side2;
}
In the case of using too few parameters, we will be asking the compiler to execute
the following two instructions which it cannot do because the second line is
incomplete.

int side1 = length;


int side2 = ; /* error, uninitialized parameter */
If we are using prototypes, which we should be doing, the compiler will report
that there are not enough parameters during compilation, and we can very quickly
repair the error.

When providing too many parameters, there is an extra value which the system
does not know what to do with, so it probably just ignores it. If you pass an extra
value to the function, you are probably expecting the function to use the value for
something, so there is some sort of an error. Detecting and reporting these kinds
of errors is what prototyping is all about. You should be very diligent in the use of
prototyping for all of your C programming.

HOW IS THE DATA RETURNED?

Returning data is not as easy to define since the compiler writer has a good deal of
leeway, but he must follow one rule;

The returned value must be available for use long enough to permit the
programmer to store it away in a local variable.
The value returned, in this case the product of the two values passed in, may be
returned on the stack or it may be returned in a register, or any other way that the
compiler writer desires. It is up to the compiler writer to provide a means of
storing the returned value in the calling program for you in a manner that
corresponds with his means of returning it. Simply keep in mind that the system
must somehow maintain a copy of the returned value long enough for you to store
a local copy of it. It must keep the value available until execution reaches a
"sequence point", which in this case means the end of the statement. When you
tell the system to assign the value to area, you are saving a copy of it. Following
that, the compiler writer may delete the memory he used to return the value. If he
returned it on the stack, it is imperative that he remove it from the stack in
preparation for the next operation. But that is fine because you have the value
stored in area and you can use it in whatever way you desire.

HOW DO WE PASS A POINTER?

Since we are starting a whole new subject, it would be profitable to write a


completely new program with a couple of pointers in it to use as our illustration.
So, consider the following program fragment;

int length = 16;

int main()
{
int width = 10;
int *p_width = &width;
int area;
area = mod_product(&length, p_width)
}

int mod_product(int *sideA, int *sideB)


{
*sideA = *sideA / 2;
*sideB = *sideB / 2;
return *sideA * *sideB;
}
This is a very simple program that does nothing worthwhile except to act as a
very good example of how pointers are passed as parameters in a function call.
We define a global variable named length and within the main() function we
define another variable named width to give us some data to work with. Then we
define a pointer named p_width and cause it to point to the variable named width
by assigning it the address of width. Finally, we define a variable named area so
we will have a place to store the result of the function call. The length and width
are defined in different places in this program only to illustrate two different
storage means. In a meaningful program, such similar variables should be defined
together and in a similar fashion.

                

Just prior to making the call to the function, we have the memory layout as
depicted in figure 6. If you understand all of this article up to this point, you
should be able to understand every detail of this diagram. Keep in mind that a
pointer is actually another storage element, sort of like an integer, but one that
stores the address of an entity rather than some actual data.

CALLING THE FUNCTION WITH POINTERS

When we call the function we are executing the following two statements in the
manner which we defined earlier in this document. These statements create two
new pointers on the stack and initializes them to point to two variables, one in the
main program named width, and one in global memory named length;
int *sideA = &length;
int *sideB = p_width;

                

Once again, two different methods of passing a pointer to a function are used for
illustration. In the first case we take the address of the actual parameter right in
the function call and pass the resulting pointer to the function. In the second case
we pass a pointer's value. A well planned program should pass both parameters in
the same manner in order to make the program easier to understand. You should
be able to clearly see that the reason these two pointers are pointing to variables in
the other parts of the program is because we passed pointers to those other
variables. Following execution of the function call, we are in the function and the
memory layout is depicted in figure 7.

                

Following execution of the three statements within the function but prior to the
return to the main program, we have the memory layout as depicted in figure 8.
You will notice that the system has modified the two variables named length and
width which are elements of the calling program. It has calculated the return value
but we have no way to depict where it is stored since each compiler can use any
method it desires. Suffice it to say that somewhere the system has the value of 40
stored away for return.

Following return, the value of 40 is stored in the variable named area and the
program terminates.

This program should have clearly depicted how the pointers are used to provide
access to the actual values in the calling program. You should notice also that
copies of the pointers were passed to the function in this program which says that
the first rule, given at the beginning of this document, is not violated.

PASSING AN ARRAY TO A FUNCTION

The name of an array is actually a pointer which is pointing to the first element in
the array, with the added caveat that it cannot be changed. It is actually a constant
pointer. Therefore when we pass the name of the array to a function we are
passing a pointer to the first element and we make a copy of that pointer for use
within the function. For more details on arrays, see the document entitled Arrays
and Pointers in this group of documents.

Study the following program fragment for a few minutes and we will make a few
comments on it.

#define ELEMENTS 10
double my_array[ELEMENTS];

int main()
{
int index;
int sum;

for (index = 0 ; index < ELEMENTS ; index++)


{
my_array[index] = (double)(index * 2);
}
sum = sum_array(ELEMENTS, my_array);
}

double sum_array(int size, double in_array[])


{
int index;
double total = 0.0;
for (index = 0 ; index < size ; index++)
{
total = total + in_array[index];
}
return total;
}

                

A graphical representation of the address space just prior to executing the for loop
in the function is given in Figure 9. You will notice that we did not pass the entire
array to the function, we only passed the address of the first element which we
stored in the variable in_array. This gives us access to the entire array for either
reading or modification.

Note that the pointer in_array is not a constant but is a variable and can be
changed because of the way we defined it.

A VERY IMPORTANT DEFINITION

The diligent student will notice that we did not say, "an array is a pointer",
because that is definitely not true. We can say, "the name of an array is a constant
pointer to the first element of the array." Be sure you understand that statement
completely because it could save you a lot of grief some time in your
programming future. This is carefully defined in the document entitled Arrays and
Pointers in this group of documents.

PASSING A STRUCTURE TO A FUNCTION

We finally come to the big one, passing a structure to a function. We will begin as
usual, by defining a very simple program containing the construct of current
interest. In this case we declare a trivial structure that can store each of the
elements of a date, and write a program that passes a date variable to a function
and passes a pointer to the date structure to another function.

struct date
{
int month;
int day;
int year;
};

int main()
{
struct date birthday;

birthday.month = 7;
birthday.day = 4;
birthday.year = 1776;
use_struct(birthday); /* Pass the full date */
use_point(&birthday); /* Pass a pointer to the date */
}

void use_struct(struct date in_date)


{
/* Use the date passed in */
}

void use_point(struct date *in_date)


{
/* Use the date pointer passed in */
}
The first thing you should notice is that the entire date structure named birthday is
stored on the stack because it is defined locally. A lot of large structures defined
in this way will use up the stack very quickly. This should encourage you to use
dynamically allocated memory as often as possible for large entities. The heap is
much larger than the stack on most systems.

                

When we execute the use_struct() function, the entire date structure is passed into
the function. A structure is allocated on the stack with storage space for each of
the three variables, and the three values from birthday are copied into their
respective spaces. The function then has access to each of the three variables
which it can read or modify, and the structure is removed from the stack when
control returns to the calling program. It should be apparent that this could be
very inefficient for a large structure since it could take a relatively long time to
build the structure and copy the data from the actual parameter. Figure 10 gives a
graphical representation of the memory space of the computer when we have just
entered the function use_struct(), but before we have changed any of the values of
the date structure on the stack.

                

Calling use_point() with a pointer to the structure is very similar to the previous
example program, so very little needs to be said about it except to examine figure
11 for a graphical representation of the memory space just after entering the
function. Note that the pointer named in_date is actually pointing to the entire
structure that was already on the stack so a new structure does not have to be built
and initialized. It looks like it is pointing to only the month variable, but it is
actually pointing to all three components of the date structure. This is a weakness
with this particular graphical notation.

FINAL CAVEATS

You must keep in mind that the representation of the stack in each of these
examples has been greatly simplified. We only showed those elements on the
stack that were needed to accomplish the task of passing parameters to a function.
In addition to what we depicted, the return address may be placed on the stack
that tells the system where to return to following execution of the function. There
may also be some frame pointers used internally by the function, and there may
be some wasted bytes that are used only as fillers to provide some particular byte
alignment. Careful byte alignment can make the resulting program much more
efficient in execution time by wasting a few bytes here and there.

All of this is taken care of by the compiler transparently to you, but you should be
aware that some other operations are taking place that you have no control over.
I trust that you found this information useful.
C++

Simple concept
As we begin the study of C++ and object oriented programming, a few comments are in
order to help you get started. Since the field of object oriented programming is probably
new to you, you will find that there is a significant amount of new terminology for you to
grasp. This is true of any new endeavor and you should be warned not to be intimidated
by all of the new concepts. We will add a few new topics in each chapter and you will
slowly grasp the entire language.

Chapters one through four of this tutorial will concentrate on the non object oriented
additions to C++. We will not begin the discussion of any object oriented programming
techniques until chapter five.

EVEN COMMENTS ARE IMPROVED IN C++

Example program ------> CONCOM.CPP

Examine the file named CONCOM.CPP for an example of several new things in C++.
We will take the new constructs one at a time beginning with the comments.

A C++ comment begins with the double slash "//", starts anywhere on a line, and runs to
the end of that line where it is automatically terminated. The old method of comment
definition used with ANSI-C can also be used with C++ as illustrated in lines 11 through
14, among other places in this program. The new method is the preferred method of
comment definition because it is impossible to inadvertently comment out several lines of
code. This can be done by forgetting to include the end of comment notation when using
the older C method of comment notation. Good programming practice would be to use
the new method for all comments and reserve the old method for use in commenting out a
section of code during debugging since the two methods can be nested.

It would be well to caution you at this point however, that you should not use comments
when the same sense of program definition can be obtained by using meaningful names
for variables, constants, and functions. The careful selection of variable and function
names can make nearly any code self documenting and you should strive to achieve this
in your code.

THE KEYWORDS const AND volatile

There are two new keywords used in lines 9 through 11 which were not part of the
original K&R definition of C, but are part of the ANSI-C standard. The keyword const is
used to define a constant. In line 9 the constant is of type int, it is named START, and is
initialized to the value 3. The compiler will not allow you to accidentally or purposefully
change the value of START because it has been declared a constant. If you had a variable
named STARTS in this program, the system would not allow you to slightly misspell
STARTS as START and accidentally change it. The compiler would give you an error
message so you could fix the error. Since it is not permissible to change the value of a
constant, it is imperative that you initialize it when it is declared so it will have a useful
value.

You will note that the keyword const is also used in the function header in line 23 to
indicate that the formal parameter named data_value is a constant throughout the
function. Any attempt to assign a new value to this variable will result in a compile error.
This is a small thing you can add to your programs to improve the compiler's ability to
detect errors for you.

The keyword volatile is also part of the ANSI-C standard but was not included in the
original K&R definition of C. Even though the value of a volatile variable can be
changed by you, the programmer, there may be another mechanism by which the value
could be changed, such as by a hardware interrupt timer causing the value to be
incremented. The compiler needs to know that this value may be changed by some
external force when it optimizes the code. A study of code optimization methods is very
interesting, but beyond the scope of this tutorial. Note that a constant can also be volatile,
which means that you cannot change it, but the system can modify it through some
hardware function.

Ignore the output statement given in line 25 for a few minutes. We will study it in some
detail later in this chapter. If you are experienced in the K&R style of programming, you
may find line 5 and 23 a little strange. This illustrates prototyping and the modern method
of function definition as defined by the ANSI-C standard. Prototyping is optional in C but
absolutely required in C++. For that reason, chapter 4 of this tutorial is devoted entirely
to prototyping.

It would be advantageous for you to compile and execute this program with your C++
compiler to see if you get the same result as given in the comments at the end of the
listing. One of the primary purposes of compiling it is to prove that your compiler is
loaded and executing properly.

THE SCOPE OPERATOR

Example program ------> SCOPEOP.CPP

The example program named SCOPEOP.CPP illustrates another construct that is new to
C++. There is no corresponding construct in either K&R or ANSI-C. This allows access
to the global variable named index even though there is a local variable of the same name
within the main() function. The use of the double colon in front of the variable name, in
lines 11, 13, and 16, instructs the system that we are interested in using the global
variable named index, defined in line 4, rather than the local variable defined in line 8.
The use of this technique allows access to the global variable for any use. It could be used
in calculations, as a function parameter, or for any other purpose. It is not really good
programming practice to abuse this construct, because it could make the code difficult to
read. It would be best to use a different variable name instead of reusing this name, but
the construct is available to you if you find that you need it sometime.

Be sure to compile and execute this program before proceeding on to the next example
program where we will discuss the cout operator used in lines 10, 11, 15, and 16.

THE iostream LIBRARY

Example program ------> MESSAGE.CPP

Examine the example program named MESSAGE.CPP for our first hint of object
oriented programming, even though it is a very simple one. In this program, we define a
few variables and assign values to them for use in the output statements illustrated in
lines 17 through 20, and in lines 23 through 26. cout is used to output data to the standard
device, the monitor, but it works a little differently from our old familiar printf() function,
because we do not have to tell the system what type we are outputting. Note that cout is
not actually an output function, but we can sort of think of it as one until we fully define
it later in this tutorial. For the time being, we will simply state that cout is an object used
to send output data to the monitor.

C++, like the C language, has no input or output operations as part of the language itself,
but defines the stream library to add input and output functions in a very elegant manner.
A portion of the stream library is included in this program in line 2.

The operator <<, sometimes called the "put to" operator but more properly called the
insertion operator, tells the system to output the variable or constant following it, but lets
the system decide how to output the data. In line 17, we first tell the system to output the
string, which it does by copying characters to the monitor, then we tell it to output the
value of index. Notice however, that we fail to tell it what the type is or how to output the
value. Since we don't tell the system what the type is, it is up to the system to determine
what the type is and to output the value accordingly. After the system finds the correct
type, we also leave it up to the system to use the built in default as to how many
characters should be used for this output. In this case, we find that the system uses
exactly as many characters as needed to output the data, with no leading or trailing
blanks, which is fine for this output. Finally, the newline character is output as a single
character string, and the line of code is terminated with a semicolon.

When we told the cout object to output some data in line 17, we actually called two
different functions because we used it to output two strings and a variable of type int.
This is the first hint at object oriented programming because we simply broadcast a
message to the system to print out a value, and let the system find an appropriate function
to do so. We are not required to tell the system exactly how to output the data, we only
tell it to output it. This is a very weak example of object oriented programming, and we
will study it in much more depth later in this tutorial.

In line 18, we tell the system to output a different string, followed by a floating point
number, and another string of one character, the newline character. In this case, we told it
to output a floating point number without telling it that it was a floating point number,
once again letting the system choose the appropriate output means based on its type. We
did lose a bit of control in the transaction, however, because we had no control over how
many significant digits to print before or after the decimal point. We chose to let the
system decide how to format the output data.

The variable named letter is of type char, and is assigned the value of the uppercase X in
line 14, then printed as a letter in line 19 because the cout object knows it is a character
and outputs it accordingly

Because C++ has several other operators and functions available with streams, you have
complete flexibility in the use of the stream output functions. You should refer to your
compiler documentation for details of other available formatting commands. Because it is
expected to be mandated by the upcoming ANSI-C++ standard, the cout and printf()
statements can be mixed in any way you desire. However all compilers do not yet
conform to this standard and some use different forms of buffering for the two kinds of
output. This could result in scrambled output, but it should be easy for the student to
repair the output in such a way that only one form is used, either the cout or the printf().

MORE ABOUT THE stream LIBRARY

The stream library was defined for use with C++ in order to add to the execution
efficiency of the language. The printf() function was developed early in the life of the C
language and is meant to be all things to all programmers. As a result, it became a huge
function with lots of extra baggage, most of which is used by only a few programmers.
By defining the special purpose stream library, the design of C++ allows the programmer
to use full formatting capabilities, but only load what is needed for the current
programming job. Although it is not all illustrated here, there is a full set of formatting
functions available in the C++ stream library. Check your compiler documentation for the
complete list.

Lines 23 through 26 illustrate some of the additional features of the stream library which
can be used to output data in a very flexible yet controlled format. The value of index is
printed out in decimal, octal, and hexadecimal format in lines 23 through 25. When one
of the special stream operators, dec, oct, or hex, is output, all successive output will be in
that number base. Looking ahead to line 30, we find the value of index printed in hex
format due to the selection of the hexadecimal base in line 25. If none of these special
stream operators are output, the system defaults to decimal format.

THE cin OPERATOR

In addition to the predefined stream object, named cout, there is a predefined cin stream
object which is used to read data from the standard input device, usually the keyboard.
The cin stream uses the >> operator, usually called the "get from" operator but properly
called the extraction operator. It has most of the flexibility of the cout stream. A brief
example of the use of the cin stream is given in lines 28 through 30. The special stream
operators, dec, oct, and hex, also select the number base for the cin stream separately
from the cout stream. If none is specified, the input stream also defaults to decimal.

In addition to the cout stream object and the cin stream object there is one more standard
stream object, cerr, which is used to output to the error handling device. This device
cannot be redirected to a file on some systems, like the output to the cout stream object
can be. The three streams, cout, cin, and cerr, correspond to the stdout, the stdin, and the
stderr stream pointers of the C programming language. Their use will be illustrated
throughout the remainder of this tutorial.

The stream library also has file I/O capability which will be briefly illustrated in the next
example program.

Be sure to compile and execute this program before going on to the next one. Remember
that the system will ask you to enter an integer value which will be echoed back to the
monitor, but changed to the hexadecimal base.

FILE STREAM OPERATIONS

Example program ------> FSTREAM.CPP

Examine the example program named FSTREAM.CPP for examples of the use of
streams with files. We will be using a few C++ objects in this program but we hAve not
yet studied them, so you will not understand them at this point. Don't spend too much
time trying to understand them yet.

In this program a file is opened for reading, another for writing, and a third stream is
opened to the printer to illustrate the semantics of stream operations on a file. Both input
and output files are of type FILE in C programs, but the ifstream type is used for file
input and the ofstream is used for output files. This is illustrated in lines 8 through 10 of
this example program. Actually ifstream is a C++ class and infile is an object of that class
as we will see later in this tutorial.

The only difference between the streams in the last program and the streams in this
program is the fact that in the last program, the streams were already opened for us by the
system. You will note that the stream object named printer is used in the same way we
used the cout stream object in the last program. Finally, because we wish to exercise
good programming practice, we close all of the files we have opened prior to ending the
program.

This is our first example of object oriented programming because we are actually using
objects in this program. The object named infile is told to open itself in line 17, then it is
told to get one character at a time in line 44, and finally it is told to close itself in line 52.
The "dot" notation is used with objects in a similar manner that structures are used in C.
The name of the object is mentioned, followed by a "dot", and followed by the name of
the action that the object is to execute. This terminology will be used in great profusion
later in this tutorial, so don't worry about it at this time. The objects outfile and printer are
manipulated in exactly the same manner.

For more information on the stream file I/O library, see Bjarne Stroustrup's book which is
listed in the introduction to this tutorial, or refer to your compiler documentation. Don't
worry too much about it yet, after you learn the terminology by studying the rest of this
tutorial, you will be able to return to a personal study of the stream library, and profit
greatly from the study.

Be sure to compile and execute this program. When you execute it, it will request a file to
be copied. You can enter the name of any ASCII file that resides in the current directory.

VARIABLE DEFINITIONS

Example program ------> VARDEF.CPP

Examine the file named VARDEF.CPP for a few more additions to the C++ language
which aid in writing a clear and easy to understand program. In C++, as in ANSI-C,
global and static variables are automatically initialized to zero when they are declared.
The variables named index in line 4, and goofy in line 27 are therefore automatically
initialized to zero. Of course, you can still initialize either to some other value if you so
desire. Global variables are sometimes called external since they are external to any
functions.

Automatic variables, those declared inside of any function, are not automatically
initialized but will contain the value that happens to be in the location where they are
defined, which must be considered a garbage value. The variable named stuff in line 8,
therefore does not contain a valid value, but some garbage value which should not be
used for any meaningful purpose. In line 11, it is assigned a value based on the initialized
value of index and it is then displayed on the monitor for your examination.

THE C++ REFERENCE

Notice the ampersand in line 9. This defines another_stuff as a reference which is a new
addition to C++. The reference should not be used very often, if ever, in this context, but
this is a very simple example used to introduce the reference and discuss its use and
operation. The reference is not the same as any other entity used in C because it operates
like a self dereferencing pointer. Following its initialization, the reference becomes a
synonym for the variable stuff, and changing the value of stuff will change the value of
another_stuff because they are both actually referring to the same variable. The synonym
can be used to access the value of the variable stuff for any legal purpose in the language.
It should be pointed out that a reference must be initialized to reference some variable
when it is defined or the compiler will respond with an error. Following initialization, the
reference cannot be changed to refer to a different variable. The reference is difficult to
discuss because we want to call it a reference variable, but it is not a variable since it
cannot be changed. Whether we like the name or not it is simply called a reference.

The use of the reference in this way can lead to very confusing code, but it has another
use where it can make the code very clear and easy to understand. We will study the
proper use of the reference in chapter 4 of this tutorial.

DEFINITIONS ARE EXECUTABLE STATEMENTS

Coming from your background of C, you will find the statement in line 16 very strange,
but this is legal in C++. Anyplace it is legal to put an executable statement, it is also legal
to define a new variable because a data definition is an executable statement according to
the definition of C++. In this case, we define the new variable named more_stuff and
initialize it to the value of 13. It has a scope from the point where it is defined to the end
of the block in which it is defined, so it is valid throughout the remainder of the main()
program. The variable named goofy is defined even later in line 27.

It is significant that the variable is declared near its point of usage. This makes it easier to
see just what the variable is used for, since it has a much more restricted scope of
validity. When you are debugging a program, it is convenient if the variable declaration is
located in close proximity to where you are debugging the code.

WHAT ABOUT definition AND declaration?

The words definition and declaration refer to two different things in C++, and in ANSI-C
also for that matter. They really are different and have different meanings, so we should
spend a little time defining exactly what the words mean in C++. A declaration provides
information to the compiler about the characteristics of something such as a type or a
function but it doesn't actually define any code to be used in the executable program. A
definition, on the other hand, actually defines something that will exist in the executable
program, either some useful variables, or some executable code. You are required to have
one and only one definition of each entity in the program. In short, a declaration
introduces a name into the program and a definition introduces some code and requires
memory space to store something.

If we declare a struct, we are only declaring a pattern to tell the compiler how to store
data later when we define one or more variables of that type. But when we define some
variables of that type, we are actually declaring their names for use by the compiler, and
defining a storage location to store the values of the variables. Therefore, when we define
a variable, we are actually declaring it and defining it at the same time.

C permits multiple definitions of a variable in any given namespace, provided the


definitions are the same and it generates only a single variable for the multiple
definitions. C++, however, does not permit redefinition of a variable or any other entity
for a very definite reason that we will discuss later.

We will refer to these definitions many times throughout the course of this tutorial so if
this is not clear now, it will clear up later.

A BETTER for LOOP

Take careful notice of the for loop defined in line 20. This loop is a little clearer than the
for loop that is available in ANSI-C, because the loop index is defined in the for loop
itself. The scope of this loop index depends on how new your compiler is.

If your compiler is a little old, the scope of the loop index is from its definition to the end
of the enclosing block. In this case its scope extends to line 32 since the closing brace in
line 32 corresponds to the most recent opening brace prior to the definition of the
variable. Since the variable is still available, it can be used for another loop index or for
any other purpose which an integer type variable can legally be used for.

If your compiler is relatively new, the scope of the loop index is from its definition to the
end of the loop. In this case its scope extends to line 25 because that is where the loop
ends. This is a very new extension to the C++ language by the standards committee, and
will only be available with the newest compilers.

Regardless of the age of your compiler, the variable named count2 is defined and
initialized during each pass through the loop because it is defined within the block
controlled by the for loop. Its scope is only the extent of the loop, lines 23 to 25, so that it
is automatically deallocated each time the loop is completed. It is therefore defined,
initialized, used and deallocated five times, once for each pass through the loop.

You will notice that the variable count2 is assigned a numerical value in line 23 but when
it is printed out, a character value is actually output. This is because C++ is careful to use
the correct type for output. If you have a very old compiler, it may output a numerical
value here.

Finally, as mentioned earlier, the static variable named goofy is defined and
automatically initialized to zero in line 27. Its scope is from the point of its definition to
the end of the block in which it is defined, line 32.

Be sure to compile and execute this program.

OPERATOR PRECEDENCE

Operator precedence is identical to that defined for ANSI-C so no attempt will be made
here to define it. There is a small difference when some operators are overloaded which
we will study later in this tutorial. Some of the operators act slightly different when
overloaded than the way they operate with elements of the predefined language.
Do not worry about the previous paragraph, it will make sense later in this tutorial after
we have studied a few more topics

PROGRAMMING EXERCISES
 Write a program that displays your name and date of birth on the monitor three
times using the cout stream object. Define any variables you use as near as
possible to their point of usage.
 Write a program with a few const values and volatile variables and attempt to
change the value of the constants to see what kind of error message your compiler
gives you.
 Write a program that uses stream objects to interactively read in your birthday
with three different cin statements. Print your birthday in octal, decimal, and
hexadecimal notation just for the practice.

COMPOUND TYPES

ENUMERATED TYPES

Example program ------> ENUM.CPP

Examine the file named ENUM.CPP for an example that uses an enumerated type
variable. The enumerated type is used in C++ in a similar way that it was used in ANSI-
C, but there are a lot of differences. The keyword enum is not required to be used again
when defining a variable of that type, but it can be used if desired. The name game_result
is defined as an enumerated type making the use of the keyword enum optional.
However, it may be clearer for you to use the keyword when defining a variable in the
same manner that it is required to be used in C, and you may choose to do so.

The example program uses the keyword enum in line 9, but omits it in line 8 to illustrate
to you that it is indeed optional, but that is a trivial difference. There is a bigger
difference in the way an enumerated type is used in C++. In C, the enumerated type is
simply an int type variable, but in C++ it is not an int, but its own type. Mathematical
operations can not be performed on it, nor can an integer be assigned to it. It cannot be
incremented or decremented as it can be in C. In the example program, an integer is used
as the loop index for the for loop because it can be incremented, then the value of the
loop index named count is assigned to the enumerated variable by using a cast. The cast
is required or a compile error is reported. The mathematical operations and the increment
and decrement operators can be defined for the enumerated type, but they are not
automatically available. Operator overloading will be studied later, and the last sentence
will make much more sense at that time.

If you have an older compiler, the enumerated variable game_result can be used for the
loop variable but your code would not be portable to a newer compiler.

The remainder of this program should be no problem for you to understand. After
studying it, be sure to compile and execute it and examine the output.

A SIMPLE STRUCTURE

Example program ------> STRUCTUR.CPP

Examine the example program named STRUCTUR.CPP for an illustration using a very
simple structure. This structure is no different from that used in ANSI-C except for the
fact that the keyword struct is not required to be used again when defining a variable of
that type. Lines 12 and 13 illustrate the definition of variables without the keyword, and
line 14 indicates that the keyword struct can be included if desired. It is up to you to
choose which style you prefer to use in your C++ programs.

Once again, be sure to compile and execute this program after studying it carefully,
because the next example program is very similar but it introduces a brand new construct
not available in standard C, the class.

A VERY SIMPLE CLASS

Example program ------> CLASS1.CPP

Examine the example program named CLASS1.CPP for our first example of a class in
C++. This is the first class example, but it will not be the last, since the class is the major
reason for using C++ over ANSI-C or some other programming language. You will
notice the keyword class used in line 4, in exactly the same way that the keyword struct
was used in the last program, and they are in fact very similar constructs. There is a
definite difference, as we will see, but for the present time we will be concerned more
with their similarities.

The word animal in line 4 is the name of the class, and when we define variables of this
type in lines 13 through 15, we can either omit the keyword class or include it if desired
as illustrated in line 15. In the last program, we declared 5 variables of a structure type,
but in this program we declare 5 objects. They are called objects because they are of a
class type. The differences are subtle, and as we proceed through this tutorial, we will see
that the class construct is indeed very important and valuable. The class was introduced
here only to give you a glimpse of what is to come later in this tutorial.

The class is a type which can be used to define objects in much the same way that a
structure is a type that can be used to define variables. Your dog named King is a specific
instance of the general class of dogs, and in a similar manner, an object is a specific
instance of a class. It would be well to take note of the fact that the class is such a
generalized concept that there are libraries of prewritten classes available in the
marketplace. You can purchase classes which perform some generalized operations such
as managing stacks, queues, or lists, sorting data, managing windows, etc. This is because
of the generality and flexibility of the class construct.

The new keyword public in line 6, followed by a colon, is necessary in this case because
the variables in a class are defaulted to a private type and we could not access them at all
without making them public. Don't worry about this program yet, we will cover all of this
in great detail later in this tutorial. Be sure to compile and run this example program to
see that it does what we say it does with your compiler. Keep in mind that this is your
first example of a class and it illustrates essentially nothing concerning the use of this
powerful C++ construct.

THE FREE UNION OF C++

Example program ------> UNIONEX.CPP

Examine the program named UNIONEX.CPP for an example of a free union. In ANSI-C,
all unions must be named in order to be used, but this is not true in C++. When using C+
+ we can use a free union, a union without a name. The union is embedded within a
simple structure and you will notice that there is not a variable name following the
declaration of the union in line 13. In ANSI-C, we would have to name the union and
give a triple name (three names dotted together) to access the members. Since it is a free
union, there is no union name, and the variables are accessed with only a doubly dotted
name as illustrated in lines 20, 24, 28, and others.

You will recall that a union causes all the data contained within the union to be stored in
the same physical memory locations, such that only one variable is actually available at a
time. This is exactly what is happening here. The variable named fuel_load, bomb_load,
and pallets are stored in the same physical memory locations and it is up to the
programmer to keep track of which variable is stored there at any given time. You will
notice that the transport is assigned a value for pallets in line 28, then a value for
fuel_load in line 30. When the value for fuel_load is assigned, the value for pallets is
corrupted and is no longer available since it was stored where fuel_load is currently
stored. The observant student will notice that this is exactly the way the union is used in
ANSI-C except for the way components are named.

The remainder of the program should be easy for you to understand, so after you study
and understand it, compile and execute it.

C++ TYPE CONVERSIONS

Example program ------> TYPECONV.CPP

Examine the program named TYPECONV.CPP for a few examples of type conversions
in C++. The type conversions are done in C++ in exactly the same manner as they are
done in ANSI-C, but C++ gives you another form for doing the conversions.
Lines 10 through 17 of this program use the familiar "cast" form of type conversions used
in ANSI-C, and there is nothing new to the experienced C programmer. You will notice
that lines 10 through 13 are all the same. The only difference is that we are coercing the
compiler to do the indicated type conversions prior to doing the addition and the
assignment in some of the statements. In line 13, the int type variable will be converted to
type float prior to the addition, then the resulting float will be converted to type char prior
to being assigned to the variable c.

Additional examples of type coercion are given in lines 15 through 17 and all three of
these lines are essentially the same.

The examples given in lines 19 through 26 are unique to C++ and are not valid in ANSI-
C. In these lines the type coercions are written as though they are function calls instead of
the more familiar "cast" method as illustrated earlier. Lines 19 through 26 are identical to
lines 10 through 17.

You may find this method of type coercion to be clearer and easier to understand than the
"cast" method and in C++ you are free to use either, or to mix them if you so desire, but
your code could be very difficult to read if you indescriminantly mix them.

Be sure to compile and execute this example program.

PROGRAMMING EXERCISES

Starting with the program ENUM.CPP, add the enumerated value of FORFEIT to the
enumerated type game_result, and add a suitable message and logic to get the message
printed in some way. Add the variable height of type float to the class of CLASS1.CPP
and store some values in the new variable. Print some of the values out. Move the new
variable ahead of the keyword public: and see what kind of error message results. We
will cover this error in chapter 5 of this tutorial

POINTERS

Because pointers are so important in C and C++, this chapter will review some of the
more important topics concerning pointers. Even if you are extremely conversant in the
use of pointers, you should not completely ignore this chapter because some new material
unique to C++ is presented here.

POINTER REVIEW

Example program ------> POINTERS.CPP

Examine the program named POINTERS.CPP for a simple example of the use of
pointers. This is a pointer review and if you are comfortable with the use of pointers, you
can skip this example program completely.

A pointer in either ANSI-C or C++ is declared with an asterisk preceding the variable
name. The pointer is then a pointer to a variable of that one specific type and should not
be used with variables of other types. Thus pt_int is a pointer to an integer type variable
and should not be used with any other type. Of course, an experienced C programmer
knows that it is simple to coerce the pointer to be used with some other type by using a
cast, but he must then assume the responsibility for its correct usage.

In line 12 the pointer named pt_int is assigned the address of the variable named pig and
line 13 uses the pointer named pt_int to add the value of dog to the value of pig because
the asterisk dereferences the pointer in exactly the same manner as standard C. Figure 3-1
is a graphical representation of the data space following execution of line 13. Note that a
box containing a dot represents a pointer. The address is used to print out the value of the
variable pig in line 14 illustrating the use of a pointer with the output stream object cout.
Likewise, the pointer to float named pt_float is assigned the address of x, then used in a
trivial calculation in line 18.

CONSTANT POINTERS AND POINTERS TO CONSTANTS

The definition of C++ allows a pointer to a constant to be defined such that the value to
which the pointer points cannot be changed but the pointer itself can be moved to another
variable or constant. The method of defining a pointer to a constant is illustrated in line
22. In addition to a pointer to a constant, you can also declare a constant pointer, one that
cannot be changed. Line 23 illustrates this. Note that neither of these pointers are used in
illustrative code.

Either of these constructs can be used to provide additional compile time checking and
improve the quality of your code. If you know a pointer will never be moved due to its
nature, you should define it as a constant pointer. If you know that a value will not be
changed, it can be defined as a constant and the compiler will tell you if you ever
inadvertently attempt to change it.

A POINTER TO VOID

The pointer to void is actually a part of the ANSI-C standard but is relatively new so it is
commented upon here. A pointer to void can be assigned the value of any other pointer
type. You will notice that the pointer to void named general is assigned an address of an
int type in line 15 and the address of a float type in line 20 with no cast and no complaints
from the compiler. This is a relatively new concept in C and C++. It allows a programmer
to define a pointer that can be used to point to many different kinds of things to transfer
information around within a program. A good example is the malloc() function which
returns a pointer to void. This pointer can be assigned to point to any entity, thus
transferring the returned pointer to the correct type.
A pointer to void is aligned in memory in such a way that it can be used with any of the
simple predefined types available in C++, or in ANSI-C for that matter. They will also
align with any compound types the user can define since compound types are composed
of the simpler types.

If you are not completely comfortable with this trivial program using pointers, you should
review the use of pointers in any good C programming book or Coronado Enterprises C
tutorial before proceeding on because we will assume that you have a thorough
knowledge of pointers throughout the remainder of this tutorial. It is not possible to write
a C program of any significant size or complexity without the use of pointers.

Be sure to compile and execute this program.

DYNAMIC ALLOCATION AND DEALLOCATION

Example program ------> NEWDEL.CPP

Examine the program named NEWDEL.CPP for our first example of the new and delete
operators. The new and delete operators do dynamic allocation and deallocation in much
the same manner that the malloc() and free() functions do in your old favorite C
implementation.

During the design of C++, it was felt that since dynamic allocation and deallocation are
such a heavily used part of the C programming language and would also be heavily used
in C++, it should be

MEMORY DIAGRAM
This document provides some basic information that you may need to fully understand
the topical documents provided at this web site.

Figure 1 is used to define the memory elements of any program via a graphical
representation. This diagram is a depiction of memory and will be used to illustrate how
the various entities of a C or C++ program are stored within the computer memory.

The entire area of figure 1 represents the memory in the computer, including the area to
the right that looks like a ladder. All of the executable code and all of the variables within
any given program are stored within the area illustrated by this diagram. The big question
is, "How are the various entities stored in this space?"

There are three areas of memory that have special capabilities assigned by the compiler
and linker. They are listed as follows;

Stack - The area that looks like a ladder on the right part of the diagram is the stack. The
stack is allocated by the system to be a fixed size and is filled as needed from the bottom
to the top one element at a time. Elements are removed from the top to the bottom one
element at a time. Thus the last element added to the stack is the first element that is
removed when no longer needed. Any element on the stack is potentially available for
reference or modification by the executing code, but elements are added and removed
only from the top.

Heap - This is the area within the box named the heap. This is allocated by the system to
be of a fixed size and is used by the system as needed in a random fashion. By random, it
does not mean that there is any disorder to the way this area is used, it means the memory
is not assigned in any particular order. It can in fact be assigned in blocks as needed from
anyplace within the heap. Any memory within the heap that is not currently allocated for
use by the program is stored in the "free list", a list of memory blocks that can be
assigned to the program as needed.

Global Memory - This is all of the memory on the machine that is not assigned to the
stack or the heap.

As an aid to clarity, all keywords, identifiers, and function names used in the text portion
of these documents will be given in bold type.

WHAT ABOUT A MULTI-USER ENVIRONMENT?

We are assuming a single user computer for simplicity. In the case of a multi-user
system, each user is assigned a block of memory which is carved up as shown here so
that the same principles apply to each user.

HOW IS GLOBAL MEMORY ASSIGNED

The block of code that is the main() program is stored in global memory and every
function that is required for the program to execute is also stored somewhere in global
memory. Even though the system will assign the various blocks of code in a very orderly
manner, we must assume that they are actually assigned in no particular order. In fact we
should assume that they are randomly assigned all over the global storage area and that
any particular function is not contiguous to any other function.

Note that some compilation/linking systems permit you to locate code and variables
where you want them in memory, but that is beyond the scope of this document.

Figure 1 contains a box with the title main(). This box represents the block of code for the
main() program. Even though all of the functions in any program appear as code blocks
within the global memory, we will not include them in any of the remaining figures since
they don't interact in a manner that is conducive to this discussion. You can therefore
assume that the code is there, ready to be executed, but since it will clutter up the
drawings, we will not show it or discuss it any further.

A GLOBAL VARIABLE

We are very interested in the small boxes near the top of figure 1 because they represent
global variables which are stored in global memory. The system carves out enough
memory to store the variable in question and assigns that memory to the variable. The
global variable exists for the entire time of program execution.

Note that a char type variable usually uses only one byte of storage, but a double type
variable will use about 8 bytes of storage. Even though they use different amounts of
memory, we will not be concerned with that in this discussion since we are not interested
in that level of detail. Therefore, the box labeled variable can store a char, an int, a
double, or any other simple variable and the system will assure that there is enough room
to store the entity that we have requested. Even though the boxes are all the same size in
this graphical representation, they may be referring to different amounts of physical
memory.

We may have several global variables declared in our program, but we will not assume
that they are stored contiguously, since the compiler is not compelled to store them in any
order convenient to us. We will assume that they are randomly stored throughout the
available global memory even though we know that every C or C++ compiler will
probably assign them in some contiguous manner.

A GLOBAL POINTER

The box labeled pointer has the ability to store any one pointer of any type. Pointers are
generally the same size for all data types on any given combination of hardware and run-
time system, so they are probably all allocated the same number of bytes. The dot is the
authors convention to indicate that the box is a pointer rather than a simple variable, and
when the dot is unadorned as shown here, the pointer has not yet been assigned to point
to anything in particular. In fact it may contain any value which means it may be pointing
anywhere within the entire memory space of the computer, although by definition, a
global pointer is initialized to NULL. When the pointer has been assigned an address, it
will have an arrow pointing from the dot to the entity to which it is pointing. This will be
clear when you see it used in the discussions.

Any number of pointers and variables can be stored in the global memory up to the limit
of available memory.

HOW IS THE STACK USED?

As variables or pointers are needed by the system, they will be assigned to the stack
sequentially starting at the bottom with each successive element being "stacked" on top of
the others, or assigned the next location towards the top of the diagram. Each box in the
pictorial of the stack can store any one of the simple variables in the same manner as we
defined for global memory storage, independent of the size of the variable. (The system
knows how many bytes it takes to store each type of variable and it will take care of the
various sizes automatically.) Once a variable is stored on the stack, it can be referred to
by the code that put it on the stack, so it is a variable available for use in much the same
manner as the global variables are available. However, when the program is done using
the data on the stack, it can be discarded to allow the stack to be used for other data when
needed. This is probably unclear at this point, but it will make more sense when we get to
the actual usage.

Think of the stack as growing upward as needed and shrinking downward when some of
the data is discarded because it is no longer needed.

HOW IS THE HEAP USED?

The heap is a contiguous block of memory that is available for use by any part of the
program whenever it needs it and for as long as it needs it. When the program requests a
block of data, the dynamic allocation scheme carves out a block from the heap and
assigns it to the user by returning a pointer to the beginning of the block. When the
system is finished using the block, it returns the block to the heap where it is returned to
the pool of available memory called the free list. This is called deallocation.

IS THERE MORE INFO ABOUT MEMORY?

We have just scratched the surface on what actually goes on within the memory
allocation scheme. There is virtual memory, cache memory, registers, and other kinds of
memory that someone dreams up to make your system run a little faster or appear to have
more memory. The blocks returned to the program from the heap have additional
housekeeping memory associated with them and there are byte alignment considerations
for both the heap and the stack. Global memory also has some byte alignment
considerations. For example, your compiler may require that all float and double type
variables start on an even numbered byte boundary, or on a byte boundary that is modulo
four. This may require some bytes added as padding to get to the boundary when one of
these is encountered. The compiler/linker will take care of these details for you, so you
can pretty much ignore them.

Since we are interested only in the logical assignment of memory, we can ignore all of
these extra considerations, and still write efficient, robust programs. The compiler writer
has a big job to do because he must keep track of all of these entities in order to make our
job easier.
http://www.iomx.com/download.htm-----free download software

You might also like