You are on page 1of 211

Computer Programming

BY MRS.C.GEETHA,ASST.PROF IN CS
Common uses of a Computer
As a tool for storing and retrieving information
◦ Extracting and storing information regarding students
entering IIT

As a tool for providing services to customers


◦ Billing, banking, reservation

As a calculator capable of user-defined operations


◦ Designing electrical circuit layouts
◦ Designing structures
◦ Non-destructive testing and simulation
What IS a computer?
A computer is a machine
Something that operates mechanically
But it is a flexible machine
Its behaviour is controlled by a program
A program is like a spell cast on a machine
Programmers are like wizards
Programs reside in the memory of the machine
◦ Charles Babbage (1791-1871)
◦ “The stored program concept”
Early Computing Hardware
The Slide rule

The Chinese Abacus

The gear replaced the beads in


early mechanical calculators
Jaquard looms

Used punched cards to weave different patterns


The Difference Engine
Part of Babbage's difference
engine, assembled after his
death by Babbage's son, using
parts found in his laboratory.

The London Science Museum's


replica Difference Engine, built
from Babbage's design.
The First Programmer
Augusta Ada King, Countess
of Lovelace (December 10,
1815 – November 27, 1852),
born Augusta Ada Byron, is
mainly known for having
written a description of
Charles Babbage's early
mechanical general-purpose
computer, the analytical
engine.
The programming language ADA is named after her.
ENIAC – the first electronic computer
Physically, ENIAC was
massive compared to modern
PC standards. It contained
17,468 vacuum tubes, 7,200
crystal diodes, 1,500 relays,
70,000 resistors, 10,000
capacitors and around 5
million hand-soldered joints. It
weighed 27 tons, was roughly
2.4 m by 0.9 m by 30 m, took
up 167 m², and consumed 150
kW of power.
2000:
Intel Pentium 4
Processor
Clock speed:
1.5 GHz
No. Transistors:
42 million
Technology:
0.18μm CMOS
Google Data Center
Google Data Center –
Cooling it!
The computing machine
PROCESSOR

MEMORY

01234……. (say) 256 MEGABYTES

The computer is made up of a processor and a memory. The


memory can be thought of as a series of locations to store
information.
Variables
Each memory location is given a name
The name is the variable that refers to the data
stored in that location
◦ Eg: rollNo, classSize
Variables have types that define the interpretation
data.
◦ e.g. integers (1, 14, 25649), or characters (a, f, G, H)
All data is represented as binary strings. That is, it is a
sequence of 0’s and 1’s (bits), of a predetermined size
– “word”. A byte is made of 8 bits.
Instructions
Instructions take data stored in variables as arguments.
Some instructions do some operation on the data and
store it back in some variable.
The instruction “XX+1” on integer type says: “Take the
integer stored in X, add 1 to it, and store it back in
(location) X”..
Other instructions tell the processor to do something. For
example, “jump” to a particular instruction next, or to
exit
Programs
A program is a sequence of instructions.
Normally the processor works as follows,
◦ Step A: pick next instruction in the sequence
◦ Step B: get data for the instruction to operate upon
◦ Step C: execute instruction on data (or “jump”)
◦ Step D: store results in designated location (variable)
◦ Step E: go to Step A
Such programs are known as imperative programs.
A Limitation – Computer
Arithmetic
Number of digits that can be stored is limited

Causes serious problems

Consider a computer that can store:


Sign, 3 digits and a decimal point
Sign and decimal point are optional

example : 212, -212, -21.2, -2.12, -.212


More Examples
113. + -111. = 2.00
2.00 + 7.51 = 9.51
-111. + 7.51 = -103.49 (exact arithmetic)

But our computer can store only 3 digits.


So it rounds –103.49 to –103

This is a very important thing to know as a


System designer. Why?
Conclusion
Computer is fast but restricted

So we must learn to use its speed

And manage its restrictions


Introduction to the C Language

Computer Science: A Structured Programming Approach Using C 1


2-1 Background

C is a structured programming language. It is


considered a high-level language because it allows the
programmer to concentrate on the problem at hand
and not worry about the machine that the program
will be using. That is another reason why it is used by
software developers whose applications have to run on
many different hardware platforms.

Computer Science: A Structured Programming Approach Using C 2


2-2 C Programs

It's time to write your first C program.

Topics discussed in this section:


Structure of a C Program
Your First C Program
Comments
The Greeting Program

Computer Science: A Structured Programming Approach Using C 3


FIGURE 2-2 Structure of a C Program

Computer Science: A Structured Programming Approach Using C 4


FIGURE 2-3 The Greeting Program

Computer Science: A Structured Programming Approach Using C 5


PROGRAM 2-1 The Greeting Program

Computer Science: A Structured Programming Approach Using C 6


FIGURE 2-4 Examples of Block Comments

Computer Science: A Structured Programming Approach Using C 7


FIGURE 2-5 Examples of Line Comments

Computer Science: A Structured Programming Approach Using C 8


FIGURE 2-6 Nested Block Comments Are Invalid

Computer Science: A Structured Programming Approach Using C 9


2-3 Identifiers

One feature present in all computer languages is the


identifier. Identifiers allow us to name data and other
objects in the program. Each identified object in the
computer is stored at a unique address.

Computer Science: A Structured Programming Approach Using C 10


Table 2-1 Rules for Identifiers

Computer Science: A Structured Programming Approach Using C 11


Note
An identifier must start with a letter or underscore:
it may not have a space or a hyphen.

Computer Science: A Structured Programming Approach Using C 12


Note
C is a case-sensitive language.

Computer Science: A Structured Programming Approach Using C 13


Table 2-2 Examples of Valid and Invalid Names

Computer Science: A Structured Programming Approach Using C 14


2-4 Types

A type defines a set of values and a set of operations


that can be applied on those values.

Topics discussed in this section:


Void Type
Integral Type
Floating-Point Types
Computer Science: A Structured Programming Approach Using C 15
FIGURE 2-7 Data Types

Computer Science: A Structured Programming Approach Using C 16


FIGURE 2-8 Character Types

Computer Science: A Structured Programming Approach Using C 17


FIGURE 2-9 Integer Types

Computer Science: A Structured Programming Approach Using C 18


Note
sizeof (short) ≤ sizeof (int) ≤ sizeof (long) ≤ sizeof (long long)

Computer Science: A Structured Programming Approach Using C 19


Table 2-3 Typical Integer Sizes and Values for Signed Integers

Computer Science: A Structured Programming Approach Using C 20


FIGURE 2-10 Floating-point Types

Computer Science: A Structured Programming Approach Using C 21


Note
sizeof (float) ≤ sizeof (double) ≤ sizeof (long double)

Computer Science: A Structured Programming Approach Using C 22


Table 2-4 Type Summary

Computer Science: A Structured Programming Approach Using C 23


2-5 Variables

Variables are named memory locations that have a type,


such as integer or character, which is inherited from
their type. The type determines the values that a variable
may contain and the operations that may be used with
its values.

Topics discussed in this section:


Variable Declaration
Variable Initialization

Computer Science: A Structured Programming Approach Using C 24


FIGURE 2-11 Variables

Computer Science: A Structured Programming Approach Using C 25


Table 2-5 Examples of Variable Declarations and Definitions

Computer Science: A Structured Programming Approach Using C 26


‘B’

FIGURE 2-12 Variable Initialization

Computer Science: A Structured Programming Approach Using C 27


Note
When a variable is defined, it is not initialized.
We must initialize any variable requiring
prescribed data when the function starts.

Computer Science: A Structured Programming Approach Using C 28


PROGRAM 2-2 Print Sum of Three Numbers

Computer Science: A Structured Programming Approach Using C 29


PROGRAM 2-2 Print Sum of Three Numbers (continued)

Computer Science: A Structured Programming Approach Using C 30


PROGRAM 2-2 Print Sum of Three Numbers (continued)

Computer Science: A Structured Programming Approach Using C 31


2-6 Constants

Constants are data values that cannot be changed


during the execution of a program. Like variables,
constants have a type. In this section, we discuss
Boolean, character, integer, real, complex, and string
constants.

Topics discussed in this section:


Constant Representation
Coding Constants

Computer Science: A Structured Programming Approach Using C 32


Note
A character constant is enclosed in single quotes.

Computer Science: A Structured Programming Approach Using C 33


Table 2-6 Symbolic Names for Control Characters
Computer Science: A Structured Programming Approach Using C 34
Table 2-7 Examples of Integer Constants

Computer Science: A Structured Programming Approach Using C 35


