178 Data Structures Notes
178 Data Structures Notes
Week 1
Lect 1 - 08/01/24
N/A
Lect 2 – 10/01/24
Components of a Computer
- Processor
o Device to fetch, decode and execute instructions.
o Possibly fetching and storing data as part of execution.
o Store
The processor puts out the data to store at that address and asserts a
“WRITE” command on the control line. Details of signal timing is ignored.
o Load
The processor puts out an address and asserts a “READ” command on the
control line. Now it must wait for some device to recognize the address
and put data on the data lines.
o Designed to work with larger units of info (2, 4, 8, 16 bytes per unit) called words.
o Is the part of the computers that does the work / follows the instructions.
o Has tiny a set of memory called registers.
NI (next instruction): keeps track of where the next instruction is in
memory.
o Diff kinds of processors will have different numbers of registers
Some can be used for anything and some (like NI) have special purpose
o A device that does the following unit turned off :
- Memory
o Used to store all the instructions and data that a program can use directly
o Where instructions and data are kept as bits.
o Key details are that memory access is through Load and Store
o Store
Assume memory recognizes the address – it copies the data into a
location within.
o Load
Assume memory recognizes the address – it copies the data from location
within to the data lines.
o Has M locations [0 to M-1] called addresses.
o Each location can store some number of bits.
A location that can store 8 bits is called a byte.
o Memory is given a size in bytes (KB< MB< GB<TB<PB).
A bit can be in 1 of 2 states (0 or 1)
Only 256 patterns that can be stored in a byte all the possible
combination of 0 or 1 for each bit.
- Interconnection Bus
o A mechanism to connect processor, memory, and I/O device.
o The path that all info travels over.
o One set of wires is the address.
How the processor indicated which location it wants to read or write to.
o One set of wires is the data.
Information read from memory or information being sent to memory for
storage.
Sometimes they are the same wire; address encoded at the start and
used for data in the second part.
o Final set of wires are the control lines.
Not coved much in this course.
Into to Arduino
- Microprocessors
o Small limited capability computers in a single chip package.
o Contains:
Processing core
Flash memory and RAM
I/O peripherals
Peripherals like clocks, timers etc.
o Used in applications that benefit from small-sized or low-cost computing; where
fill fledged computers are too expensive or overkill.
o Form the centre of an embedded system.
- Arduino
o Open-source electronics and computing platform ecosystem
o Cheap and easy to learn without formal training.
o Can simply plug into a computer via USB to start programming.
o Applications
Electronic door lock
Alarm clock
3D printer
Auto watering system
Mobile robots
Etc.
- Arduino Uno R3
o Uses an ATMEL ATmega328P
Low power 8-bit micro controller up to 16 MHz clock speed
Rough estimate of how many lines of byte code instructions it can run per
second.
- Programming an Arduino
o Based on c and c++
o Can also use object programing but not in this course.
o https://ww.arduino.cc/refernce/en/
- Essential elements
o #include <arduino.h>
Contains all of the Arduino functions and sub-libraries.
o 2 mandatory functions: setup () and loop ()
o set up ()
called only once as soon as the program starts.
o Void loop ()
Called indefinitely; as soon as the loop is finished it will be called again.
Programming Paradigm
- Programming format
o Treat as a top-down problem decomposition
o Ex.
Problem: want to eat at 6pm
Solution (top level): make dinner.
Decompose one level:
Plan menu
purchase food items.
Prepare food items.
Serve food and eat.
Take each first level step and treat as a problem to decompose.
This brake down may not be optimal because the steps are linked. What if
the store does not sell what you are looking for
A loop should be used to ensure all steps can be executed.
Do {
o Plan meal
o purchase ingredients
} until all ingredients are purchased.
Ensure that the first state and end state are independent / steps are de-
coupled.
o Only 2 variations of steps
It is a sequence of smaller steps.
It is a loop; the work you repeat and the condition under which you
repeat.
o Ex. Tree planting
Problem statement: plant a tree.
1at level steps
Get tree.
Dig hole big enough for the tree roots.
Put tree in hole.
Put dirt in hole.
Water the tree
Now we have 5 smaller steps which can be turned into code
Consider step 2
This looks like a loop
While (hole is too small){
o Scoop out one shovel of dirt
)
- Building
o C is a high-level language and C programs need to be converted into low level
machine executable code
o Building is a process that converts a C program into and Executable.
o There are 4 stages to obtaining an executable file from a C program:
1. Preprocessing
2. Compilation
3. Assembly
4. Linking
- Preprocessing
o The first phase through which source code is passed.
o Includes:
Removal of comments
Expansion of Macros
Expansion of the included files
Conditional compilation
o The preprocessed output is stored in the filename.i
o Macros structures – definitions / declarations outside of main code.
o Lines that start with # are called preprocessor directives.
o #include <filename>
Allows processor to insert contents of filename at the location where the
#include directive is found.
angle brackets around the filename tell the preprocessor to look for the
file in the include path list.
o “filepath” the processor searches the file in the current directory first, then the
include path.
o #define is a way of specifying a text substitution.
The first term is the text that will be replaced, and the second term is the
replacing text.
Can be parameterized.
Ex. #define ZERO 0
- Compiling
o The next step is to compile filename.i and produce an intermediate compiled
output file filename.s
This file is in assembly level instructions.
- Assembly
o Contains machine level instructions.
o Filename.s is taken as input and turned into filename.obj (binary) by assembler.
- Linking
o The final phase in which all the linking of function calls with their definitions are
done.
o The linker knows where all the functions are implemented.
- Ex. Typical first C program
Tutorial
Pointers:
Int *var1; pointer
Int **var2; pointerToPointer
Printf(“%x”, **pointerToPointer) -> what is stored in the memory address of the variable.
Printf(“%x”, *pointerToPointer) -> memory address of the first pointer.
Printf(“%x”, pointerToPointer) -> memory address of pointerToPointer (should be the same as
the address of the variable because it is assigned to it).
- When using a pointer to cast different specifier types it is easier to simply cast it later
- Ex
- //void pointers
printf("void pointers\n");
int a = 7;
float b = 7.6;
void *ptr;
ptr = &a;
printf("Integer variable is = %d\n", *( (int*) ptr) );
ptr = &b;
printf("Float variable is = %f\n", *( (float*) ptr) );
Week 2
Lect 1 12/01/24
Pointers
Conversions (3)
Conversions (5)
- Legitimate use of a pointer cast: you know the address of some
specialized memory or register.
o #define DEVICE_ADDRESS 0xFF00100
int *p
p = DEVICE_ADDRESS; //Error in ANSI-C
p = (int *) DEVICE_ADDRESS; // OK in ANSI-C
Strings
- A string is a sequence of character, identified by double quote marks: “hello”
- This really means six characters in a row
o ‘h’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’
- Strings in C are stored in arrays of characters: char str [10]
o Warning: a “C-string” is not the same as a string type in C++ or most other
programming languages
Other Features of C
Typedef (1)
- You are able to add your own types to your programs to make code more
readable.
o typedef float real; // real is now the same as float
real r1, r2; // r1 and r2 are type real (float)
- You can also define multiple types at once
o typedef unsigned char byte, uchar, *pbyte;
byte b;
pbyte pb;
- byte and uchar are now alternate names for an unsigned char.
More interestingly, pbyte is a pointer to an unsigned char.
Typedef (2)
- enum colors {RED, GREEN, BLUE};
enum colors electron_gun;
electron_gun = RED;
Operators
Arithmetic Operators
a = b + c;
a = b – c;
a = b * c;
a = b / c; // integer if both int; double
// otherwise (note conversions)
a = b % c; // mod (or remainder)
a += 4; // same as a = a + 4;
a -= 7; // same as a = a – 7;
a = -7; // Careful!! Not the same as prior line
a = ++b; // b is incremented, then value assigned to a
a = b++; // value of b assigned to a, then b incremented
- int a, b, *c, d;
++b;
b++;
--c;
c--;
a = b++ + --d;
- Autoincrement and autodecrement adds or subtracts one unit of
value. In the case of ints and chars, this is 1. In the case of a pointer, it
depends on what the pointer points to and how the underlying
computer deals with addresses.
o This concept does not apply with floats or doubles.
- int a, b, c, k, j, m;
a = (b = 7) + (c = 9); // returns 16
- Comma operator – isn’t used much but is a standard C language component. The
expression appears as (exp1, exp2) where exp1 is evaluated, then exp2. The
result of exp2 is returned.
o k = (j=j+1, m=4); // returns 4
o The comma operator is useful for doing several things in loops.
o int s = 0;
while(++s, s < 5) {...}
Comparison Operators
- Should be pretty straightforward:
o ==, !=, <, <=, > , >=
o flag = a > b // Flag evaluates to 0 (false) or non-zero (true).
// For most compilers, you’ll get a one if true,
// but sometimes you may get numeric difference
// between a and b.
- In this course, assume that true is equivalent to 1.
- Hint: you can use the following macros:
o #define FALSE 0
#define TRUE 1
Comparison Operators
- Warning: Never compare result of a comparison to true or false.
o #define FALSE 0
#define TRUE 1
...
if(a>b) { ... } // correct
if((a>b) == TRUE){ ... } // incorrect
- Avoid equality checks with floating point.
Lect 2 17/01/24
Flow Contorl
Hybrid Storage in C
Storing Data
- We have looked at arrays – a way of storing a collection of
identical items.
- Now look at structures – collections of heterogeneous
(dissimilar) items
- Also look at unions – multiple ways to look at the same
“data”.
- today.year
o Refers to the year field in a struct date variable called today.
- pdate->year
o Refers to the year field in a struct date variable pointed to by the
struct date pointer called pdate.
- Warning: using ‘->’ when ‘.’ should be used is a common
programming
syntax error.
Memory Allocation in C
- Heap
o Allocations and deallocations are performed explicitly by the programmer
and at run time – you can allocate a block at any time and free a block at
any time
o Accessing this memory is slower
o Much larger than stack memory (usually only limited by the physical
memory
available)
o Requires pointers to access
- Static
o Reserved for global variables, or variables that have the static qualifier
which allows the scope of the variable to extend beyond it’s code block
- Stack
// static memory allocation in
// RAM
int x = 1;
char y[100];
float z = 1.255;
- Heap
// dynamic memory allocation and
// deallocation in RAM
int* m = (int*)malloc(sizeof(int));
free(m);
struct date_time {
unsigned int year;
unsigned char month;
unsigned char day;
Time time; // Time struct within date_time struct
} dt, *pdt;
free(pdt);
- The union definition allows for storing different data types in the
same memory location.
union IP4Address {
unsigned int fulladdress;
unsigned char octets [4];
};
- Interpretation: An IP4Address is a block of memory big enough to hold the larger of an unsigned int or an
array of 4 unsigned characters. On a 32-bit computer, these would be the same size. It is only one block, but
if we call it fulladdress, then we can do integer operations, and if we call it octets, we can work as
though it is 4 bytes.
// Let’s say the specification for the computer says there is a device at
// address 0xFF100040 that can be turned on by writing the value 1 to it.
iaddr.address = 0xFF100040;
*iaddr.plocation = 1;
Flow Control
- Choices
o One or none
o One or the other
o One of many
- Repetition (Iteration)
o Definite iteration
o Indefinite iteration
Pre-check
Post-check
- Form:
if(<condition>) <statement>;
//or
if(<condition>) {
<statement>;
}
- If <condition> is true (non-zero), then the <statement> will be
executed; otherwise <statement> will be skipped.
a = b > 50 ? 10 : 4;
- If b is greater than 50, a=10, else a=5. So depending on the value of
b, the value assigned to a is either 10 or 4.
- Equivalent to:
if (b > 50) {
a = 10;
} else {
a = 4;
}
switch (ch) {
case ‘A’:
statement_a;
break;
case ‘B’:
statement_b;
break;
case ‘C’:
statement_c;
break;
default:
statement_default;
}
- Suppose the break statement in case ‘B’ was missing. The code for case B would do statement_b then
statement_default.
- Switch is based on the value of ch. If ch=‘A’, the code goes to case ‘A’
- Default statement in case ch doesn’t match any of the preceding cases.
Iteration
do {
statement1;
statement2;
} while (condition);
next_statement;
- Execute statement/block of statements. Evaluate condition. If true
(non-zero), go back and do statement/block again. If false (0), go on
to next_statement.
- C tries to avoid the need for a “go to” statement (considered to be the
worst way to change program flow) by providing ways to implement
the most prevalent changes in path.
{
statement1;
break;
statement2;
continue;
// continue skip the rest of the block for the current iteration
//and move on to the next iteration
statement3;
statement4;
}
// break causes program flow to continue just after the end of the
// current block
Pointers
- A pointer is declared with a type like so
o Int* p;
- A pointer stores an address in memory as its value:
o Int a = 5; p =&a;
o // p = the address of a
Once a pointer is assigned to the address of a variable, it is said to
point to that variable – e.g., p points to a
If you take a peek at the value of p, you will see a memory address
Printf(“Value stored in variable ‘a’: %d\a”, a); // prints 5
Printf(“Address of variable ‘a’: %x\n”, &a); //prints the address of a
Printf(“Value stored in pointer ‘p’: %x\n”, p): //prints the address stored in p (in
this case the address of a)
- You are able to retrieve or change the value of whatever is stored in the memory
location pointed to by a pointer using a dereferencing operation.
o The dereferencing operator is simply an asterisk (*) placed before the
pointer name.
Every time you see the asterisk that isn’t part of a pointer’s
declaration (the initialization of the pointer), it means ‘the value
pointed to by…’
o *p = 6; should be read as “the value pointed to by p is assigned the value
of 6” which results in being assigned the value of 6.
o Int b = *p; should be read as “b is assigned that value pointed to by p”
which results in b being assigned the value of 6
Double Pointers
- A double pointer is declared with a type like so: int **dp; or like int** dp;
- A double pointer stores the address of another pointer in memory as its value
dp= &p;
o Once a double pointer is assigned to the address of another pointer, it is
said to point to that pointer – e.g., dp points to p
o If you take a peek at the value of dp, you will see a memory address – the
memory address that the pointer p is located at
- You are able to retrieve or change the address that is stored in the pointer
pointed to by a double pointer using a single dereferencing operation
o *dp = &b; // the pointer pointed to by dp (p) nor points to b
// in other words, p now points to b
- You are able to retrieve or change the value that is stored in the memory location
pointed to by the pointer pointed to by the double pointer using a single
dereferencing operation
o **dp = 10; // b now equals 10
- When would you ever want to use double pointers?
o One reason is you want to change the value of the pointer passed to a
function as the function argument, to do this you require pointer to a
pointer
It has to do with the way arguments are passed into a function:
pass by value
Pass by value means you are making a copy in memory of
the actual parameter’s value that is passed in, thus the
function uses a copy of the contents of the actual parameter.
Ex. I created a function that takes two pointers as arguments
and has them swap their values (i.e., what they’re pointing
to). A naïve implementation of this function might look
something life this:
//This code won’t swap refernces as expected
- In simple words, pass in double pointers when you want to preserve (OR retain
changes in) pointer assignments or memory allocations outside of a function’s
call.
- To gain visual understanding of how pointers and pointer-to-pointers are handled
in the C language, let’s examine one of the examples we covered during the
tutorial session:
Void example2(){
Printf(“Showing example 2: Pointers to Pointers Example\n”);
Int var = 2022;
Int* ptr:
Int** ptrToPtr;
Ptr = &var;
ptrToPtr = &ptr;
printf(“Output of var = %d\n”, var);
printf(“Output of *ptr = %d\n”, *ptr);
printf(“Output of **ptrToPter = %d\n”, **ptrToPtr);
}
Conclusion:
- The asterisk in front of pointers gives access to the content of the memory cells
they point to, a process known as dereferencing
- (*) in front of pointer gives access to the content of variables to which they are
pointing to, and these variables can be of various data types such as int, char,
float, or any other.
- (*) in front of pointer-to-pointers gives access to the content of the pointer they
are pointing to, and this content is typically the address of a memory cell.
- (**) in front of pointer-to-pointer gives access to the content of the variable
pointed to by the
pointer which in turn is pointed to by that pointe-to-pointer.
Tutoring
Syntax:
Struct name{
Int a;
Float b;
Char c;
};
Struct student{
Float GPA;
String school;
String program;
} Nathan, max;
Enum colours{
RED, \\ 0
GREEN, \\ 1
BLUE \\ 2
};
\\ computer treats them as integers instead of strings
Typedef
Syntax:
Typedef struct name newname;
Stack:
- First in last out
- Push (putting something in) and pop (taking something out)
- Compile time
o When a compiler goes through your program it goes through main frist
It then looks for the first function called in main
Then it looks for a function called within a function
Goes back to main and so on
Heap:
- Run time memory
- Explicitly defined memory
o Memory allocated at runtime
o Ie. Malloc
Link Lists:
- Nodes (can be any data to be stored)
o Usefule because you can store anything inside of it
Varibales
Structs
Functions
enums
- Head is start
- Tail is end
- Can’t only access one thing i.e. one node at a time
- Only want to use it if you want to access everything at once
Struct node{
Int data;
Struct node*next // pointer to the next node
}
Unions:
Untion A{
Unsinged int addres.
s; // 4 bytes
Unsigned char octets [4]; // 4 bytes
};
Week 3
Lect 1
Lect 2
Lect 3
Tutorial 26/01/24