topic 6a – the char data type. cisc 105 – topic final review section 2 characters are numbers...
Post on 20-Dec-2015
217 Views
Preview:
TRANSCRIPT
Topic 6A – The char Data Type
CISC 105 – Topic Final
Review Section 2
Characters are Numbers The char data type is really just a
small (8 bit) number. As such, each symbol (character)
is represented by a number. Typically, this representation is
defined by a standard known as ASCII.
CISC 105 – Topic Final
Review Section 2
Letters The upper-case letters go from ‘A’
which has ASCII value 65 through ‘Z’ which has value 90. Thus: ‘A’ < ‘B’ < ‘C’ < … < ‘X’ < ‘Y’ < ‘Z’
The lower-case letters go from ‘a’ which has ASCII value 97 though ‘z’ which has value 122. Thus: ‘a’ < ‘b’ < ‘c’ < … < ‘x’ < ‘y’ < ‘z’
CISC 105 – Topic Final
Review Section 2
Letters Notice that the lower-case letters
have larger ASCII values than upper-case letters. Thus: ‘A’ < ‘B’ < … < ‘Y’ < ‘Z’ < … < ‘a’ < ‘b’
< … < ‘x’ < ‘y’ < ‘z’ A program can compare chars using
less-than, greater-than, etc… operators using the above relationships.
CISC 105 – Topic Final
Review Section 2
Digits The digits go from ‘0’ which has
ASCII value 48 through ‘9’ which has ASCII value 57. Thus: ‘0’ < ‘1’ < ‘2’ < … < ‘7’ < ‘8’ < ‘9’
Notice that each digit does NOT equal its ASCII value. Therefore 3 and ‘3’ are NOT the same.
CISC 105 – Topic Final
Review Section 2
Other Characters All of the other characters (such
as !,@,#,$,%,^,&,*,(,),-,+,=,_) all have ASCII values as well.
They can also be compared in the same manner as the letters and digits.
However, as these characters do not relate as easily as the letters do to each other, this is more difficult.
CISC 105 – Topic Final
Review Section 2
Arithmetic Operations The char data type can also be
subjected to arithmetic operations. Thus,
‘A’ + 3 = 68 = ‘D’‘h’ - 4 = 101 = ‘e’‘3’ * 1 = 51 = ‘3’
Topic 8 – Introduction to Pointers and Function Output Parameters
CISC 105 – Topic Final
Review Section 2
Variables and Memory When a variable is declared, the
operating system will find a location in memory in which to store that variable.
Each variable exists at a specific memory location and each memory location has a unique address.
Therefore, each variable exists at a unique memory location and a unique address identifies that location.
CISC 105 – Topic Final
Review Section 2
The & Operator As seen previously in the scanf
function, the & operator means “the address of.”
Thus,
evaluates to address of the variable big_var1.
&big_var1
CISC 105 – Topic Final
Review Section 2
Pointers There is another set of data types,
that are capable of holding addresses of variables. They are called pointers.
This is indicated by prefacing the name of the variable with a “*”. Examples include:char *p_letterGrade;
int *p_num1;double *p_num2;
CISC 105 – Topic Final
Review Section 2
Pointers
This says that p_letterGrade holds the address of a character.
Similarly, p_num1 holds the address of a integer.
Finally, p_num2 holds the address of a double-precision floating point number.
char *p_letterGrade;int *p_num1;double *p_num2;
CISC 105 – Topic Final
Review Section 2
Pointers The new data types that we are
identifying are known as pointers. As each one will contain the address of
a variable, we can think of them as pointing to that variable.
Note that each name starts with a “p_” indicating that they are pointers. Picking some naming convention so that pointers can be easily identified is a very good programming practice.
CISC 105 – Topic Final
Review Section 2
Pointers
p_letterGrade is a pointer to a character, or a character pointer.
p_num1 is a pointer to a integer, or an integer pointer.
p_num2 is a pointer to a double, or a double-precision floating point number pointer.
char *p_letterGrade;int *p_num1;double *p_num2;
CISC 105 – Topic Final
Review Section 2
Pointers:A Definition
A pointer is simply a memory address. It can be used to access whatever
exists at that memory address.
CISC 105 – Topic Final
Review Section 2
A Simple Pointer Example Therefore, suppose we wish to
create two integer variables, and also have pointers to those two variables.
int num1, num2;int *p_num1, *p_num2;
p_num1 = &num1;p_num2 = &num2;
CISC 105 – Topic Final
Review Section 2
A Simple Pointer Example Therefore, suppose we wish to
create two integer variables, and also have pointers to those two variables.
int num1, num2;int *p_num1, *p_num2;
p_num1 = &num1;p_num2 = &num2;
First, we declare the variables.They are placed somewhere
in memory.
CISC 105 – Topic Final
Review Section 2
A Simple Pointer Example Therefore, suppose we wish to
create two integer variables, and also have pointers to those two variables.
int num1, num2;int *p_num1, *p_num2;
p_num1 = &num1;p_num2 = &num2;
Next, we declare two variablesthat are pointers to integers.
CISC 105 – Topic Final
Review Section 2
A Simple Pointer Example Therefore, suppose we wish to
create two integer variables, and also have pointers to those two variables.
int num1, num2;int *p_num1, *p_num2;
p_num1 = &num1;p_num2 = &num2;
This statement findsthe address of num1
and stores it inp_num1.
CISC 105 – Topic Final
Review Section 2
A Simple Pointer Example Therefore, suppose we wish to
create two integer variables, and also have pointers to those two variables.
int num1, num2;int *p_num1, *p_num2;
p_num1 = &num1;p_num2 = &num2;
This statement findsthe address of num2
and stores it inp_num2.
CISC 105 – Topic Final
Review Section 2
A Simple Pointer Example
int num1, num2;int *p_num1,
*p_num2;
p_num1 = &num1;p_num2 = &num2;
1004
1006
1008
1010
1012
1014
1016
1018
(num2)
(num1)
(p_num1)
(p_num2)
1014
1008
CISC 105 – Topic Final
Review Section 2
So…how is a Pointer used? A pointer can be used via the indirection
operator (or dereferencing operator), “*”. The * operator simply means “follow the
pointer.” When a pointer is “followed”, this is known as dereferencing the pointer.
A *(pointer) expression is equal to the value of the variable that the pointer points to.
CISC 105 – Topic Final
Review Section 2
The * Operator:A Simple Example In the previous example (slightly
modified):
int num1 = 9, num2 = 21, answer;
int *p_num1, *p_num2;
p_num1 = &num1;p_num2 = &num2;
answer = num1 +*p_num2;
num1 = num2 =*p_num1 = *p_num2 =answer =
92192130
CISC 105 – Topic Final
Review Section 2
Types of References
Here, in the final statement, using num1 is called a direct reference, as we simply go the location the num1 is stored at.
The use of p_num2 is a indirect reference, as we first go to the location the pointer p_num2 is stored at to get the address of the data, and then we go there.
int num1 = 9, num2 = 21, answer;int *p_num1, *p_num2;
p_num1 = &num1;p_num2 = &num2;
answer = num1 + *p_num2;
CISC 105 – Topic Final
Review Section 2
Call-By-Value Thus far, we have seen one type of
function parameter, known as call-by-value.
This type of function calling initializes the input parameters to the values passed into the function.
The value passed into the function is copied and the copy is stored in the function parameter (named in the function definition header).
CISC 105 – Topic Final
Review Section 2
Call-By-Value Example
int x = 27;fun_y(x);
…
void fun_y(int z){ printf(“z=%d”,z); return;}
1004
1006
1008
1010
1012
1014
1016
1018
(x) 27
(z) 27
CISC 105 – Topic Final
Review Section 2
Call-By-Value Example
int x = 27;fun_y(x);
…
void fun_y(int z){ printf(“z=%d”,z); return;}
1004
1006
1008
1010
1012
1014
1016
1018
(x) 27
(z) 27
Notice that there are two variable references.First, we make a direct reference to x when we call fun_y().Next, we make a direct reference to z when we call printf().
CISC 105 – Topic Final
Review Section 2
Call-By-Reference We can also call a function using
what is known as call-by-reference. Instead of copying the value
passed into a function into the function parameter, we pass a pointer to the value into the function.
CISC 105 – Topic Final
Review Section 2
Call-By-Reference Example
int x = 27;fun_y(&x);
…
void fun_y(int *p_x){ printf(“x=%d”,*p_x); return;}
1004
1006
1008
1010
1012
1014
1016
1018
(x) 27
(p_x) 1014
CISC 105 – Topic Final
Review Section 2
Call-By-Reference Example
int x = 27;fun_y(&x);
…
void fun_y(int *p_x){ printf(“x=%d”,*p_x); return;}
1004
1006
1008
1010
1012
1014
1016
1018
(x) 27
(p_x) 1014
First, we use the & operator on x to get its memory address.Then that address is passed into fun_y() and stored in p_x.
Next, we make an indirect reference to x when we call printf().When this happens, we first look at p_x to get the memory
address of x. Then, we go to that location (1014) and get the value of x.
CISC 105 – Topic Final
Review Section 2
Comparison There are obvious differences in these
calling methods. First and foremost, in the call-by-value
method, the value stored in the variable in the calling function cannot be changed by the called function, as that value is copied into the new variable that is declared in the function parameters of the called function.
This copy is the one the called function uses.
CISC 105 – Topic Final
Review Section 2
Call-By-Value Example II
int x = 27;fun_y(x);
…
void fun_y(int z){ z = z + 1; printf(“z=%d”,z); return;}
1004
1006
1008
1010
1012
1014
1016
1018
(x) 27
(z) 2728
CISC 105 – Topic Final
Review Section 2
Here, the function fun_y() knows nothing about the variable x.
Thus, any statement inside fun_y() cannot use x, they must use z.
So, when fun_y() modifies z, the value stored in x is not modified.
Call-By-Value Example II
int x = 27;fun_y(x);
…
void fun_y(int z){ z = z + 1; printf(“z=%d”,z); return;}
CISC 105 – Topic Final
Review Section 2
Comparison In the call-by-reference method, the
value stored in the variable stored in the variable in the calling function CAN be changed by the called function, as a pointer to that value is passed into the called function.
Thus, both functions use the same value, one directly (the calling function) and one indirectly (the called function).
CISC 105 – Topic Final
Review Section 2
Call-By-Reference Example II
int x = 27;fun_y(&x);
…
void fun_y(int *p_x){ *p_x = *p_x + 1; printf(“z=%d”, *p_x); return;}
1004
1006
1008
1010
1012
1014
1016
1018
(x) 27
(p_x) 1014
28
CISC 105 – Topic Final
Review Section 2
Here, the function fun_y() has a pointer to the memory location of x.
Thus, any statement inside fun_y() CAN use x.
So, when fun_y() modifies x, the value stored in x IS modified.
Call-By-Reference Example II
int x = 27;fun_y(&x);
…
void fun_y(int *p_x){ *p_x = *p_x + 1; printf(“z=%d”, *p_x); return;}
CISC 105 – Topic Final
Review Section 2
Function Output Parameters Notice that the variable x is both an input
parameter and output parameter to the function fun_y().
It is initialized to a value and the function uses that value (input parameter).
It is also updated by the function; the function stores a value there (output parameter).
Notice that if x were to be used again in the calling function, after the call to fun_y(), the new value, in this case 28, would be seen.
CISC 105 – Topic Final
Review Section 2
Function Output Parameters This approach also allows us to return more
than one piece of data from a function. This can be accomplished by passing pointers
to variables of the type we wish to return. For example, if we wish to return 3 double
types, we create three double variables in the calling function and pass 3 pointers to those variables into the called function.
Then, the called function stores the output in those variables, using an indirect reference.
CISC 105 – Topic Final
Review Section 2
Function Output Parameters (A Simple Example) – Rev. I
double x,y,z;double *p_x, *p_y, *p_z;
p_x = &x; p_y = &y; p_z = &z;get_doubles(p_x,p_y,p_z);printf(“x=%f, y=%f, z=%f”,x,y,z);
…
void get_doubles(double *p2_x, double *p2_y, double *p2_z){ double in1, in2, in3; printf(“Enter three doubles>”); scanf(“%lf %lf %lf”,&in1, &in2, &in3); *p2_x = in1; *p2_y = in2; *p2_z = in3;}
CISC 105 – Topic Final
Review Section 2
Function Output Parameters (A Simple Example) – Rev. II
double x,y,z;
get_doubles(&x, &y, &z);printf(“x=%f, y=%f, z=%f”,x,y,z);
…
void get_doubles(double *p2_x, double *p2_y, double *p2_z){ double in1, in2, in3; printf(“Enter three doubles>”); scanf(“%lf %lf %lf”,&in1, &in2, &in3); *p2_x = in1; *p2_y = in2; *p2_z = in3;}
CISC 105 – Topic Final
Review Section 2
Function Output Parameters (A Simple Example) – Rev. III
double x,y,z;
get_doubles(&x, &y, &z);printf(“x=%f, y=%f, z=%f”,x,y,z);
…
void get_doubles(double *p2_x, double *p2_y, double *p2_z){ printf(“Enter three doubles>”); scanf(“%lf %lf %lf”, p2_x, p2_y, p2_z);}
CISC 105 – Topic Final
Review Section 2
Common Errors with Pointers Never, EVER, attempt to dereference a pointer
before it has been assigned to something (set equal to the address of something).
As a variable is in an unknown state (garbage) before it is initialized, this would cause a program to attempt to access some random location in memory, which is not allowed.
This often results in the common program run-time error message, “Segmentation Fault.”
CISC 105 – Topic Final
Review Section 2
Common Errors with Pointers Note that this is a run-time error. It will not
cause a compiler error. Therefore, make sure you set a pointer
equal to the address of some variable (of the correct type!) before you attempt to use it.
For example:
double x = 10.0, y = 20.0, *p_x, *p_y;p_x = &x;
printf(“x = %f and y = %f\n”, *p_x, *p_y);
CISC 105 – Topic Final
Review Section 2
Common Errors with Pointers Note that this is a run-time error. It will not
cause a compiler error. Therefore, make sure you set a pointer
equal to the address of some variable (of the correct type!) before you attempt to use it.
For example:
double x = 10.0, y = 20.0, *p_x, *p_y;p_x = &x;
printf(“x = %f and y = %f\n”, *p_x, *p_y);
ERROR!This will cause the program
to crash as p_y has not been initialized.
CISC 105 – Topic Final
Review Section 2
Common Errors with Pointers Also, a pointer can only point to the
“correct” data type. For example, an integer pointer CANNOT point to a float data type.
This is a compile-time error. It will generate a compiler error.
For example:double x = 10.0, *p_x, *p_y;int y = 20;
p_x = &x; p_y = &y
printf(“x = %f and y = %f\n”, *p_x, *p_y);
CISC 105 – Topic Final
Review Section 2
Common Errors with Pointers Also, a pointer can only point to the
“correct” data type. For example, an integer pointer CANNOT point to a float data type.
This is a compile-time error. It will generate a compiler error.
For example:double x = 10.0, *p_x, *p_y;int y = 20;
p_x = &x; p_y = &y
printf(“x = %f and y = %f\n”, *p_x, *p_y);
ERROR!This is not allowed as y is
an int and p_y is a pointerto a double.
Topic 9 – Introduction To Arrays
CISC 105 – Topic Final
Review Section 2
Introduction to Data Structures Thus far, we have seen “simple” data
types. These refer to a single memory cell which holds one variable in memory.
In order to solve some programming problems, it is often useful to store a set of data (more than one variable) in a specific form, or structure, in memory.
CISC 105 – Topic Final
Review Section 2
The Array The simplest data structure is that
of an array. An array refers to a collection of
two or more contiguous (adjacent) memory cells that hold variables of the same data type.
Each variable in the array is referred to as an array element.
CISC 105 – Topic Final
Review Section 2
Array Structure Each element in the array is referenced
using two components, the array name and an index.
The first is simply the name of the array. The second is the array index. This is simply
an integer that indicates which element you are referencing. For example, the first element has index 0, the second has index 1, the third has index 2, and so forth.
Notice that the array elements are numbered starting with zero (0) and not one (1).
CISC 105 – Topic Final
Review Section 2
Array Structure in Memory When an array is declared, the operating
system finds some location in memory to store it.
Here, the operating system does not simply need to find one memory cell, but one memory cell for each element in the array.
Therefore, if an array of 40 doubles were to be declared, the OS would allocate a section of memory that is big enough to store 40 double variables, one after the other.
CISC 105 – Topic Final
Review Section 2
Array Structure in Memory For example, if x was
declared to be an array of four integers, a section of memory consisting of four memory cells, one to hold each of the array elements, is allocated.
Note that the starting memory address is determined by the operating system (just like each simple variable).
1004
1006
1008
1010
1012
1014
1016
1018
(x[0])
(x[1])
(x[2])
(x[3])
CISC 105 – Topic Final
Review Section 2
Declaring Arrays An array is declared much like a
simple variable. After the array name, a bracket “[” is found, then the size of the array (an integer value) and then a closing bracket “]”.
Thus, an array of four integers, named x, would be declared as:
int x[4];
CISC 105 – Topic Final
Review Section 2
Declaring Arrays An array can be made of any simple
data type. An array of six doubles, named y:
An array of twelve characters, named p:
An array of nine floats, named floaters:
double y[6];
char p[12];
float floaters[9];
CISC 105 – Topic Final
Review Section 2
Referencing Array Elements Once an array has been declared, there
must be a method of accessing each element in the array.
This is done by using the array name, the bracket “[”, the index of the element being referenced, and then a closing bracket “]”.
Thus, in order to access the first element in the array grades:
grades[0]
CISC 105 – Topic Final
Review Section 2
Referencing Array Elements Note that the first element in an
array has index 0. The second element has index 1, the third index has index 2, etc…
Any statement that can be used to manipulate a simple variable can also be used to manipulate an array element, when used in this manner.
CISC 105 – Topic Final
Review Section 2
Manipulating Array Elements These are all valid statements
(assuming x is an array of floats):
printf(“%f”,x[0]); x[3] = 25.0; sum = x[0] + x[1]; sum += x[2]; x[3] += 1.0; x[2] = x[0] + x[1];
CISC 105 – Topic Final
Review Section 2
Initializing Arrays We can initialize arrays when we
declare them:
int array[6] = { 23, 45, 220, -23, 22, 0 };
This sets array[0] to 23, array[1] to 45, array[2] to 220, array[3] to –23, array[4] to 22, and array[5] to 0.
CISC 105 – Topic Final
Review Section 2
Array Indices:A Closer Look As we have seen, array elements are
accessed with two components, the name of the array and the index, which indicates the index of the element of the array we are accessing.
This index can range from zero (0) through the number of elements minus one (1). For example, an array with 16 elements has indices ranging from 0 to 15.
CISC 105 – Topic Final
Review Section 2
Array Index Ranges: Errors The index into an array should not
go above this range. For example, in an array with 16
elements, the reference array[16] is invalid, as this would attempt to reference the 17th element.
CISC 105 – Topic Final
Review Section 2
Array Index Ranges: Errors If this is done, the resulting value
is indeterminate (garbage). This is similar to what happens
when a variable is used before it is initialized (set to something).
It is equal to whatever happens to be in memory at the time, as the program has not yet put anything there.
CISC 105 – Topic Final
Review Section 2
Array Index Ranges: Errors Overstepping the bounds of an array is
actually much worse than using a variable before it is initialized.
When you use a variable before it is initialized, this is like attempting to look into a box (the variable) before you put anything in there (the value). However, the variable has been allocated by the operating system; that memory cell has been reserved by the OS for that variable. No other data will be placed there.
CISC 105 – Topic Final
Review Section 2
Array Index Ranges: Errors When you overstep the bounds of an
array, that memory cell you are referencing has NOT been allocated by the operating system for the array.
It may have been allocated for some other purpose (such as storing another variable). Thus, attempting to read (or change) a value is this manner is VERY dangerous.
CISC 105 – Topic Final
Review Section 2
Array Index Ranges: Errors Thus, it is important to keep in mind that C
will NOT check to see if the index the program is attempting to access is actually a correct index (within the size of the array).
Incorrect array indices will result in unpredictable and potentially hazardous results when the program runs.
So…make sure to check your array indices!
CISC 105 – Topic Final
Review Section 2
Sequential Array Access Very often, a programmer desires to
access each element of an array in sequence.
This is common as arrays typically hold data that is related.
This is commonly accomplished in C using a for loop statement, creating a counting loop which runs from zero to the size of the array minus one. The loop control variable (the counter) is used as the array index inside the loop body.
CISC 105 – Topic Final
Review Section 2
Sequential Array Access For example, suppose the
array x holds four integers and we wish to put the sum of all four elements in the variable sum.
1004
1006
1008
1010
1012
1014
1016
1018
int count=0, sum = 0;int x[4] = { 2, 4, 6, 8 };
for ( count = 0;count <= 3;count++ )
{ sum += x[count]; }
(count) 0
(sum) 0
(x[0])
(x[1])
(x[2])
(x[3]) 8
6
4
2
1
26
2
12
3
20
4
Topic 9A – Arrays as Function Arguments
CISC 105 – Topic Final
Review Section 2
Arrays as Function Arguments There are two ways to use arrays
as function arguments: Use an array element as a function
argument, i.e. passing one integer from an array of integers into a function.
Use a full array as a function argument, i.e. passing an entire array into a function.
CISC 105 – Topic Final
Review Section 2
Array Elements as Function Arguments Individual array elements can be
used as function arguments in the same way their corresponding data type “simple” variables can be.
If a function takes one integer as a parameter, an element of an integer array can be used.
CISC 105 – Topic Final
Review Section 2
Array Elementsas Function Arguments
int x[5] = { 1, 2, 3, 4, 5 };float average;average = avg_of_5(x[0],x[1],x[2],x[3],x[4]);printf(“The total is %f.”,average);...
float avg_of_5(int a, int b, int c, int d, int e){
return (a + b + c + d + e) / 5.0;}
CISC 105 – Topic Final
Review Section 2
Array Elementsas Function Arguments Notice that there is no difference between
passing a “simple” integer into such a function and passing an element of an integer array into such a function.
We can also use array elements as function output parameters. We simply pass in the address of the array element, in the same way as we do with “simple” variables, using the “&” operator.
CISC 105 – Topic Final
Review Section 2
Array Elementsas Function Arguments
int x[6] = { 1, 2, 3, 4, 5, 0};tot_of_5(x[0], x[1], x[2], x[3],
x[4], &x[5]);printf(“The total is %d.”,x[5]);...
void tot_of_5(int a, int b, int c, int d, int e, int *p_f)
{*p_f = a + b + c + d + e;
}
CISC 105 – Topic Final
Review Section 2
Arrays as Function Arguments In addition to using array elements as function
arguments, an entire array can be used as a function argument.
However, this is a somewhat more complicated process.
The first point to realize is that an array name (without an index) evaluates to the memory address of the first element of the array. Thus, if integer_array is an array of integers:
integer_array == &integer_array[0]
CISC 105 – Topic Final
Review Section 2
Arrays as Function Arguments As the array name is equal to the
address of the first element of the array, we can think of this as a pointer to the array.
Now…how do we pass arrays as function arguments?
To pass an array of variables, the parameter name is followed by a “[]”.
Notice that the size of the array is NOT placed inside the brackets.
CISC 105 – Topic Final
Review Section 2
Arrays as Function Arguments Therefore, for a function that takes two
arrays, one of floats and one of integers, as parameters, the prototype would look like:
void function1(float [], int []);
The function definition would look like:void function1(float x[], int y[])
{
}
CISC 105 – Topic Final
Review Section 2
Arrays as Function Arguments Notice that the size
of the array is not passed into the function. So, this information must be passed in some other way.
A program to set all elements of an integer array to some value, could look like:
void fill_array( int array[], int n, int set_value){ int i; for (i = 0; i < n; i++) {array[i] = set_value;}}
CISC 105 – Topic Final
Review Section 2
Arrays as Function Arguments
This function takes an array, the size of the array, and the value to set the array elements to as parameters.
Thus, to set all 10 elements of the array y to 27, we could call the function:
fill_array(y,10,27);
void fill_array( int array[], int n, int set_value){ int i; for (i = 0; i < n; i++) {array[i] = set_value;}}
CISC 105 – Topic Final
Review Section 2
Array Name and Pointer Equivalence Again, the array name is simply
the address of the first element of that array, thus a pointer to the array.
Therefore,void fill_array(int [], int, int); Could rewritten as:void fill_array(int *, int, int);
Topic 9B –Array Sorting and Searching
CISC 105 – Topic Final
Review Section 2
Algorithms An algorithm is a set of steps that can
be followed to solve a problem. Designing and developing an
algorithm is often the most difficult part of the problem-solving process.
For each problem, there can be many different algorithms that correctly solve the problem.
CISC 105 – Topic Final
Review Section 2
Algorithms Some algorithms may operate much
faster than others that do the same thing (algorithms that solve the same problem may vary in efficiency).
Some algorithms may be easier to understand and may “make more sense” than others that do the same thing (algorithms that solve the same problem may vary in complexity).
CISC 105 – Topic Final
Review Section 2
Introduction to Sorting Many of the algorithms that operate on data
contained within an array require the data in that array to be sorted.
This means that the data contained in the array needs to be in order, from lowest-to-highest, or vice versa.
We will examine two simple techniques for putting the array in lowest-to-highest order.
Note that once this problem is solved, the reverse, putting the array in highest-to-lowest order, is trivial.
CISC 105 – Topic Final
Review Section 2
Introduction to Sorting There are many approaches to
sorting. Some sorting algorithms are much
better than others. We will examine a very simple
sorting algorithm, a selection sort. This algorithm is intuitive (easy-to-
understand), although it is not very efficient.
CISC 105 – Topic Final
Review Section 2
Selection Sort:The Basic Idea The basic idea of the selection sort is to
process the array from left-to-right (index 0, index 1, etc…)
At each element, we look to the right and find the lowest value. Once we find the lowest value (to the right of the current element), we swap the two elements.
Then, we move on to the next element and repeat the process.
CISC 105 – Topic Final
Review Section 2
Selection Sort:The Algorithm(1) current_element = 0(2) Find index_of_min, the index of the smallest
element in the subarray, array[current_element] to array[size – 1]
(3) If current_element does not equal index_of_min, swap elements at current_element and index_of_min
NOTE: You have just completed one pass through the selection sort
(4) If current_element = size – 1 , stop. Else current_element++ & goto step (2)
CISC 105 – Topic Final
Review Section 2
Selection Sort : An Example
24 98 4 3 55 62
X[1] X[2] X[3] X[4] X[5]X[0]
3 24 4 9824 98 9855 9862
CISC 105 – Topic Final
Review Section 2
Sorting Algorithms Keep in mind that a selection sort is
simply one method of sorting an array. It is a very simple-to-understand
approach. It is also not very efficient. Other sorting algorithms that are much
more efficient, although much harder-to-understand, include the bubble sort and the quicksort. Here is an example of the bubble sort.
CISC 105 – Topic Final
Review Section 2
Bubble Sort:The Basic Idea The basic idea of the bubble sort is to process the
array from left-to-right (index 0, index 1, etc…) At each element, we look to the next element to
the right and find the lower value. If the element to the right is less than the current one, we swap the two elements.
Then, we move on to the next element and repeat the process.
You can pass through the array N-1 times, where N is the size of the array (or less if you practice techniques to make the sort more efficient).
CISC 105 – Topic Final
Review Section 2
Bubble Sort : An Example
24 98 4 3 55 62
X[1] X[2] X[3] X[4] X[5]X[0]
No change as these are already in order
CISC 105 – Topic Final
Review Section 2
Bubble Sort : An Example
24 98 4 3 55 62
X[1] X[2] X[3] X[4] X[5]X[0]
98 and 4 will switch positions
CISC 105 – Topic Final
Review Section 2
Bubble Sort : An Example
24 4 98 3 55 62
X[1] X[2] X[3] X[4] X[5]X[0]
98 and 3 will switch positions
CISC 105 – Topic Final
Review Section 2
Bubble Sort : An Example
24 4 3 98 55 62
X[1] X[2] X[3] X[4] X[5]X[0]
98 and 55 will switch positions
CISC 105 – Topic Final
Review Section 2
Bubble Sort : An Example
24 4 3 55 98 62
X[1] X[2] X[3] X[4] X[5]X[0]
98 and 62 will switch positions
CISC 105 – Topic Final
Review Section 2
Bubble Sort : An Example
24 4 3 55 62 98
X[1] X[2] X[3] X[4] X[5]X[0]
Note that you have just completed one pass of the bubble sort. Unlike the selection sort, the bubble sort results in the highest number in the array being in the highest position at the end of one pass.
CISC 105 – Topic Final
Review Section 2
Introduction to Searching Searching an array is a closely related
problem to sorting an array. The simplest approach to array searching is
the linear search. This searching method consists of examining
the array elements from left to right. If the target is found, we save the index
where it was found and stop. If not, and there are still more array elements to the right, we move to the next element and repeat.
CISC 105 – Topic Final
Review Section 2
The Linear Search Thus, we simply start at index 0
and see if the target is there. If so, we stop.
If not, we move to index 1 and see if the target is there.
If not, we move to index 2 and see if the target is there.
etc…
CISC 105 – Topic Final
Review Section 2
Linear Search: An Example
24 98 4 3 55 62
X[1] X[2] X[3] X[4] X[5]X[0]
55 is located at index 4!
We will perform a linear search on the array X in orderto find the target value of 55.
CISC 105 – Topic Final
Review Section 2
Searching Algorithms The linear search is not a very
efficient algorithm. Notice that this algorithm does not
depend on, or require, that the array is sorted, or in any order at all.
If the array is sorted, we can use a much more efficient searching algorithm, the binary search.
CISC 105 – Topic Final
Review Section 2
The Binary Search The binary search is very intuitive.(1) Begin with the entire array(2) Select the middle element. (3) If the target is less than the middle element,
choose the next subarray to be the half of the array to the left (smaller than) the middle element. If the target is greater than the middle element, choose the next subarray to be the half of the array to the right (greater than) the middle element.
(4) Then, repeat on the new subarray.
CISC 105 – Topic Final
Review Section 2
Binary Search: An Example
3 4 24 25 55 62
X[1] X[2] X[3] X[4] X[5]X[0]
55 is located at index 4!
98
X[6]
We will perform a binary search on the array X in orderto find the target value of 55.
CISC 105 – Topic Final
Review Section 2
Summary Searching and sorting arrays are
common problems in computer science. Both problems, like almost all problems,
have multiple solutions. Solutions vary in terms of their
complexity and efficiency. We have examined the selection sort,
the bubble sort, the linear search, and the binary search.
Topic 9C – Multiple Dimension Arrays
CISC 105 – Topic Final
Review Section 2
Multiple Dimension Arrays A multiple dimension array is an array
that has two or more dimensions. Two dimensional arrays are the simplest
type of multiple dimension arrays. They can be used to represent tables of data, matrices, and other two dimensional objects.
One of the most obvious example of a two dimensional array is the tic-tac-toe board.
CISC 105 – Topic Final
Review Section 2
Multiple Dimension Arrays Example: Tic-Tac-Toe A tic-tac-toe board has two dimensions,
the row and the column. Each dimension is composed of 3 possible indices (there are 3 rows and 3 columns).
0
1
2
0 1 2
[0][0] [0][1] [0][2]
[1][0]
[2][0]
[1][1] [1][2]
[2][1] [2][2]
CISC 105 – Topic Final
Review Section 2
Two Dimensional Arrays We can see how a two dimensional
array looks like a table or matrix. Thus, we can represent a two
dimensional array as rows and columns. To declare a two-dimensional array:
(data type) array_name[# of rows][# of columns];
CISC 105 – Topic Final
Review Section 2
Two Dimensional Arrays Declarations Therefore, a two dimensional array of
integers, named x, with 29 rows and 33 columns would be declared as:
int x[29][33]; A two dimensional array of
characters, named c, with 119 rows and 2 columns would be declared as:
char c[119][2];
CISC 105 – Topic Final
Review Section 2
Referencing Multiple Dimension Arrays To access an element of a multiple
dimension array, we use the same form as for one dimensional arrays, with the extra dimension(s) also present, such as: x[2][7] = x[1][7] + 27; y[9][2][0][4] = 9; printf(“%d”,p[3][4][5][9][0]);
CISC 105 – Topic Final
Review Section 2
Initialization of Multiple Dimension Arrays Multiple dimension arrays can be
initialized in much the same way as one dimensional arrays.
char board[3][3] = { {‘X’, ‘X’, ‘O’}, {‘O’, ‘X’, ‘O’},
{‘X’, ‘O’, ‘X’} }; Notice how the initialization list is
grouped into rows.
CISC 105 – Topic Final
Review Section 2
Initialization of Multiple Dimension Arrays In addition to grouping the initialization
list into rows, the initialization list can simply be provided as a straight list:
char board[3][3] = {‘X’,‘X’,‘O’,‘O’,‘X’, ‘O’,‘X’,‘O’,‘X’};
This type of initialization list fills in the first row, left-to-right, then the second row, left-to-right, then the third row, etc…
CISC 105 – Topic Final
Review Section 2
Initialization ofMultiple Dimension Arrays
Thus, this declaration will set board[0][0] to ‘X’, board[0][1] to ‘X’, board[0][2] to ‘O’, board[1][0] to ‘O’, board[1][1] to ‘X’, board[1][2] to ‘O’, board[2][0] to ‘X’, board[2][1] to ‘O’, board[2][2] to ‘X’.
char board[3][3] = {‘X’,‘X’,‘O’,‘O’,‘X’, ‘O’,‘X’,‘O’,‘X’};
CISC 105 – Topic Final
Review Section 2
Summary Multiple dimension arrays are very similar
to one dimensional arrays, in declarations, initialization, and referencing.
When passing a multiple dimension array into a function, the size of the dimensions MUST be specified (in contrast to one dimensional arrays), with the exception of the size of the first array dimension.
Topic 10 - Strings
CISC 105 – Topic Final
Review Section 2
Characters and Strings Thus far, we have not used the char data type too much, as most applications deal with a group of characters, a data structure known as a string.
The C programming language implements the string as an array of characters (chars).
CISC 105 – Topic Final
Review Section 2
String Declarations A string, as it is simply an array of
characters, is declared as:char string1[20];
This declares a string named string1 which can hold strings from length 0 to length 19.
Notice that this fact means we “lose,” or cannot use one of the 20 characters declared. We will see why this is shortly.
CISC 105 – Topic Final
Review Section 2
String Initialization Strings can be initialized using a
string constant, in this form:char string1[20] = “Hello there”;
So, what does this string look like in memory?H e l l o t h e r
e \0 ? ? ? ? ? ? ? ?
CISC 105 – Topic Final
Review Section 2
Strings in Memory
As can be seen, the first characters (array elements) are the initialization string. Then comes a \0 character. This is the null character. This is a special character that means “end of string”. The array elements that follow the null character are not initialized, therefore their contents are indeterminate and unknown.
H e l l o t h e r
e \0 ? ? ? ? ? ? ? ?
CISC 105 – Topic Final
Review Section 2
Strings in Memory All strings must end with a null
character. When a string is enclosed in double quotes, i.e. “Hello there”, a null character is automatically inserted.
The double quotes mean “the string is whatever is inside the quotes followed by a null character.”
CISC 105 – Topic Final
Review Section 2
Strings in Memory The requirement of this null
character to indicate the end of the string shows why a string declaration of char string1[20];can only hold strings of length 0 to 19. The one “lost” character of the twenty allocated for string1 is needed for the null character.
CISC 105 – Topic Final
Review Section 2
String Input/Output The standard C input and output
functions, printf and scanf can directly work with strings using the placeholder “%s”.
For example, what is the output of the following program fragment?
char string1[20] = “Hello there.”;
printf(“%s”,string1); Hello there.
CISC 105 – Topic Final
Review Section 2
String Input/Output The printf function, as well as other
functions that work with strings, depend on the strings they receive as arguments to be terminated with the null character.
Therefore, it is important that whenever a programmer-written function constructs an array, it inserts the null character at the end of the array.
CISC 105 – Topic Final
Review Section 2
String Input/Output We can also use the “%s” placeholder
with the scanf statement. For instance, to read a string from the keyboard and place it in string1:
char string1[20];
scanf(“%s”,string1);
CISC 105 – Topic Final
Review Section 2
String Input/Output
Notice that we do not use the “&” operator on string1.
Remember that the name of an array is the memory address of its first element. Thus, since string1 is a memory address, it does not need the “address of” operator.
char string1[20];
scanf(“%s”,string1);
CISC 105 – Topic Final
Review Section 2
String Input/Output Using the scanf function with the “%s”
placeholder stores the user input string in the character array (string) corresponding to the placeholder.
This input function does NOT check to make sure the string it read from the keyboard is short enough to fit in the specified character array.
Thus, it is possible to overrun the character array using a scanf statement. Thus, make sure the array that you are scanfing into is large enough to handle all possible inputs.
CISC 105 – Topic Final
Review Section 2
String Operations and Assignment Previously, we have seen the
assignment operator “=” used to store data in a variable.
We can use the “=” operator during string initialization (setting an initial value when the string is declared).
This is the ONLY time we can use the assignment operator to set a string.
CISC 105 – Topic Final
Review Section 2
String Operationsand Assignment We have seen before that the name of an
array is the memory address of the first element of that array (in this case, the first character in the string).
Thus, any statement such as:char string1[20];string1 = “Hello”;would attempt to set the address of the first element of the array, which cannot be changed by using such an assignment statement.
CISC 105 – Topic Final
Review Section 2
String Operationsand Assignment C provides a number of routines to
manipulate strings, through library functions.
All of the string manipulation functions are defined in string.h.
Each of the string manipulation functions takes, and returns, variables of type char *. Keep in mind that a string is represented by the memory address of its first element (as is always true with arrays).
CISC 105 – Topic Final
Review Section 2
String Operationsand Assignments The first, and most basic, string
manipulation library function is the string-copy function, strcpy().
This function takes two parameters, the destination string and the source string.
Its prototype looks like:strcpy(char *dest, const char *source);
CISC 105 – Topic Final
Review Section 2
The strcpy Function This function makes a copy of the source
string in the destination string. This is a simple example of the strcpy()
function:char string1[20];
strcpy(string1,”Hello there”); This code fragment sets string1 to “Hello
there” (with the last ‘e’ followed by a null character, as indicated with the double quotes).
CISC 105 – Topic Final
Review Section 2
The strcpy Function
? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ?
H e l l o t h e r
e \0 ? ? ? ? ? ? ? ?
char string1[20];
strcpy(string1,”Hello there”);
string1
string1
CISC 105 – Topic Final
Review Section 2
The strcpy Function It is important to note that the strcpy
function does not perform any bounds checking.
Therefore, just as like using the “%s” placeholder with scanf, we can overflow the destination array.
It is important to ensure the destination array is large enough to hold the string that the strcpy function will place in it.
CISC 105 – Topic Final
Review Section 2
The strcpy Function When such an overflow occurs, the same
problems that were discussed for array overstepping can occur.
Most of the time, the array will overflow into unallocated memory.
However, if the memory cells immediately following the array are allocated and then the strcpy function oversteps the array bounds, it can overwrite the variables which are allocated to these memory cells.
CISC 105 – Topic Final
Review Section 2
Substrings
Keep in mind that string evaluates to the address of the first character, or string = &string[0].
Using this, we can see how to use a substring. For example, to reference the substring “there”, we could simply use &string[6] instead of string.
H e l l o t h e r
e \0 ? ? ? ? ? ? ? ?
string
CISC 105 – Topic Final
Review Section 2
String Lengths Notice that the size of the
character array is an upper limit on the size of the string it can contain.
Thus, we need some way to find the size of the string contained in a character array (the actual number of characters present before the null character).
CISC 105 – Topic Final
Review Section 2
String Lengths This can be determined using the
strlen function. This function takes one parameter, a char * (or string name) and returns one value, the length in characters of the string, a size_t value, which is an unsigned integer.
CISC 105 – Topic Final
Review Section 2
String Lengths What would be the output of the
following program fragment?H e l l o t h e r
e J o h n \0 ? ? ?
string
int string_size;string_size = strlen(string);printf(“Size = %d\n”,string_size);
Size = 16
CISC 105 – Topic Final
Review Section 2
String Lengths Note that the strlen function determines
the number of characters between the memory address provided (normally the string name, thus the address of the first character) and the first-encountered null character.
If a string does not end in a null character, the function will not work correctly.
CISC 105 – Topic Final
Review Section 2
String Lengths Additionally, if a string is overstepped (a
longer string is stored than characters allocated), the string length, as reported by strlen, could be greater than the size of the character array declared to hold the string.
Note that this is NOT valid. Strings should not overflow their array size; such an overflow is not correct programming and could result in incorrect program operation.
CISC 105 – Topic Final
Review Section 2
String Concatenation Sometimes, a program may need to
append one string onto another string. This is known as concatenation, or
concatenating the arrays. This is accomplished using the C library
functions strcat and strncat. The strncat function is simply a
“counted” version of strcat, just as strncpy is a “counted” version of strcpy.
CISC 105 – Topic Final
Review Section 2
String Concatenation This function, strcat, takes two parameters,
the destination string and the source string. This function takes the second string and
appends it to the first string, overwriting the null character at the end of the first string with the first character of the second string.
The last character copied onto the end of the first string is the null character of the second string.
CISC 105 – Topic Final
Review Section 2
String ConcatenationH e l l o \0
J i m \0
string1
string2
char string1[10] = “Hello”;char string2[10] = “Jim”;
CISC 105 – Topic Final
Review Section 2
String ConcatenationH e l l o \0
J i m \0
string1
string2
char string1[10] = “Hello”;char string2[10] = “Jim”;
strcat(string1,string2);
J i m \0
CISC 105 – Topic Final
Review Section 2
String Concatenation Bear in mind that the strcat (and
strncat) functions assume ample space in the destination array to hold what is copied into it.
No bounds checking is present…so make sure the first array (the one that is being copied to) is big enough to hold the contents of both strings!
CISC 105 – Topic Final
Review Section 2
String Comparison Frequently, we may wish to compare
strings. For integers, floating-point numbers, and
other such data types, we can use simple comparison operators such as:int x=9, y=27;
if (x < y) { … }
if (y < x) { … }
if (y == x) { … }
CISC 105 – Topic Final
Review Section 2
String Comparison If we were to do this with strings…char string1[20] = “Hello.”;char string2[20] = “A dog.”;if (string1 < string2) { … }
This is a valid comparison; however it does not compare the strings “Hello.” and “A dog.”
As the name of an array is the memory address of its first element, this comparison statement tests to see if the memory address string1 begins at is less than the memory address string2 begins at.
CISC 105 – Topic Final
Review Section 2
String Comparison Thus, C provides the strcmp function to
compare strings. This function takes two strings and
returns an integer value: A negative integer if str1 is less than str2. Zero if str1 equals str2. A positive integer if str1 is greater than str2.
So, when is a string less than, equal to, or greater than another string?
CISC 105 – Topic Final
Review Section 2
String Comparison The simplest case is that of
equality. If the two strings are the same length (same number of characters) and each character of one string is equal to the corresponding character in the other string, the strings are considered equal.
CISC 105 – Topic Final
Review Section 2
String Comparison There are two rules for less
than/greater than and strings: If the first n characters of str1 and str2
match and str1[n] and str2[n] are the first non-matching characters, str1 is less than str2 if str1[n] < str2[n].
If str1 is shorter in length than str2 and all of the characters of str1 match the corresponding characters of str2, str1 is less than str2.
CISC 105 – Topic Final
Review Section 2
String Comparison So what would be the result of the
following comparison function calls? strcmp(“hello”,“jackson”); strcmp(“red balloon”,“red car”); strcmp(“blue”,“blue”); strcmp(“aardvark”,“aardvarks”);
CISC 105 – Topic Final
Review Section 2
String Input/Output Functions We have already seen the printf
and scanf functions as the primary method of input and output in the C language.
We can now introduce sprintf and sscanf which use a string instead of the principle I/O devices (the keyboard and the display screen).
CISC 105 – Topic Final
Review Section 2
String Input/Output Functions We can use the sprintf function to
create a string. This function works the same as printf except that it takes one additional parameter, the string to store the result in.
The format of sprintf is:sprintf(string,format string,
print list); Notice that the format is the same as for
printf with the addition of the string.
CISC 105 – Topic Final
Review Section 2
String Input/Output Functions So, the sprintf function works the
exact same as the printf function except that instead of displaying the resulting text, it stores it in the specified string.
Note that this function, like all others that operate on strings, does not do bounds checking.
CISC 105 – Topic Final
Review Section 2
String Input/Output Functions This program fragment
int month = 12;
int day = 25;
int year = 2000;
char string1[20];
sprintf(string1, “%d/%d/%d”,
month,day,year);
would store the string “12/25/2000” in the character array string1.
CISC 105 – Topic Final
Review Section 2
String Input/Output Functions Just as sprintf is simply a version of
printf that outputs to a string and not the display, sscanf is a version of scanf that takes input from a string and not the keyboard.
The format of sscanf is:sscanf(string,format string,
scan list); Notice that the format is the same as
for scanf with the addition of the string.
CISC 105 – Topic Final
Review Section 2
String Input/Output Functions This program fragment
char string1[20] = “12/25/2000”;
int month;
int day;
int year;
sscanf(string1, “%d/%d/%d”,
&month,&day,&year);
would store the value 12 in month, the value 25 in day, and the value 2000 in year.
Topic 11 – Structures
CISC 105 – Topic Final
Review Section 2
Introduction to Structures We have seen that an array is a list of
the same type of elements. A structure is a collection of differing
data types. It is usually used to implement a record (as in a database record).
For example, a good use of a structure would be to represent a student’s record in a class / grading database.
CISC 105 – Topic Final
Review Section 2
Introduction to Structures For each student, the program needs to
store the student’s last, middle, and first names, their student ID number, their numerical grade (course average) and their final course grade.
Thus, for each student record, we need four strings (each name and the ID number), a float (numerical grade), and a character (letter grade).
CISC 105 – Topic Final
Review Section 2
Introduction to Structures Thus, we can define a structure to hold
a student record as:typedef struct {
char last[20];
char middle[20];
char first[20];
float numerical_grade;
char letter_grade;
} student_record;
CISC 105 – Topic Final
Review Section 2
Structures A structure definition goes outside of
any function, including main(). This is similar to function prototypes
which precede main. A good idea is to place structure definitions immediately before function prototypes.
Once the structure definition is present, variables of the structure data type can now be declared inside functions.
CISC 105 – Topic Final
Review Section 2
Structures For example,
typedef struct {char last[20], middle[20], first[20];float numerical_grade;char letter_grade;
} student_record;
int main(){
float a, b, cstudent_record TopStudent;student_record others[175];int x, y, z;. . .
}
CISC 105 – Topic Final
Review Section 2
Structures For example,
typedef struct {char last[20], middle[20], first[20];float numerical_grade;char letter_grade;
} student_record;
int main(){
float a, b, cstudent_record TopStudent;student_record others[175];int x, y, z;. . .
}
Here, we declare onevariable of type
student_record namedTopStudent.
CISC 105 – Topic Final
Review Section 2
Structures For example,
typedef struct {char last[20], middle[20], first[20];float numerical_grade;char letter_grade;
} student_record;
int main(){
float a, b, cstudent_record TopStudent;student_record others[175];int x, y, z;. . .
}
Here, we declare anarray of 175 variables of type
student_record namedothers.
CISC 105 – Topic Final
Review Section 2
Structures Note that for each variable of type
student_record, we can store 3 strings, 1 floating point number, and one character.
So, the question remains…how do we access all of these variables contained within our new programmer-designed data type?
CISC 105 – Topic Final
Review Section 2
Structure Pointers C provides the indirect component selection
operator “->”. This is a dash followed by a greater-than sign, which forms an arrow-like operator.
This new, indirect operator takes a pointer to a structure variable on the left side and the component name to be accessed on the right side.
This is a contrast to the direct component selection operator “.” This operator takes a structure variable on the left side and the component name to be accessed on the right side.
CISC 105 – Topic Final
Review Section 2
Structure Pointers Thus, the following expressions are
equivalent:(*best_p).last best_p->last(*best_p).first best_p->first(*best_p).letter_grade
best_p->letter_grade
Note that either form is correct, however, the form on the right side is more clear and straight-forward.
CISC 105 – Topic Final
Review Section 2
Structure Pointers Thus, we can rewrite our function
output parameter example:int read_record(student_record *record_p){
int result;result = scanf(“%s %s %s %f %c”,
record_p->last,record_p->middle,record_p->first,&record_p->numerical_grade,&record_p->letter_grade);
if (result == 5) { return 1; }else { return 0; }
}
CISC 105 – Topic Final
Review Section 2
Summary A structure is a programmer-defined
datatype that is a record (a collection of variables of varying datatypes).
An individual component of a structure can be accessed using a structure variable name and the “.” operator.
We can make a pointer to a structure in the same way we can make a pointer to any other datatype.
CISC 105 – Topic Final
Review Section 2
Summary An individual component of a
structure can be access using a pointer to a structure and the “->” operator.
Topic 12 –Linked Lists
CISC 105 – Topic Final
Review Section 2
The Linked List Now that we understand the
concept of dynamic memory allocation, we can look at a linked list.
A linked list is a data structure which is a sequence of nodes in which each node is linked, or connected to, the node following it.
CISC 105 – Topic Final
Review Section 2
The Linked List
Data 1
Next node
Data 1 Data 2
Next node
Data 2 Data 3
Next node
Data 3
Data 4
NO NEXT
Data 4
CISC 105 – Topic Final
Review Section 2
The Linked List In this linked list example, each node
has two pieces of data. Each node also has a pointer to the next node.
So, we need two things to form a linked list: a way to combine various datatypes and variables together into one datatype and a way to “point” to the next one of these combination datatypes.
So…how can we accomplish this?
CISC 105 – Topic Final
Review Section 2
The Linked List The first goal, combining various
datatypes and variables into one datatype, is easily handled with a structure.
The second goal, being able to “point” to the next structure is easily handled using pointers.
So, we have all of the components we need in order to construct a linked list.
CISC 105 – Topic Final
Review Section 2
Structures with Pointer Components We can form a linked list by defining
a structure with a pointer component.
typedef struct a_node {
char lastname[20];
float num_grade;
struct a_node *next_p;
} a_node2;
CISC 105 – Topic Final
Review Section 2
Structureswith Pointer Components
The a_node name is known as a structure tag. What it does is let us use the phrase struct a_node as an alternative to using the word a_node2.
We use this as the datatype for the link pointer, as the compiler has not yet reached the definition of the word a_node2. It has reached the definition of the phrase struct a_node, so we can use this as the datatype.
typedef struct a_node {char lastname[20];float num_grade;struct a_node *next_p;
} a_node2;
CISC 105 – Topic Final
Review Section 2
Structureswith Pointer Components
This definition is illegal and will result in a compile error. When the compiler reaches the declaration of the link pointer, it does not yet know what an a_node2 is. Thus, this will cause a compiler error.
typedef struct {char lastname[20];float num_grade;a_node2 *next_p;
} a_node2;
CISC 105 – Topic Final
Review Section 2
Structureswith Pointer Components
Notice that when we use this structure tag, we need to use the entire phrase struct a_node and not simply a_node.
typedef struct a_node {char lastname[20];float num_grade;struct a_node *next_p;
} a_node2;
CISC 105 – Topic Final
Review Section 2
Creating a Linked List We can then setup a linked list
using these structures:a_node2 *node1_p, *node2_p, *node3_p;node1_p = (a_node2 *)malloc(sizeof(a_node2));node2_p = (a_node2 *)malloc(sizeof(a_node2));node3_p = (a_node2 *)malloc(sizeof(a_node2));strcpy(node1_p->lastname, “Smith”);strcpy(node2_p->lastname, “Jones”);strcpy(node3_p->lastname, “Williams”);node1_p->num_grade=90; node2_p->num_grade=20;node3_p->num_grade=100;node1_p->next_p = node2_p;node2_p->next_p = node3_p;node3_p->next_p = NULL;
CISC 105 – Topic Final
Review Section 2
Address = 2370
2370
Address = 1080
1080
Address = 1000
1000
Creating a Linked List
Node1_p Node3_pNode2_p
Smith WilliamsJones
90 20 100
1080 2370 NULL
CISC 105 – Topic Final
Review Section 2
Creating a Linked List Notice that if we have the pointer to the
first node in the linked list, we do not need the pointers to the other nodes, as the first node contains a pointer to the second node, the second node contains a pointer to the third node, etc.
Thus, we can access any node in the linked list by starting at the first node and following the link pointers.
Thus, we can think of a linked list as . . .
CISC 105 – Topic Final
Review Section 2
Creating a Linked List
Address = 2370Address = 1080Address = 1000
1000
Node1_p
Smith WilliamsJones
90 20 100
1080 2370 NULL
CISC 105 – Topic Final
Review Section 2
Accessing the DataContained in a Linked List So, we can see that node1_p points
to the first node in our linked list. This first node is known as the head of the linked list.
We can access the data in the first node by using the “->” operator:
printf(“Name:%s\n”,node1_p->lastname);
printf(“Grade:%f\n”,node1_p->num_grade);
CISC 105 – Topic Final
Review Section 2
Accessing the Data Contained in a Linked List The first node also contains a pointer to
the second node. Therefore, we can access this pointer and use it to access the data in the second node:
printf(“Name?”); scanf(“%s”,node1_p->next_p->lastname);printf(“Grade?”);scanf(“%f”,&(node1_p->next_p->num_grade));printf(“Name:%s”,node1_p->next_p->lastname);printf(“Grade:%f”,node1_p->next_p->num_grade);
CISC 105 – Topic Final
Review Section 2
Accessing the DataContained in a Linked List We can access the data contained in
nodes past the second node in the same manner; we can simply follow the pointers to the “next node” until we arrive at the node that contains the data we want to access.
Thus, if the address stored in node1_p is known by a function, that function can access every element (node) of the linked list.
CISC 105 – Topic Final
Review Section 2
The Tail Node Notice in the picture that the last node in
the list had its link pointer set to NULL. Thus, we can test to see if we are at the
last node in a linked list. If the link pointer of a node is set to
NULL, we are at the end of the list. If the link pointer of a node is not set to NULL, it will point to the next node in the list.
CISC 105 – Topic Final
Review Section 2
The Tail Node In this way, the NULL pointer is used
to indicate the end of the linked list. The last node in the linked list is
called the tail of the list. So, the head of the list is the first
node, the tail of the list is the last node, and we can tell that we are at the tail of the list if the link pointer is set to NULL.
CISC 105 – Topic Final
Review Section 2
Linked List Advantages Linked lists provide a number of
advantages. First and foremost, they are perfectly
sized for the data that they store. When a data record is encountered, a node to store it is allocated. This defeats the limitations of arrays, where we needed to know the array size at program compile time.
CISC 105 – Topic Final
Review Section 2
Linked List Advantages As linked lists are “linked” using
pointers, it is easy to manipulate them.
Two common operations that can be easily performed on linked lists are the insertion of a node into the list (at some point) and the deletion of a node from the list.
CISC 105 – Topic Final
Review Section 2
Linked List Advantages:Inserting a Node into the List
Address = 2370Address = 1080Address = 1000
1000
Node1_p
Smith WilliamsJones
90 20 100
1080 2370 NULL
Address = 8460
Norton
98
2370
8460
CISC 105 – Topic Final
Review Section 2
Linked List Advantages:Deleting a Node from the List
Address = 2370Address = 1080Address = 1000
1000
Node1_p
Smith WilliamsJones
90 20 100
1080 2370 NULL2370
CISC 105 – Topic Final
Review Section 2
Linked List Traversal A common operation on a linked list
is traversing a list. This means that we keep following the link pointers until we arrive at the end of the list.
We can write a function that traverses the linked list we have previously made, displaying the data stored in each node.
CISC 105 – Topic Final
Review Section 2
Linked List Traversal
void display_list(a_node2 *head_p){
a_node2 *current_p;if (head_p == NULL)
printf(“Empty List!”);else{ current_p = head_p; while (current_p != NULL) { printf(“%s:”,current_p->lastname); printf(“%d\n”,current_p->num_grade); current_p = current_p->next_p;
} }}
CISC 105 – Topic Final
Review Section 2
Linked List Traversal
We can also write a function that searches a linked list for a target data item, in this case, a last name.
CISC 105 – Topic Final
Review Section 2
Linked List Traversal
a_node2 * serach_list(a_node2 *head_p, char target[]){
a_node2 *current_p;for(current_p = head_p;
current_p != NULL && strcmp(current_p->lastname,target) != 0; current_p = current_p->next)
{ }return current_p;
}
top related