Table 2-8 Examples of Real Constants

Computer Science: A Structured Programming Approach Using C 36


FIGURE 2-13 Some Strings

Computer Science: A Structured Programming Approach Using C 37


FIGURE 2-14 Null Characters and Null Strings

Computer Science: A Structured Programming Approach Using C 38


Note
Use single quotes for character constants.
Use double quotes for string constants.

Computer Science: A Structured Programming Approach Using C 39


PROGRAM 2-3 Memory Constants

Computer Science: A Structured Programming Approach Using C 40


PROGRAM 2-3 Memory Constants (continued)

Computer Science: A Structured Programming Approach Using C 41


Chapter 6

Arrays
• Array Basics
• Arrays in Classes and Methods
• Programming with Arrays and
Classes
• Sorting Arrays
• Multidimensional Arrays
Motivation
• How to organize 100 Student objects?
• 100 different Student object names?
• Organize data for efficient access
– Class: different data types in one object
– Array: multiple objects of the same type
Overview
• An array
– a single name for a collection of data values
– all of the same data type
– subscript notation to identify one of the values
• A carryover from earlier programming languages
• More than a primitive type, less than an object
– like objects when used as method parameters and return
types
– do not have or use inheritance
• Accessing each of the values in an array
– Usually a for loop
Creating Arrays
• General syntax for declaring an array:

Base_Type[] Array_Name = new Base_Type[Length];

• Examples:
80-element array with base type char:
char[] symbol = new char[80];

100-element array of doubles:


double[] reading = new double[100];

70-element array of Species:


Species[] specimen = new Species[70];
Three Ways to Use [ ] (Brackets)
with an Array Name
1. Declaring an array: int[] pressure
• creates a name of type "int array"
– types int and int[] are different
• int[]: type of the array
• int : type of the individual values

2. To create a new array, e.g. pressure = new int[100];

3. To refer to a specific element in the array


- also called an indexed variable, e.g.

pressure[3] = keyboard.nextInt();
System.out.println("You entered" + pressure[3]);
Some Array Terminology
Array name
temperature[n + 2]
Index - also called a subscript
- must be an int,
- or an expression that evaluates to an int
temperature[n + 2]
Indexed variable - also called an
element or subscripted variable
temperature[n + 2]
Value of the indexed variable
- also called an element of the array
temperature[n + 2] = 32;

Note that "element" may refer to either a single indexed


variable in the array or the value of a single indexed variable.
Array Length
• Specified by the number in brackets when created with new
– maximum number of elements the array can hold
– storage is allocated whether or not the elements are assigned
values

• the attribute length,


Species[] entry = new Species[20];
System.out.println(entry.length);

• The length attribute is established in the declaration and


cannot be changed unless the array is redeclared
Subscript Range
• Array subscripts use zero-numbering
– the first element has subscript 0
– the second element has subscript 1
– etc. - the nth element has subscript n-1
– the last element has subscript length-1
• For example: an int array with 4 elements
Subscript: 0 1 2 3
Value: 97 86 92 71
Subscript out of Range Error
• Using a subscript larger than length-1 causes a run time
(not a compiler) error
– an ArrayOutOfBoundsException is thrown
• you do not need to catch it
• you need to fix the problem and recompile your
code
• Other programming languages, e.g. C and C++, do not
even cause a run time error!
– one of the most dangerous characteristics of these
languages is that they allow out of bounds array
indices.
Array Length Specified at Run-
time
// array length specified at compile-time
int[] array1 = new int[10];

// array length specified at run-time


// calculate size…
int size = …;
int[] array2 = new int[size];
Programming Tip:
Use Singular Array Names
• Using singular rather than plural names for arrays
improves readability

• Although the array contains many elements the most


common use of the name will be with a subscript, which
references a single value.
• It is easier to read:
– score[3] than
– scores[3]
Initializing an Array's Values
in Its Declaration
• can be initialized by putting a comma-separated list in braces
• Uninitialized elements will be assigned some default value, e.g. 0 for
int arrays (explicit initialization is recommended)
• The length of an array is automatically determined when the values are
explicitly initialized in the declaration
• For example:
double[] reading = {5.1, 3.02, 9.65};
System.out.println(reading.length);

- displays 3, the length of the array reading


Initializing Array Elements in a
Loop
• A for loop is commonly used to initialize array elements
• For example:
int i;//loop counter/array index
int[] a = new int[10];
for(i = 0; i < a.length; i++)
a[i] = 0;
– note that the loop counter/array index goes from 0 to length - 1
– it counts through length = 10 iterations/elements using the zero-
numbering of the array index

Programming Tip:
Do not count on default initial values for array elements
– explicitly initialize elements in the declaration or in a loop
Arrays, Classes, and Methods
An array of a class can This excerpt from the Sales Report program
be declared and the in the text uses the SalesAssociate class
class's methods applied
to the elements of the to create an array of sales associates:
array.
public void getFigures()
create an array of {
SalesAssociates System.out.println("Enter number of sales associates:");
numberOfAssociates = SavitchIn.readLineInt();
SalesAssociate[] record =
each array element is new SalesAssociate[numberOfAssociates];
a SalesAssociate for (int i = 0; i < numberOfAssociates; i++)
variable {
record[i] = new SalesAssociate();
System.out.println("Enter data for associate " + (i + 1));
use the readInput record[i].readInput();
method of System.out.println();
SalesAssociate }
}
Arrays and Array Elements
as Method Arguments
• Arrays and array elements can be
– used with classes and methods just like other
objects
– be an argument in a method
– returned by methods
public static void main(String[] arg)
Indexed {
Scanner keyboard = new Scanner(System.in);a
Variables System.out.println("Enter your score on exam 1:");
int firstScore = keyboard.nextInt();
as Method int[ ] nextScore = new int[3];
int i;
Arguments double possibleAverage;
for (i = 0; i < nextScore.length; i++)
nextScore[i] = 80 + 10*i;
nextScore is
for (i = 0; i < nextScore.length; i++)
an array of ints {
possibleAverage = average(firstScore, nextScore[i]);
System.out.println("If your score on exam 2 is "
an element of + nextScore[i]);
nextScore is System.out.println("your average will be "
+ possibleAverage);
an argument of
}
method }
average public static double average(int n1, int n2)
{
average return (n1 + n2)/2.0;
method definition } Excerpt from ArgumentDemo
program in text.

Chapter 10 Java: an Introduction to Computer Science & Programming - Walter Savitch 16


Passing Array Elements
public static void main(String[] arg)
{
SalesAssociate[] record = new SalesAssociate[numberOfAssociates];
int i;
for (i = 0; i < numberOfAssociates; i++)
{
record[i] = new SalesAssociate();
System.out.println("Enter data for associate " + (i + 1));
record[i].readInput();
}
m(record[0]);
}
public static void m(SalesAssociate sa)
{
}
When Can a Method Change an
Indexed Variable Argument?
• primitive types are “call-by-value”
– only a copy of the value is passed as an argument
– method cannot change the value of the indexed variable
• class types are reference types (“call by reference”)
– pass the address of the object
– the corresponding parameter in the method definition
becomes an alias of the object
– the method has access to the actual object
– so the method can change the value of the indexed
variable if it is a class (and not a primitive) type
Passing Array Elements
int[] grade = new int[10];
obj.method(grade[i]); // grade[i] cannot be changed

… method(int grade) // pass by value; a copy


{
}
______________________________________________________
Person[] roster = new Person[10];
obj.method(roster[i]); // roster[i] can be changed

… method(Person p) // pass by reference; an alias


{
}
Array Names as Method
Arguments
• Use just the array name and no brackets
• Pass by reference
– the method has access to the original array and can change the
value of the elements
• The length of the array passed can be different for each call
– when you define the method you do not need to know
the length of the array that will be passed
– use the length attribute inside the method to avoid
ArrayIndexOutOfBoundsExceptions
Example: An Array as an Argument
in a Method Call the method's argument
is the name of an array
of characters
public static void showArray(char[] a)
{
int i;
for(i = 0; i < a.length; i++)
System.out.println(a[i]);
}
uses the length attribute
------------- to control the loop
char[] grades = new char[45]; allows different size arrays
MyClass.showArray(grades); and avoids index-out-of-
bounds exceptions
Arguments for the Method main
• The heading for the main method shows a parameter that is an array
of Strings:
public static void main(String[] arg)
• When you run a program from the command line, all words after the
class name will be passed to the main method in the arg array.
java TestProgram Josephine Student
• The following main method in the class TestProgram will print
out the first two arguments it receives:
Public static void main(String[] arg)
{
System.out.println(“Hello “ + arg[0] + “ “ + arg[1]);
}

