Week 07
Nerds You Should Know #6 | 1/45 |
... Nerds You Should Know #6 | 2/45 |
John von Neumann
|
|
Data and Memory | 3/45 |
For the next two lectures ...
malloc()
free()
Data | 4/45 |
Values of various types (1
-2
3.14
'A'
'1'
"abc"
The C language supports:
int
unsigned int
long
char
float
double
sizeof()
... Data | 5/45 |
Data exists outside programs in files
A file is a sequence of bytes, accessed sequentially
The FILE *
Every C program is connected to three streams:
stdin
stdout
stderr
stdio.h
getc
putc
fgets
fputs
scanf
printf
... Data | 6/45 |
Ways to input data into a program:
prompt$ prime1 719 promtp$ ohce rise to vote sir
argv[1] == "719" argv[1] == "rise" && argv[2] == "to" && argv[3] == "vote" && argv[4] == "sir"
sscanf(argv[1], "%d", &number)
... Data | 7/45 |
Ways to input data into a program:
stdin
prompt$ ./floats Enter a number: 3.141593 Enter a number: 2.718282 The greater number is 3.141593
scanf()
getchar()
fgets(...,stdin)
<
prompt$ more xy.txt 3.141593 2.718282 prompt$ ./floats < xy.txt Enter a number: Enter a number: The greater number is 3.141593
Memory | 8/45 |
Memory is a very large array of bytes
0x00000000
0x7fffffff
char
int
float
*ptr
... Memory | 9/45 |
Within a program, data objects have scope and lifetime
Scope: region of program in which an object is known
... Memory | 10/45 |
Local variables and parameters:
malloc()
malloc()
free()
Pointers | 11/45 |
Pointer variables contain memory addresses
Pointers are typed (know what kind of object they point to)
Using a pointer to access a simple memory object:
int x, y, *xp; xp = &x; *xp = 5; y = *xp+2;
Using a pointer to access a structured object:
typedef struct { int x; float y; char z; } Rec; Rec r, *rp; rp = &r; (*rp).x = 5; rp->z = 'm';
... Pointers | 12/45 |
For a function to be able to change the "actual" value of a variable, we need to pass a pointer as a parameter.
swap()
void swap(int a, int b) { int temp; temp = a; a = b; b = temp;// only the local "copies" of a and b will swap } void test(void) { int a = 5, b = 7; swap(a, b); printf("a = %d, b = %d\n", a, b);// a and b will have their original value }
... Pointers | 13/45 |
swap()
void swap(int *p, int *q) { int temp; temp = *p; *p = *q; *q = temp;// will change the actual values of a and b } void test(void) { int a = 5, b = 7; swap(&a, &b); printf("a = %d, b = %d\n", a, b);// a and b will now be successfully swapped }
Arrays | 14/45 |
Arrays contain a sequence of values of the same type.
Each array is defined as:
#define N NumOfElems ElemType a[N];
Elements are accessed via a[0]
a[1]
a[N-1]
The name a
&a[0]
Iteration over arrays:
// index-based int i; for (i = 0; i < N; i ++) { ... a[i] ... }// pointer-based ElemType *p; for (p = a; p < &a[N]; p++) { ... *p ... }
Exercise: Implementing string.h | 15/45 |
C strings are arrays of bytes, terminated by '\0'
Implement the following operations from the string.h library:
typdef char *String; int strlen(const String s); String strcpy(String dest, const String src);
Use indexed-based iteration for strlen()
strcpy()
The const
Structs | 16/45 |
Structs contain a named collection of values of various types.
Structs are defined as:
struct StructTag { Type1 FieldName1; Type2 FieldName2; ... Typen FieldNamen; };
Often, we define structs
typedef
typedef struct StructTag {...} StructTypeName;
Dynamic Data Structures |
... Dynamic Data Structures | 18/45 |
Dynamic data structures are built at runtime.
Linked lists are an example. They are defined as:
typedef struct node { DataT data;// e.g. int data; struct node *next; } NodeT;
... Dynamic Data Structures | 19/45 |
Iterating over an existing linked list NodeT *list
NodeT *p = list; while (p != NULL) { ... p->data ...// do something with the data p = p->next;// move forward }
... Dynamic Data Structures | 20/45 |
Creating a new list through iteration
NodeT *list; int i; for (i = 1; i < N; i += 2) {// fill list with odd numbers list = makeNode(i);// create new node list = list->next;// move forward } printList(list);
... Dynamic Data Structures | 21/45 |
Creating a new list through iteration
NodeT *list, *head; head = makeNode(1); list = head;// both point to the first node int i; for (i = 3; i < N; i += 2) { list->next = makeNode(i);// create and link new node list = list->next;// move forward } printList(head);
... Dynamic Data Structures | 22/45 |
Stacks are a form of linked lists used to model:
... Dynamic Data Structures | 23/45 |
Queues are a form of linked lists used to model:
Abstract Data Types |
Abstract Data Types | 25/45 |
Abstract data types (ADTs) are ...
Example: Quack ADT | 26/45 |
Implement a data structure called Quack (QUeue and stACK):
... Example: Quack ADT | 27/45 |
The operations are contained in a header file quack.h
typedef struct _node *Quack; Quack createQuack(void);// create and return Quack void push(int, Quack);// put the given integer onto the quack int pop(Quack);// pop and return the top element on the quack int isEmptyQuack(Quack);// return 1 if Quack is empty, else 0 void makeEmptyQuack(Quack);// remove all the elements on Quack void showQuack(Quack);// print contents of Quack, from the top down
push()
pop()
Quack
A Linked List Implementation of a Quack | 28/45 |
createQuack()
// quackLL.c: a linked-list-based implementation of a quack #include "quack.h" #define HEADDATA -99999// dummy data struct _node { int data; struct _node *next; }; Quack createQuack(void) { Quack head = (Quack)malloc(sizeof(struct _node)); assert(head != NULL); head->data = HEADDATA;// should never be used head->next = NULL; return head; }
... A Linked List Implementation of a Quack | 29/45 |
push(data,qs)
data
qs
void push(int data, Quack qs) { if (qs == NULL) { fprintf(stderr, "push: quack not initialised\n"); } else { Quack newnode = (Quack)malloc(sizeof(struct _node)); assert(newnode != NULL); newnode->data = data; newnode->next = qs->next;// old top qs->next = newnode;// new top } }
... A Linked List Implementation of a Quack | 30/45 |
pop(qs)
qs
int pop(Quack qs) { int retval = 0; if (qs == NULL) { fprintf(stderr, "pop: quack not initialised\n"); } else if (isEmptyQuack(qs)) { fprintf(stderr, "pop: quack underflow\n"); } else { Quack topnode = qs->next;// top node must be there retval = topnode->data; qs->next = topnode->next;// new top free(topnode);// free the old top } return retval; }
... A Linked List Implementation of a Quack | 31/45 |
Effect of createQuack()
push()
Exercise: Implementing Quack Functions | 32/45 |
Implement the following functions for the Linked List implementation of quacks:
int isEmptyQuack(Quack);// return 1 if Quack is empty, else 0 void makeEmptyQuack(Quack);// remove all the elements on Quack void showQuack(Quack);// print contents of Quack, from the top down
Notes:
qs
qs->next == NULL
Implementing Quack Functions for Queues | 33/45 |
The quack implementations can be extended to queues
qush()
push()
... Implementing Quack Functions for Queues | 34/45 |
New interface quack.h
typedef struct _node *Quack; Quack createQuack(void);// create and return Quack void push(int, Quack);// put the given integer onto the quack void qush(int, Quack);// put the given integer onto the quack int pop(Quack);// pop and return the top element on the quack int isEmptyQuack(Quack);// return 1 if Quack is empty, else 0 void makeEmptyQuack(Quack);// remove all the elements on Quack void showQuack(Quack);// print contents of Quack, from the top down
... Implementing Quack Functions for Queues | 35/45 |
qush(data,qs)
data
qs
void qush(int data, Quack que) { if (que == NULL) { fprintf(stderr, "qush: quack not initialised\n"); } else { Quack newnode = (Quack)malloc(sizeof(struct _node)); assert(newnode != NULL); newnode->data = data; newnode->next = NULL;// will become the new bottom Quack endnode = que; while (endnode->next != NULL) {// go to end of list endnode = endnode->next; } endnode->next = newnode;// new bottom } }
Array Implementation of Quacks |
An Array Implementation of a Quack | 37/45 |
We can implement quacks as an array instead of a linked list.
Both use exactly the same .h
Quack
// quackAR.c: an array-based implementation of a quack #include "quack.h" #define HEIGHT 1000 struct _node { int array[HEIGHT]; int top; }; Quack createQuack(void) { Quack qs = (Quack)malloc(sizeof(struct _node)); assert(qs != NULL); qs->top = -1;// note the array in struct _node does not get initialised return qs; }
Exercise: Re-implementing Quack Functions | 38/45 |
Re-implement push()
qush()
pop()
push()
qush()
pop()
... Exercise: Re-implementing Quack Functions | 39/45 |
For the array implementation of quacks, re-implement the other functions
int isEmptyQuack(Quack);// return 1 if Quack is empty, else 0 void makeEmptyQuack(Quack);// remove all the elements on Quack void showQuack(Quack);// print contents of Quack, from the top down
Which of these functions can be exactly the same in both quack implementations?
Comparing the LL and AR Implementation | 40/45 |
struct _node
struct _node
Exercise: Testing the LL and AR Implementations of Quacks | 41/45 |
quack.h
gcc -Wall -Werror -O quackLL.c tester.c
to test the LL implementation
gcc -Wall -Werror -O quackAR.c tester.c
to test the AR implementation
Exercise: Josephus' Ring | 42/45 |
1st century Jewish historian/philosopher/mathematician
The legend:
... Exercise: Josephus' Ring | 43/45 |
2 3 1 4 12 5 11 6 10 7 9 8
and you start counting at 1, people would be removed in the order:
3 6 9 12 4 8 1 7 2 11 5
Tips for Next Quiz | 44/45 |
scanf
comp 1921 87.5
via
char str[BUFSIZ]; int i; float f; scanf("%s %d %f", str, &i, &f);
... Tips for Next Quiz | 45/45 |
Sample practice question
1->3->5->7->9->...->99 1->2->3->4->5->6->7->8->9->10->...->99->100 1->2->4->5->7->8->10->...->100
Produced: 4 Sep 2016