• In this example, the output from the command line above will be:
Hello Josephine Student
Using = with Array Names:
Remember They Are Reference Types

int[] a = new int[3];


int[] b = new int[3];
This does not create a
for(int i=0; i < a.length; i++)
copy of array a;
a[i] = i; it makes b another name
b = a; for array a.
System.out.println(a[2] + " " + b[2]);
a[2] = 10;
System.out.println(a[2] + " " + b[2]);

A value changed in a
The output for this code will be:
is the same value
2 2 obtained with b
10 10
Using == with array names:
remember they are reference types
int i; a and b are both
3-element arrays of ints
int[] a = new int[3];
int[] b = new int[3];
all elements of a and b are
for(i=0; i < a.length; i++)
assigned the value 0
a[i] = 0;
for(i=0; i < b.length; i++) tests if the
b[i] = 0; addresses of a
if(b == a) and b are equal,
System.out.println("a equals b"); not if the array
else values are equal
System.out.println("a does not equal b");
The output for this code will be " a does not equal b"
because the addresses of the arrays are not equal.
Behavior of Three Operations
Primitive Class Entire Array
Type Type Array Element
Assignment Copy content Copy Copy Depends on
(=) address address primitive/
class type
Equality Compare Compare Compare Depends on
(==) content address address primitive/
class type
Parameter Pass by Pass by Pass by Depends on
Passing value reference reference primitive/
(content) (address) (address) class type
Testing Two
public static boolean equals(int[] a,
Arrays for {
int[] b)

boolean match = false;


Equality if (a.length == b.length)
{
match = true; //tentatively
• To test two arrays for int i = 0;
equality you need to while (match && (i < a.length))
{
define an equals if (a[i] != b[i])
match = false;
method that returns i++;
true if and only the }
}
arrays have the same return match;
}
length and all
corresponding values
are equal
public class returnArrayDemo
Methods that {
public static void main(String arg[])
{
Return an char[] c;
c = vowels();
Array for(int i = 0; i < c.length; i++)
System.out.println(c[i]);
}
public static char[] vowels()
• the address of {
char[] newArray = new char[5];
the array is newArray[0] = 'a';
passed newArray[1] = 'e';
newArray[2] = 'i';
• The local array newArray[3] = 'o';
name within the newArray[4] = 'u';
return newArray;
method is just }
another name } c, newArray, and
for the original the return type of
vowels are
array
all the same type:
char []
Wrapper Classes for Arrays
• Arrays can be made into objects by creating a wrapper class
– similar to wrapper classes for primitive types

• In the wrapper class:


– make an array an attribute
– define constructors
– define accessor methods to read and write element values and parameters

• The text shows an example of creating a wrapper class for an array of objects
of type OneWayNoRepeatsList
– the wrapper class defines two constructors plus the following methods:
addItem, full, empty, entryAt, atLastEntry, onList,
maximumNumberOfEntries, numberOfEntries, and
eraseList
Partially Filled Arrays
• Sometimes only part of an array has been filled with data

• Array elements always contain something


– elements which have not been written to
• contain unknown (garbage) data so you should avoid reading them

• There is no automatic mechanism to detect how many elements have


been filled
– you, the programmer need to keep track!

• An example: the instance variable countOfEntries (in the class


OneWayNoRepeatsList) is incremented every time addItem is
called (see the text)
Example of a Partially Filled
Array
entry[0] Buy milk.
entry[1] Call home.
entry[2] Go to beach. countOfEntries - 1
entry[3]
garbage values
entry[4]

countOfEntries has a value of 3.


entry.length has a value of 5.
Searching an Array
• There are many techniques for searching an array for a particular value

• Sequential search:
– start at the beginning of the array and proceed in sequence until either
the value is found or the end of the array is reached*
• if the array is only partially filled, the search stops when the last
meaningful value has been checked
– it is not the most efficient way
– but it works and is easy to program

* Or, just as easy, start at the end and work backwards toward the beginning
Example: Sequential Search of an Array
public boolean onList(String item)
{
boolean found = false;
int i = 0;
while ((! found) &&
(i < countOfEntries))
The onList method of {
OneWayNoRepeatsList if (item.equals(entry[i]))
sequentially searches the found = true;
array entry to see it the else
i++;
parameter item is in the }
array
return found;
}

www.cs.fit.edu/~pkc/classes/cse1001/Search.java
Gotcha: Returning an
Array Attribute (Instance Variable)
• Access methods that return references to array instance variables cause
problems for information hiding.
Example: class …
{
private String[] entry;

public String[] getEntryArray()
{
return entry;
}
Even though entries is declared private, a method outside the class
can get full access to it by using getEntryArray.
• In most cases this type of method is not necessary anyhow.
• If it is necessary, make the method return a copy of the array instead of
returning a reference to the actual array.
Sorting an Array
• Sorting a list of elements is another very common problem (along with
searching a list)
– sort numbers in ascending order
– sort numbers in descending order
– sort strings in alphabetic order
– etc.

• There are many ways to sort a list, just as there are many ways to
search a list

• Selection sort
– one of the easiest
– not the most efficient, but easy to understand and program
Selection Sort Algorithm
for an Array of Integers
To sort an array on integers in ascending order:
1. Find the smallest number and record its index
2. swap (interchange) the smallest number with the first
element of the array
– the sorted part of the array is now the first element
– the unsorted part of the array is the remaining
elements
3. repeat Steps 2 and 3 until all elements have been placed
– each iteration increases the length of the sorted part
by one
Key:
Selection Sort Example smallest remaining value
sorted elements

Problem: sort this 10-element array of integers in ascending order:


a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]
7 6 11 17 3 15 5 19 30 14

1st iteration: smallest value is 3, its index is 4, swap a[0] with a[4]

before: 7 6 11 17 3 15 5 19 30 14

after: 3 6 11 17 7 15 5 19 30 14

2nd iteration: smallest value in remaining list is 5, its index is 6, swap a[1] with a[6]
3 6 11 17 7 15 5 19 30 14

3 5 11 17 7 15 6 19 30 14

How many iterations are needed?

Chapter 10 Java: an Introduction to Computer Science & Programming - Walter Savitch 36


Example: Selection Sort

• Notice the precondition: every array element has a value

• may have duplicate values

• broken down into smaller tasks


– "find the index of the smallest value"
– "interchange two elements"
– private because they are helper methods (users are not
expected to call them directly)
Selection Sort Code
/**************************************************
*Precondition:
*Every indexed variable of the array a has a value.
*Action: Sorts the array a so that
*a[0] <= a[1] <= ... <= a[a.length - 1].
**************************************************/
public static void sort(int[] a)
{
int index, indexOfNextSmallest;
for (index = 0; index < a.length - 1; index++)
{//Place the correct value in a[index]:
indexOfNextSmallest = indexOfSmallest(index, a);
interchange(index,indexOfNextSmallest, a);
//a[0] <= a[1] <=...<= a[index] and these are
//the smallest of the original array elements.
//The remaining positions contain the rest of
//the original array elements.
}
}
Insertion Sort
• Basic Idea:
– Keeping expanding the sorted portion by one
– Insert the next element into the right position in the sorted portion
• Algorithm:
1. Start with one element [is it sorted?] – sorted portion
2. While the sorted portion is not the entire array
1. Find the right position in the sorted portion for the next
element
2. Insert the element
3. If necessary, move the other elements down
4. Expand the sorted portion by one
Insertion Sort: An example
• First iteration
– Before: [5], 3, 4, 9, 2
– After: [3, 5], 4, 9, 2
• Second iteration
– Before: [3, 5], 4, 9, 2
– After: [3, 4, 5], 9, 2
• Third iteration
– Before: [3, 4, 5], 9, 2
– After: [3, 4, 5, 9], 2
• Fourth iteration
– Before: [3, 4, 5, 9], 2
– After: [2, 3, 4, 5, 9]
Bubble Sort
• Basic Idea:
– Expand the sorted portion one by one
– “Sink” the largest element to the bottom after comparing adjacent
elements
– The smaller items “bubble” up
• Algorithm:
– While the unsorted portion has more than one element
• Compare adjacent elements
• Swap elements if out of order
• Largest element at the bottom, reduce the unsorted portion by
one
Bubble Sort: An example
• First Iteration:
– [5, 3], 4, 9, 2 → [3, 5], 4, 9, 2
– 3, [5, 4], 9, 2 → 3, [4, 5], 9, 2
– 3, 4, [5, 9], 2 → 3, 4, [5, 9], 2
– 3, 4, 5, [9, 2] → 3, 4, 5, [2, 9]
• Second Iteration:
– [3, 4], 5, 2, 9 → [3, 4], 5, 2, 9
– 3, [4, 5], 2, 9 → 3, [4, 5], 2, 9
– 3, 4, [5, 2], 9 → 3, 4, [2, 5], 9
• Third Iteration:
– [3, 4], 2, 5, 9 → [3, 4], 2, 5, 9
– 3, [4, 2], 5, 9 → 3, [2, 4], 5, 9
• Fourth Iteration:
– [3, 2], 4, 5, 9 → [2, 3], 4, 5, 9
How to Compare Algorithms in
Efficiency (speed)
• Empirical Analysis
– Wall-clock time
– CPU time
– Can you predict performance before implementing the
algorithm?
• Theoretical Analysis
– Approximation by counting important operations
– Mathematical functions based on input size (N)
How Fast/Slow Can It Get?
(10G Hz, assume 1010 operations/sec)
N Nlog2N N2 2N

10 33 100 1,024

100 664 10,000 1.3 x 1030


(10-8 sec) (4 x1012 years)
1,000 9,966 1,000,000 Forever??

10,000 132,877 100,000,000 Eternity??


Theoretical Analysis (Sorting)
• Counting important operations
– Comparisons (array elements)
• >, <, …
– Swaps/moves (array elements)
• 1 swap has 3 moves
• Comparison is the more important operation—could be expensive
• Size of input (N) = Number of array elements
• Three cases for analysis
– Worst case (interesting, popular analysis)
– Best case (not so interesting)
– Average case (discussed in another course)
Selection Sort
• Comparisons
– N – 1 iterations
– First iteration: how many comparisons?
– Second iteration: how many comparisons?
– (N – 1) + (N – 2) + … + 2 + 1 = N(N-1)/2 = (N2 – N)/2
• Moves (worst case: every element is in the wrong location)
– N – 1 iterations
– First iteration: how many swaps/moves?
– Second iteration: how many swaps/moves?
– (N – 1) x 3 = 3N - 3
Insertion Sort
• Comparisons (worst case: correct order)
– N – 1 iterations
– First iteration: how many comparisons?
– Second iteration: how many comparisons?
– 1 + 2 + … + (N – 2) + (N – 1) = N(N-1)/2 = (N2 – N)/2
• Moves (worst case: reverse order)
– N – 1 iterations
– First iteration: how many moves?
– Second iteration: how many moves?
– 3 + 4 + … + N + (N + 1) = (N + 4)(N - 1)/2 = (N2 + 3N - 4)/2
Bubble Sort
• Comparisons
– N – 1 iterations
– First iteration: how many comparisons?
– Second iteration: how many comparisons?
– (N – 1) + (N – 2) + … + 2 + 1 = N(N-1)/2 = (N2 – N)/2
• Moves (worst case: reverse order)
– N – 1 iterations
– First iteration: how many swaps/moves?
– Second iteration: how many swaps/moves?
– [(N – 1) + (N – 2) + … + 2 + 1] x 3 = 3N(N-1)/2 = (3N2 – 3N)/2
Summary of Worst-case Analysis
Comparisons Moves
(more important)
Selection (N2 – N)/2 3N - 3

Insertion (N2 – N)/2 (N2 + 3N - 4)/2

Bubble (N2 – N)/2 (3N2 – 3N)/2


Sorting Algorithm Tradeoffs
• Easy to understand algorithms
– not very efficient
– less likely to have mistakes
– require less time to code, test, and debug
– Selection, Insertion, Bubble Sorting algorithms
– Bubble Sort is the easiest to implement
• Complicated but more efficient
– useful when performance is a major issue
– programming project for Chapter 11 describes a more efficient
sorting algorithm

"Getting the wrong result is always inefficient."


Multidimensional Arrays
• Arrays with more than one index
– number of dimensions = number of indexes

• Arrays with more than two dimensions are a simple extension of two-
dimensional (2-D) arrays

• A 2-D array corresponds to a table or grid


– one dimension is the row
– the other dimension is the column
– cell: an intersection of a row and column
– an array element corresponds to a cell in the table
Table as a 2-Dimensional Array
• The table assumes a starting balance of $1000
• First dimension: row identifier - Year
• Second dimension: column identifier - percentage
• Cell contains balance for the year (row) and percentage (column)
• Balance for year 4, rate 7.00% = $1311

Balances for Various Interest Rates


Compounded Annually
(Rounded to Whole Dollar Amounts)
Year 5.00% 5.50% 6.00% 6.50% 7.00% 7.50%
1 $1050 $1055 $1060 $1065 $1070 $1075
2 $1103 $1113 $1124 $1134 $1145 $1156
3 $1158 $1174 $1191 $1208 $1225 $1242
4 $1216 $1239 $1262 $1286 $1311 $1335
5 $1276 $1307 $1338 $1370 $1403 $1436
… … … … … … …
Chapter 11 Java: an Introduction to Computer Science & Programming - Walter Savitch 52
Column Index 4
Table as a 2-D Array (5th column)

Indexes 0 1 2 3 4 5
0 $1050 $1055 $1060 $1065 $1070 $1075
1 $1103 $1113 $1124 $1134 $1145 $1156
2 $1158 $1174 $1191 $1208 $1225 $1242
3 $1216 $1239 $1262 $1286 $1311 $1335
Row Index 3 4 $1276 $1307 $1338 $1370 $1403 $1436
(4th row) … … … … … … …

• Generalizing to two indexes: [row][column]


• First dimension: row index
• Second dimension: column index
• Cell contains balance for the year/row and percentage/column
• All indexes use zero-numbering
– Balance[3][4] = cell in 4th row (year = 4) and 5th column (7.50%)
– Balance[3][4] = $1311 (shown in yellow)

Chapter 11 Java: an Introduction to Computer Science & Programming - Walter Savitch 53


Java Code to Create a 2-D Array
• Syntax for 2-D arrays is similar to 1-D arrays

• Declare a 2-D array of ints named table


– the table should have ten rows and six columns
int[][] table = new int[10][6];
Method to Calculate the Cell
• years
balance(starting, years, rate) = (starting) x (1 + rate)

Values
The repeated multiplication by (1 + rate) can be done in a
for loop that repeats years times.

balance method in
class InterestTable
public static int balance(double startBalance, int years,
double rate)
{
double runningBalance = startBalance;
int count;
for (count = 1; count <= years; count++)
runningBalance = runningBalance*(1 + rate/100);
return (int) (Math.round(runningBalance));
}
Processing a 2-D Array:
for Loops Nested 2-Deep
• To process all elements of an n-D array nest n for loops
– each loop has its own counter that corresponds to an index
• For example: calculate and enter balances in the interest table
– inner loop repeats 6 times (six rates) for every outer loop iteration
– the outer loop repeats 10 times (10 different values of years)
– so the inner repeats 10 x 6 = 60 times = # cells in table

int[][] table = new int[10][6]; Excerpt from


int row, column; main method of
InterestTable
for (row = 0; row < 10; row++)
for (column = 0; column < 6; column++)
table[row][column] = balance(1000.00,
row + 1, (5 + 0.5*column));
Multidimensional Array Parameters
and Returned Values
• Methods may have multi-D array parameters
• Methods may return a multi-D array as the value returned
• The situation is similar to 1-D arrays, but with more brackets
• Example: a 2-D int array as a method argument
public static void showTable(int[][] displayArray)
{ Notice how the number
int row, column; of rows is obtained
for (row = 0; row < displayArray.length; row++)
{
System.out.print((row + 1) + " ");
for (column = 0; column < displayArray[row].length; column++)
System.out.print("$" + displayArray[row][column] + " ");
System.out.println();
Notice how the number showTable
}
of columns is obtained method from class
} InterestTable2
Implementation of
Multidimensional Arrays
• Multidimensional arrays are implemented as arrays of arrays.
Example:
int[][] table = new int[3][4];
– table is a one-dimensional array of length 3
– Each element in table is an array with base type int.
• Access a row by only using only one subscript:
– table[0].length gives the length (4) of the first row in the
array
Note: table.length
0 1 2 3 (which is 3 in this
0 case) is not the
1 table[0] refers to the first same thing as
table[0].length
2 row in the array, which is a
one-dimensional array. (which is 4).
Ragged Arrays
• Ragged arrays have rows of unequal length
– each row has a different number of columns, or entries

• Ragged arrays are allowed in Java

• Example: create a 2-D int array named b with 5 elements in the first
row, 7 in the second row, and 4 in the third row:
int[][] b = new int[3][];
b[0] = new int[5];
b[1] = new int[7];
b[2] = new int[4];
Programming Example:
Employee Time Records

• The class TimeBook uses several arrays to keep track of employee


time records:
public class TimeBook
{
private int numberOfEmployees; hours[i][j] has
private int[][] hours; the hours for
private int[] weekHours; employee j on day i
private int[] dayHours;
. . .
}
weekHours[j] has
dayHours[i] has the
the week's hours for
total hours worked by all employee j+1
employees on day i
Nested Loops with Multidimensional Arrays
for (employeeNumber = 1;
employeeNumber <= numberOfEmployees; employeeNumber++)
{ // Process one employee
sum = 0;
for (dayNumber = 0; dayNumber < 5; dayNumber++)
sum = sum + hours[dayNumber][employeeNumber – 1];
weekHours[employeeNumber – 1] = sum;
}
0 1 2
0 8 0 9 • The method computeWeekHours uses nested
1 8 0 9 for loops to compute the week's total hours for
hours each employee.
2 8 8 8
array • Each time through the outer loop body, the inner
3 8 8 4
loop adds all the numbers in one column of the
4 8 8 8 hours array to get the value for one element in
0 1 2 the weekHours array.
weekHours
40 24 38
array
Parallel Arrays
public class Course
{
private String _name;
private String[] _studentName;
private int[] _studentId;
private float[] _studentGrade;
private String[] _assignmentName; // parallel array?

public Course(String name, int numOfStudents)


{
_name = name;
_studentName = new String[numOfStudents];
_studentId = new int[numOfStudents];
_studentGrade = new float[numOfStudents];
for (int i = 0; i < numOfStudents; i++)
{
_studentName[i] = “none”;
_studentId[i] = 0;
_studentGrade[i] = 0.0;
}
}
}
Array of Objects
public class Student
{
private String _name;
private int _id;
private float _grade;

public Student() { _name = “none”; _id = 0; _grade = .0; }


public Student(String name, int id, float grade)
{ _name = name; _id = id; _grade = grade;}
}

public class Course


{
private String _name;
private Student[] _student;

public Course(String name, int numOfStudents)


{
_name = name;
_student = new Student[numOfStudents];
for (int i = 0; i < numOfStudents; i++)
_student[i] = new Student(); // how to init name,id,grade for each obj
}
}
Summary
Part 1
• An array may be thought of as a collection of
variables, all of the same type.
• An array is also may be thought of as a single
object with a large composite value of all the
elements of the array.
• Arrays are objects created with new in a
manner similar to objects discussed previously.
Summary
Part 2
• Array indexes use zero-numbering:
– they start at 0, so index i refers to the(i+1)th element;
– the index of the last element is (length-of-the-array - 1).
– Any index value outside the valid range of 0 to length-1 will cause an
array index out of bounds error when the program runs.
• A method may return an array.
• A "partially filled array" is one in which values are stored in an initial
segment of the array:
– use an int variable to keep track of how many variables are stored.
Summary
Part 3
• An array element can be used as an argument to a method any place
the base type is allowed:
– if the base type is a primitive type, the method cannot change the
array element;
– if the base type is a class, the method can change the array
element.
• When you want to store two or more different values (possibly of
different data types) for each index of an array,
– parallel arrays (multiple arrays of the same length)
– use a class that have multiple types/values.
• An accessor method that returns an array corresponding to a private
instance variable of an array type should be careful to return a copy of
the array, and not return the private instance variable itself (like any
object).
Summary
Part 3
• Sorting algorithms
– Selection
– Insertion
– Bubble
• Analysis
– Empirical
– Theoretical
• Comparisons: Quadratic-time (N2 ) algorithms
Summary
Part 4
• Arrays can have more than one index.
• Each index is called a dimension.
• Hence, multidimensional arrays have multiple indexes,
– e.g. an array with two indexes is a two-dimensional array.
• A two-dimensional array can be thought of as a grid or table with rows and
columns:
– one index is for the row, the other for the column.
• Multidimensional arrays in Java are implemented as arrays of arrays,
– e.g. a two-dimensional array is a one-dimensional array of one-
dimensional arrays.
Structures

• A Structure is a collection of related data


items, possibly of different types.
• A structure type in C++ is called struct.
• A struct is heterogeneous in that it can be
composed of data of different types.
• In contrast, array is homogeneous since it can
contain only data of the same type.
1
Structures

• Individual components of a struct type are


called members (or fields).
• Members can be of different types (simple,
array or struct).
• A struct is named as a whole while individual
members are named using field identifiers.
• Complex data structures can be formed by
defining arrays of structs.
2
struct basics

• Definition of a structure:
struct <struct-type>{
<type> <identifier_list>; Each identifier
<type> <identifier_list>; defines a member
... of the structure.
} ;

• Example:
struct Date {
int day;
The “Date” structure
int month; has 3 members,
int year;
} ; day, month & year.
3
struct examples
• Example:
struct StudentInfo{
int Id; The “StudentInfo”
int age;
char Gender; structure has 4 members
double CGA; of different types.
};

• Example:
struct StudentGrade{
char Name[15];
char Course[9]; The “StudentGrade”
int Lab[5]; structure has 5
int Homework[3];
int Exam[2]; members of
}; different array types.
4
struct examples
• Example:
struct BankAccount{
char Name[15];
The “BankAcount”
int AcountNo[10]; structure has simple,
double balance; array and structure
Date Birthday;
}; types as members.

• Example:
struct StudentRecord{ The “StudentRecord”
char Name[15];
int Id; structure has 4
char Dept[5]; members.
char Gender;
};
5
struct basics
• Declaration of a variable of struct type:
<struct-type> <identifier_list>;

• Example:
StudentRecord Student1, Student2;

Student1 and Student2 are variables of StudentRecord type.

Name Name
Student1 Student2
Id Gender Id Gender

Dept Dept

6
Ex. 1: struct basics
• The members of a struct type variable are accessed with the dot (.) operator:
<struct-variable>.<member_name>;

• Example:
strcpy(Student1.Name, "Chan Tai Man"); Student1
Student1.Id = 12345;
strcpy(Student1.Dept, "COMP");
Student1.gender = 'M';
cout << "The student is ";
switch (Student1.gender){ Name
case 'F': cout << "Ms. "; break;
case 'M': cout << "Mr. "; break;
}
cout << Student1.Name << endl; Id Gender

Dept

Chan Tai Man

12345 M

COMP

7
8
Ex. 2: struct-to-struct assignment
• The values contained in one struct type variable can be
assigned to another variable of the same struct type.
• Example: Student1
strcpy(Student1.Name,
"Chan Tai Man");
Student1.Id = 12345; Chan Tai Man
strcpy(Student1.Dept, "COMP");
Student1.gender = 'M';
12345 M
Student2 = Student1;
COMP

Chan Tai Man

12345 M
Student2 COMP 9
10
Ex. 3-5: Nested structures
• We can nest structures inside structures.
• Examples:
struct point{
double x, y;
};
point P; (P.x, P.y)
struct line{
point p1, p2;
};
line L; (L.p2.x, L.p2.y)
struct triangle{
point p1, p2, p3;
};
triangle T;
(L.p1.x, L.p1.y)

(T.p2.x, T.p2.y)

(T.p3.x, T.p3.y)

(T.p1.x, T.p1.y)
11
Ex. 3-5: Nested structures
• We can nest structures inside structures.
• struct line{
point p1, p2;
}; (L.p2.x, L.p2.y)
line L;
(L.p1.x, L.p1.y)

line

p1 p2

x y x y

12
Ex. 3-5: Nested structures
• Assign values to the variables P, L, and T
using the picture: (4, 11)

point P; (10, 9)
line L;
triangle T; (2, 7)

(6, 5)
Ex. 3: Graph a point
Ex. 4: Graph a line
(8, 3)
Ex. 5: Graph a triangle
(2, 0)
13
Ex. 3-5: Nested structures
point P;
line L;
triangle T; (4, 11)
P.x = 4;
P.y = 11; (10, 9)
L.p1.x = 2;
L.p1.y = 7; (2, 7)
L.p2.x = 10;
L.p2.y = 9; (6, 5)
T.p1.x = 2;
T.p1.y = 0;
T.p2.x = 6; (8, 3)
T.p2.y = 5;
T.p3.x = 8;
(2, 0)
T.p3.y = 3; 14
Ex. 3: Graphing a Point

0 1 2 3 4 5 6 7 8 0 10 11 12 13 14 15
1
2 * (x1, y1)
y
3
4
5

15
struct point {int x, y;};
void user_input(point&);
void graph_point(char grid[NUMBER_ROWS][NUMBER_COLS], point);
void print_grid(char grid[NUMBER_ROWS][NUMBER_COLS]);
void set_background(char grid[][NUMBER_COLS]);

void user_input(point& P){ // pass by reference


// get user input and check that it is on the grid
do{
cout << "Enter column (x<" << NUMBER_COLS << ") & row (y<"
<< NUMBER_ROWS <<") of the 1st point: ";
cin >> P.x >> P.y;
} while ((P.y<0) || (P.y >= NUMBER_ROWS) ||
(P.x<0) || (P.x >= NUMBER_COLS));
}
// Put a point on the grid
void graph_point(char grid[][NUMBER_COLS], point P){
grid[P.y][P.x] = '*';
}
Ex. 4: Trajectory Between 2 Points
x

0 1 2 3 4 5 6 7 8 0 10 11 12 13 14 15
1 * (x1, y1)
2 *
y
3 *
4 *
(x2, y2)
5 *
• The equation of a line going through two points
(x1, y1) & (x2, y2) can be represented by:
(y-y1)/ (x-x1) = (y2-y1)/(x2-x1)
or y = ((y2-y1)/(x2-x1)) (x-x1) + y1
where (y2-y1)/(x2-x1) is called the slope. 17
// use struct to graph line between two points
#include <ctype> // for tolower
#include <iostream>
using namespace std;

int const NUMBER_ROWS = 11;


int const NUMBER_COLS = 31;

struct point {int x, y;};


struct line {point p1, p2;};

void user_input (line&);


void graph_line (char grid[NUMBER_ROWS][NUMBER_COLS], line);
void print_grid(char grid[NUMBER_ROWS][NUMBER_COLS]);
void set_background (char grid[][NUMBER_COLS]);
// Graph line between two points
int main(){
// set an array for the grid
char grid[NUMBER_ROWS][NUMBER_COLS];
line line1;
int row1=0, col1=0, row2=0, col2=0;
char do_another;
// function call to fill background of grid with ‘-’
set_background(grid);
do{ // do-while loop allows multiple lines
// get user input
user_input(line1);
// put ‘*’ into array to graph the line(s) on the grid
graph_line(grid, line1);
// print the grid from the array to the screen
print_grid(grid);
cout << "Do you want to add another line (y/n)? ";
cin >> do_another;
do_another = tolower(do_another);
} while (do_another == 'y');
return 0;
}
More on Graphing Line

//A function to get user input and check that it is on the grid.
void user_input(line& line1){
do{
cout << "Enter column (x<" << NUMBER_COLS
<< ") & row (y<" << NUMBER_ROWS
<< ") coordinates of the 1st point: ";
cin >> line1.p1.x >> line1.p1.y;
} while ((line1.p1.y<0) ||
(line1.p1.y>=NUMBER_ROWS) ||
(line1.p1.x<0) ||
(line1.p1.x >= NUMBER_COLS));
// use another do-while loop for the 2nd point, col2 and row2
} 20
More on Graphing Line
void graph_line(char grid[][NUMBER_COLS], line line1){
int row, col;
double rise, run, slope;
// one point
if((line1.p1.y==line1.p2.y)&&(line1.p1.x==line2.p2.x))
grid[line1.p1.y][line1.p1.x] = '*';
else if(line1.p2.x==line1.p1.x){ // infinite slope
if (line1.p1.y < line1.p2.y){
for(row=line1.p1.y; row <= line1.p2.y; row++)
grid[row][line1.p1.x] = '*';
}
else{
for(row=line1.p1.y; row >= line1.p2.y; row--)
grid[row][line1.p1.x] = '*';
}
}
21
More on Graphing Line
else{
rise=line1.p2.y-line1.p1.y; run=line1.p2.x-line1.p1.x;
slope = (double)rise / run; // run cannot = 0
if (run >0){
for(col = line1.p1.x; col <= line1.p2.x; col++){
// line1.p1.y is offset for starting point
row=(int)(slope*(col–line1.p1.x)+line1.p1.y);
grid[row][col] = '*';
}
}
else{
for(col=line1.p1.x; col >= line1.p2.x; col--){
row=(int)(slope*(col–line1.p1.x)+line1.p1.y);
grid[row][col] = '*';
}
}
}
}
22
23
Arrays of structures
• An ordinary array: One type of data

0 1 2 … 98 99

• An array of structs: Multiple types of data in


each array element.

0 1 2 … 98 99
24
Arrays of structures
• We often use arrays of structures.
• Example:
StudentRecord Class[100];
strcpy(Class[98].Name, "Chan Tai Man");
Class[98].Id = 12345;
strcpy(Class[98].Dept, "COMP");
Class[98].gender = 'M';
Class[0] = Class[98]; Chan Tai Man

12345 M

COMP

...

0 1 2 … 98 99 25
Arrays inside structures
• We can use arrays inside structures.
• Example: (4, 3) (10, 3)
struct square{
point vertex[4];
};
(4, 1) (10, 1)
square Sq;

• Assign values to Sq using the given square


x y x y x y x y

26
Pointers
A pointer is a reference to another variable (memory
location) in a program
– Used to change variables inside a function (reference
parameters)
– Used to remember a particular member of a group (such
as an array)
– Used in dynamic (on-the-fly) memory allocation
(especially of arrays)
– Used in building complex data structures (linked lists,
stacks, queues, trees, etc.)
Outline
Pointers
Basics
Variable declaration, initialization, NULL pointer
& (address) operator, * (indirection) operator
Pointer parameters, return values
Casting points, void *
Arrays and pointers
1D array and simple pointer
Passing as parameter
Dynamic memory allocation
calloc, free, malloc, realloc
Dynamic 2D array allocation (and non-square arrays)
Pointer Basics
Variables are allocated at addresses in computer memory
(address depends on computer/operating system)
Name of the variable is a reference to that memory address
A pointer variable contains a representation of an address of
another variable (P is a pointer variable in the following):
Name V P
Address v (some value) p (some value)
int V = 101;
Abstract
101
Representation
int *P = &V;
Concrete 4 bytes for 4 bytes for
Representation int value 101 mem address v
Pointer Variable Definition
Basic syntax: Type *Name
Examples:
int *P; /* P is var that can point to an int var */
float *Q; /* Q is a float pointer */
char *R; /* R is a char pointer */
Complex example:
int *AP[5]; /* AP is an array of 5 pointers to ints */
– more on how to read complex declarations later
Address (&) Operator
The address (&) operator can be used in front of any
variable object in C -- the result of the operation is
the location in memory of the variable
Syntax: &VariableReference
Examples:
int V;
int *P;
int A[5];
&V - memory location of integer variable V
&(A[2]) - memory location of array element 2 in array A
&P - memory location of pointer variable P
Pointer Variable Initialization/Assignment
NULL - pointer lit constant to non-existent address
– used to indicate pointer points to nothing
Can initialize/assign pointer vars to NULL or use the
address (&) op to get address of a variable
– variable in the address operator must be of the right
type for the pointer (an integer pointer points only at
integer variables)
Examples:
int V;
int *P = &V;
int A[5];
P = &(A[2]);
Indirection (*) Operator
A pointer variable contains a memory address
To refer to the contents of the variable that the
pointer points to, we use indirection operator
Syntax: *PointerVariable
Example:
int V = 101;
int *P = &V;
/* Then *P would refer to the contents of the variable V
(in this case, the integer 101) */
printf(“%d”,*P); /* Prints 101 */
Pointer Sample
int A = 3; Q = &B;
int B; if (P == Q)
int *P = &A; printf(“1\n”);
int *Q = P; if (Q == R)
int *R = &B; printf(“2\n”);
if (*P == *Q)
printf(“Enter value:“); printf(“3\n”);
scanf(“%d”,R); if (*Q == *R)
printf(“%d %d\n”,A,B); printf(“4\n”);
printf(“%d %d %d\n”, if (*P == *R)
*P,*Q,*R); printf(“5\n”);
Reference Parameters
To make changes to a variable that exist after a
function ends, we pass the address of (a pointer to)
the variable to the function (a reference parameter)
Then we use indirection operator inside the function
to change the value the parameter points to:
void changeVar(float *cvar) {
*cvar = *cvar + 10.0;
}
float X = 5.0;
changeVar(&X);
printf(“%.1f\n”,X);
Pointer Return Values
A function can also return a pointer value:
float *findMax(float A[], int N) {
int I;
float *theMax = &(A[0]);
for (I = 1; I < N; I++)
if (A[I] > *theMax) theMax = &(A[I]);
return theMax;
}
void main() {
float A[5] = {0.0, 3.0, 1.5, 2.0, 4.1};
float *maxA;
maxA = findMax(A,5);
*maxA = *maxA + 1.0;
printf("%.1f %.1f\n",*maxA,A[4]);
}
Pointers to Pointers
A pointer can also be made to point to a pointer
variable (but the pointer must be of a type that
allows it to point to a pointer)
Example:
int V = 101;
int *P = &V; /* P points to int V */
int **Q = &P; /* Q points to int pointer P */

printf(“%d %d %d\n”,V,*P,**Q); /* prints 101 3 times */


Pointer Types
Pointers are generally of the same size (enough bytes
to represent all possible memory addresses), but it
is inappropriate to assign an address of one type of
variable to a different type of pointer
Example:
int V = 101;
float *P = &V; /* Generally results in a Warning */
Warning rather than error because C will allow you
to do this (it is appropriate in certain situations)
Casting Pointers
When assigning a memory address of a variable of
one type to a pointer that points to another type it
is best to use the cast operator to indicate the cast
is intentional (this will remove the warning)
Example:
int V = 101;
float *P = (float *) &V; /* Casts int address to float * */
Removes warning, but is still a somewhat unsafe
thing to do
The General (void) Pointer
A void * is considered to be a general pointer
No cast is needed to assign an address to a void * or
from a void * to another pointer type
Example:
int V = 101;
void *G = &V; /* No warning */
float *P = G; /* No warning, still not safe */
Certain library functions return void * results (more
later)
1D Arrays and Pointers
int A[5] - A is the address where the array starts
(first element), it is equivalent to &(A[0])
A is in some sense a pointer to an integer variable
To determine the address of A[x] use formula:
(address of A + x * bytes to represent int)
(address of array + element num * bytes for element size)
The + operator when applied to a pointer value uses
the formula above:
A + x is equivalent to &(A[x])
*(A + x) is equivalent to A[x]
1D Array and Pointers Example
float A[6] = {1.0,2.0,1.0,0.5,3.0,2.0};
float *theMin = &(A[0]);
float *walker = &(A[1]);
while (walker < &(A[6])) {
if (*walker < *theMin)
theMin = walker;
walker = walker + 1;
}
printf("%.1f\n",*theMin);
1D Array as Parameter
When passing whole array as parameter use syntax
ParamName[], but can also use *ParamName
Still treat the parameter as representing array:
int totalArray(int *A, int N) {
int total = 0;
for (I = 0; I < N; I++)
total += A[I];
return total;
}
For multi-dimensional arrays we still have to use the
ArrayName[][Dim2][Dim3]etc. form
Understanding Complex Declarations
Right-left rule: when examining a declaration, start
at the identifier, then read the first object to right,
first to left, second to right, second to left, etc.
objects:
Type
* - pointer to
[Dim] - 1D array of size Dim
[Dim1][Dim2] - 2D of size Dim1,Dim2
( Params ) - function
Can use parentheses to halt reading in one direction
Declarations Examples
int A A is a int
float B [5] B is a 1D array of size 5 of floats
int * C C is a pointer to an int
char D [6][3] D is a 2D array of size 6,3 of chars
int * E [5] E is a 1D array of size 5 of
pointers to ints
int (* F) [5] F is a pointer to a
1D array of size 5 of ints
int G (…) G is a function returning an int
char * H (…) H is a function returning
a pointer to a char
Program Parts
Machine
Code
Space for program code includes space for
machine language code and data Global
Variables,
Data broken into: Constants
space for global variables and constants
data stack - expands/shrinks while program runs Data
Stack
data heap - expands/shrinks while program runs
Local variables in functions allocated when
Free
function starts: Space
space put aside on the data stack
when function ends, space is freed up
Data
must know size of data item (int, array, etc.) when Heap
allocated (static allocation)
Limits of Static Allocation
What if we don’t know how much space we will
need ahead of time?
Example:
ask user how many numbers to read in
read set of numbers in to array (of appropriate size)
calculate the average (look at all numbers)
calculate the variance (based on the average)
Problem: how big do we make the array??
using static allocation, have to make the array as big as
the user might specify (might not be big enough)
Dynamic Memory Allocation
Allow the program to allocate some variables
(notably arrays), during the program, based on
variables in program (dynamically)
Previous example: ask the user how many numbers
to read, then allocate array of appropriate size
Idea: user has routines to request some amount of
memory, the user then uses this memory, and
returns it when they are done
memory allocated in the Data Heap
Memory Management Functions
calloc - routine used to allocate arrays of memory
malloc - routine used to allocate a single block of
memory
realloc - routine used to extend the amount of space
allocated previously
free - routine used to tell program a piece of memory
no longer needed
note: memory allocated dynamically does not go away at
the end of functions, you MUST explicitly free it up
Array Allocation with calloc
prototype: void * calloc(size_t num, size_t esize)
size_t is a special type used to indicate sizes, generally an
unsigned int
num is the number of elements to be allocated in the array
esize is the size of the elements to be allocated
generally use sizeof and type to get correct value
an amount of memory of size num*esize allocated on heap
calloc returns the address of the first byte of this memory
generally we cast the result to the appropriate type
if not enough memory is available, calloc returns NULL
calloc Example
float *nums;
int N;
int I;

printf(“Read how many numbers:”);


scanf(“%d”,&N);
nums = (float *) calloc(N, sizeof(float));
/* nums is now an array of floats of size N */
for (I = 0; I < N; I++) {
printf(“Please enter number %d: “,I+1);
scanf(“%f”,&(nums[I]));
}
/* Calculate average, etc. */
Releasing Memory (free)
prototype: void free(void *ptr)
memory at location pointed to by ptr is released (so we
could use it again in the future)
program keeps track of each piece of memory allocated by
where that memory starts
if we free a piece of memory allocated with calloc, the entire
array is freed (released)
results are problematic if we pass as address to free an
address of something that was not allocated dynamically
(or has already been freed)
free Example
float *nums;
int N;

printf(“Read how many numbers:”);


scanf(“%d”,&N);
nums = (float *) calloc(N, sizeof(float));

/* use array nums */

/* when done with nums: */

free(nums);

/* would be an error to say it again - free(nums) */


The Importance of free
void problem() {
float *nums;
int N = 5;
nums = (float *) calloc(N, sizeof(float));
/* But no call to free with nums */
} /* problem ends */

When function problem called, space for array of size N allocated,


when function ends, variable nums goes away, but the space
nums points at (the array of size N) does not (allocated on the
heap) - furthermore, we have no way to figure out where it is)
Problem called memory leakage
Array Allocation with malloc
prototype: void * malloc(size_t esize)
similar to calloc, except we use it to allocate a single block
of the given size esize
as with calloc, memory is allocated from heap
NULL returned if not enough memory available
memory must be released using free once the user is done
can perform the same function as calloc if we simply
multiply the two arguments of calloc together
malloc(N * sizeof(float)) is equivalent to
calloc(N,sizeof(float))
Increasing Memory Size with realloc
prototype: void * realloc(void * ptr, size_t esize)
ptr is a pointer to a piece of memory previously dynamically
allocated
esize is new size to allocate (no effect if esize is smaller than
the size of the memory block ptr points to already)
program allocates memory of size esize,
then it copies the contents of the memory at ptr to the first
part of the new piece of memory,
finally, the old piece of memory is freed up
realloc Example
float *nums;
int I;

nums = (float *) calloc(5, sizeof(float));


/* nums is an array of 5 floating point values */

for (I = 0; I < 5; I++)


nums[I] = 2.0 * I;
/* nums[0]=0.0, nums[1]=2.0, nums[2]=4.0, etc. */

nums = (float *) realloc(nums,10 * sizeof(float));


/* An array of 10 floating point values is allocated,
the first 5 floats from the old nums are copied as
the first 5 floats of the new nums, then the old
nums is released */
Dynamically Allocating 2D Arrays
Can not simply dynamically
allocate 2D (or higher) 0 1 2 3
array
Idea - allocate an array of 0
pointers (first dimension), 1
make each pointer point to A 2
a 1D array of the 3
appropriate size 4
Can treat result as 2D array
Dynamically Allocating 2D Array
float **A; /* A is an array (pointer) of float
pointers */
int I;

A = (float **) calloc(5,sizeof(float *));


/* A is a 1D array (size 5) of float pointers */

for (I = 0; I < 5; I++)


A[I] = (float *) calloc(4,sizeof(float));
/* Each element of array points to an array of 4
float variables */

/* A[I][J] is the Jth entry in the array that the


Ith member of A points to */
Non-Square 2D Arrays
No need to allocate square 2D
arrays:
float **A; 0 1 2 3 4
int I;

A = (float **) calloc(5, 0


sizeof(float *)); 1
A 2
for (I = 0; I < 5; I++)
3
A[I] = (float **)
4
calloc(I+1,
sizeof(float));
File Management in C
Console oriented Input/Output

• Console oriented – use terminal (keyboard/screen)

• scanf(“%d”,&i) – read data from keyboard

• printf(“%d”,i) – print data to monitor

• Suitable for small volumes of data

• Data lost when program terminated


Real-life applications

• Large data volumes

• E.g. physical experiments (CERN collider), human genome,


population records etc.

• Need for flexible approach to store/retrieve data

• Concept of files
Files

• File – place on disc where group of related data is stored


– E.g. your C programs, executables

• High-level programming languages support file operations


– Naming
– Opening
– Reading
– Writing
– Closing
Defining and opening file

• To store data file in secondary memory (disc) must specify to


OS

– Filename (e.g. sort.c, input.data)

– Data structure (e.g. FILE)

– Purpose (e.g. reading, writing, appending)


Filename

• String of characters that make up a valid filename for OS

• May contain two parts


– Primary
– Optional period with extension

• Examples: a.out, prog.c, temp, text.out


General format for opening file

FILE *fp; /*variable fp is pointer to type FILE*/

fp = fopen(“filename”, “mode”);
/*opens file with name filename , assigns identifier to fp */

• fp
– contains all information about file
– Communication link between system and program
• Mode can be
– r open file for reading only
– w open file for writing only
– a open file for appending (adding) data
Different modes

• Writing mode
– if file already exists then contents are deleted,
– else new file with specified name created
• Appending mode
– if file already exists then file opened with contents safe
– else new file created
• Reading mode
– if file already exists then opened with contents safe
– else error occurs.

FILE *p1, *p2;


p1 = fopen(“data”,”r”);
p2= fopen(“results”, w”);
Additional modes

• r+ open to beginning for both reading/writing

• w+ same as w except both for reading and writing

• a+ same as ‘a’ except both for reading and writing


Closing a file
• File must be closed as soon as all operations on it completed

• Ensures
– All outstanding information associated with file flushed out from
buffers
– All links to file broken
– Accidental misuse of file prevented

• If want to change mode of file, then first close and open again
Closing a file
Syntax: fclose(file_pointer);

Example:

FILE *p1, *p2;


p1 = fopen(“INPUT.txt”, “r”);
p2 =fopen(“OUTPUT.txt”, “w”);
……..
……..
fclose(p1);
fclose(p2);

• pointer can be reused after closing


Input/Output operations on files

• C provides several different functions for reading/writing

• getc() – read a character


• putc() – write a character
• fprintf() – write set of data values
• fscanf() – read set of data values
• getw() – read integer
• putw() – write integer
getc() and putc()

• handle one character at a time like getchar() and putchar()


• syntax: putc(c,fp1);
– c : a character variable
– fp1 : pointer to file opened with mode w
• syntax: c = getc(fp2);
– c : a character variable
– fp2 : pointer to file opened with mode r
• file pointer moves by one character position after every getc()
and putc()
• getc() returns end-of-file marker EOF when file end reached
Program to read/write using getc/putc
#include <stdio.h>
main()
{ FILE *fp1;
char c;
f1= fopen(“INPUT”, “w”); /* open file for writing */

while((c=getchar()) != EOF) /*get char from keyboard until CTL-Z*/


putc(c,f1); /*write a character to INPUT */

fclose(f1); /* close INPUT */


f1=fopen(“INPUT”, “r”); /* reopen file */

while((c=getc(f1))!=EOF) /*read character from file INPUT*/


printf(“%c”, c); /* print character to screen */

fclose(f1);
} /*end main */
fscanf() and fprintf()
• similar to scanf() and printf()
• in addition provide file-pointer
• given the following
– file-pointer f1 (points to file opened in write mode)
– file-pointer f2 (points to file opened in read mode)
– integer variable i
– float variable f
• Example:
fprintf(f1, “%d %f\n”, i, f);
fprintf(stdout, “%f \n”, f); /*note: stdout refers to screen */
fscanf(f2, “%d %f”, &i, &f);
• fscanf returns EOF when end-of-file reached
getw() and putw()

• handle one integer at a time


• syntax: putw(i,fp1);
– i : an integer variable
– fp1 : pointer to file ipened with mode w
• syntax: i = getw(fp2);
– i : an integer variable
– fp2 : pointer to file opened with mode r
• file pointer moves by one integer position, data stored in
binary format native to local system
• getw() returns end-of-file marker EOF when file end reached
C program using getw, putw,fscanf, fprintf
#include <stdio.h> #include <stdio.h>
main() main()
{ int i,sum1=0; { int i, sum2=0;
FILE *f1; FILE *f2;
/* open files */ /* open files */
f1 = fopen("int_data.bin","w"); f2 = fopen("int_data.txt","w");
/* write integers to files in binary /* write integers to files in binary and
and text format*/ text format*/
for(i=10;i<15;i++) putw(i,f1); for(i=10;i<15;i++) printf(f2,"%d\n",i);
fclose(f1); fclose(f2);
f1 = fopen("int_data.bin","r"); f2 = fopen("int_data.txt","r");
while((i=getw(f1))!=EOF) while(fscanf(f2,"%d",&i)!=EOF)
{ sum1+=i; { sum2+=i; printf("text file:
printf("binary file: i=%d\n",i); i=%d\n",i);
} /* end while getw */ } /*end while fscanf*/
printf("binary sum=%d,sum1); printf("text sum=%d\n",sum2);
fclose(f1); fclose(f2);
} }
On execution of previous Programs
$ ./a.out $ ./a.out
binary file: i=10 text file: i=10
binary file: i=11 text file: i=11
binary file: i=12 text file: i=12
text file: i=13
binary file: i=13
text file: i=14
binary file: i=14 text sum=60
binary sum=60, $ more int_data.bin
$ cat int_data.txt ^@^@^@^K^@^@^@^L^@^@^@^
M^@^@^@^N^@^@^@
10
$
11
12
13
14
Errors that occur during I/O

• Typical errors that occur

– trying to read beyond end-of-file

– trying to use a file that has not been opened

– perform operation on file not permitted by ‘fopen’ mode

– open file with invalid filename

– write to write-protected file


Error handling
• given file-pointer, check if EOF reached, errors while handling
file, problems opening file etc.
• check if EOF reached: feof()
• feof() takes file-pointer as input, returns nonzero if all data
read and zero otherwise
if(feof(fp))
printf(“End of data\n”);

• ferror() takes file-pointer as input, returns nonzero integer if


error detected else returns zero
if(ferror(fp) !=0)
printf(“An error has occurred\n”);
Error while opening file

• if file cannot be opened then fopen returns a NULL pointer

• Good practice to check if pointer is NULL before proceeding

fp = fopen(“input.dat”, “r”);

if (fp == NULL)
printf(“File could not be opened \n ”);
Random access to files

• how to jump to a given position (byte number) in a file


without reading all the previous data?
• fseek (file-pointer, offset, position);
• position: 0 (beginning), 1 (current), 2 (end)
• offset: number of locations to move from position
Example: fseek(fp,-m, 1); /* move back by m bytes from current
position */
fseek(fp,m,0); /* move to (m+1)th byte in file */
fseek(fp, -10, 2); /* what is this? */

• ftell(fp) returns current byte position in file


• rewind(fp) resets position to start of file
Command line arguments

• can give input to C program from command line


E.g. > prog.c 10 name1 name2 ….
• how to use these arguments?
main ( int argc, char *argv[] )
• argc – gives a count of number of arguments (including
program name)
• char *argv[] defines an array of pointers to character (or array
of strings)
• argv[0] – program name
• argv[1] to argv[argc -1] give the other arguments as strings
Example args.c
#include <stdio.h>

main(int argc,char *argv[])


{
while(argc>0) /* print out all arguments in reverse order*/
{
printf("%s\n",argv[argc-1]);
argc--;
}
}

$ cc args.c -o args.out
$ ./args.out 2 join leave 6
6
leave
join
2
./args.out
$

You might also like