gccprintf()abscanf()atoi()
❖ COMP9024 26T1 |
Helen Paik
Web Site:
❖ This term, your Teaching Team consists of ... |
| Helen Paik | ||
| K17-501C | ||
| h.paik@unsw.edu.au | ||
| non-technical/personal issue - by appointments ... | ||
| technical/course contents - Use CSE Help! (G05), or Course Forum |
| Tim Arney | ||
| David Choulex, Deniz Dilsiz, | ||
| Jiangze Zhou, Joey Zhou, | ||
| Kanak Maheshwari, Nimish Ukey, | ||
| Sachin Singh, Thomas Duffett, | ||
| Zhonghao Liu, Ziting Li | ||
| cs9024@cse.unsw.edu.au |
❖ Course Goals |
COMP9021 …
❖ Pre-conditions |
There are no prerequisites for this course.
However we will move at fast pace through the necessary programming fundamentals. You may find it helpful if you are able to:
ifwhilefor
❖ Post-conditions |
At the end of this course you should be able to:
❖ Access to Course Material |
All course information is placed on the main course website:
Bookmark the page ... a portal to all course related links (e.g., lecture content, forum, submitting assignments, viewing marks).
Access to lecture recordings on Moodle:
Ideas for the COMP9024 material are drawn from
❖ Schedule (topics are not absolutely fixed ...) |
Lectures Weekly Prac Weekly Tut Assignment Introduction, C language prac exercise -- Analysis of algorithms prac exercise problem set Dynamic data structures prac exercise problem set Graph data structures prac exercise problem set Graph algorithms prac exercise problem set Large Assignment Break -- | Search tree data structures prac exercise problem set | Search tree algorithms prac exercise problem set | String algorithms prac exercise problem set | Randomised algorithms, Review prac exercise problem set | due Final Exam (on campus) --
❖ Resources |
Textbook is a "double-header"
Good books, useful beyond COMP9024 (but coding style …)
❖ Resources (cont) |
Supplementary textbook:
Also, numerous online C resources are available.
❖ Lectures |
Lectures will:
Lecture slides will be made available before lecture
Feel free to ask questions, but No Idle Chatting (disrupts others!)
❖ Weekly Practicals |
In weeks 1-5, 7-10 :
Weekly Practicals (programming exercises) contribute 16% to overall mark ( 2 marks each x 8, best 8 chosen out of 9).
Do them yourself! and Don't fall behind!
❖ Weekly Tutorials (problem sets) |
The weekly tutorials/classes, with tutors, aims to:
You may bring your own laptop to access materials or take notes
Important - tutorials are not marked; however, they provide an opportunity for a more intimate classroom experience where you can interact more closely with the tutors and other students.
❖ Large Assignment |
The large assignment gives you experience applying tools/techniques
(but to a larger programming problem than the homework)
The assignment will be carried out individually.
The assignment will be released late Week 5 (or sometime in Week 6 ...) and is due in week 10.
The assignment contributes 24% to overall mark.
The late penalty is a per-day mark reduction equal to 5% of the max assessment mark for up to 5 days.
For example, if an assignment that would receive an on-time mark of 16/24 is submitted 3 days late, it should receive a mark of 12.4/24 (16-(24*0.05*3)).
❖ Large Assignment (cont) |
Advice on doing assignments:
They always take longer than you expect.
Don't leave them to the last minute.
Organising your time → no late penalty.
If you do leave them to the last minute:
❖ Plagiarism (cont) |
Examples of Plagiarism (student.unsw.edu.au/plagiarism):
Using same or similar idea without acknowledging the source
This includes copying ideas from a website, internet
Presenting work as independent when produced in collusion with others
This includes students providing their work to another student
Any submission based on a work of another student, or a code repository (e.g., github), or generative AI tools (e.g., ChatGPT), or contracted work is considered cheating.
Your submissions will be checked for and will be reported to the Academic Integrity Unit at UNSW.
What about ...
Find and read the use of AI policy from the course homepage
❖ Final Exam |
2-hour torture written exam during the exam period.
Format:
Must score at least 25/60 in the final exam to pass the course.
❖ Final Exam (cont) |
How to pass the Final Exam:
❖ Assessment Summary |
weekly_lab = mark for weekly program exercises (out of 2*(best 8 out of 9)) large_assn = mark for large assignment (out of 24) exam = mark for final exam (out of 60) if (exam >= 25) total = weekly_lab + mid_term + large_assn + exam else total = exam * (100/60)
To pass the course, you must achieve:
examtotal
❖ Summary |
The goal is for you to become a better Computer Scientist
❖ Why C? |
❖ Brief History of C |
C and UNIX operating system share a complex history …
❖ Basic Structure of a C Program |
// include files
// global definitions
// function definitions
function_type f(arguments) {
// local variables
// body of function
return …;
}
.
.
|
.
.
.
.
.
// main function
int main(arguments) {
// local variables
// body of main function
return 0;
}
|
❖ Exercise: What does this program compute? |
#include <stdio.h>
int f(int m, int n) {
while (m != n) {
if (m > n) {
m = m-n;
} else {
n = n-m;
}
}
return m;
}
int main(void) {
printf("%d\n", f(30,18));
return 0;
}
❖ Example: Insertion Sort in C |
Insertion Sort algorithm (in Pseudo Code):
insertionSort(A): | Input array A[0..n-1] of n elements | | for all i=1..n-1 do | | element=A[i], j=i-1 | | while j≥0 and A[j]>element do | | A[j+1]=A[j] | | j=j-1 | | end while | | A[j+1]=element | end for
e.g., A = [29, 10, 14, 37, 13]
❖ Example: Insertion Sort in C (cont) |
#include <stdio.h> // include standard I/O library defs and functions
#define SIZE 6 // define a symbolic constant
void insertionSort(int array[], int n) { // function headers must provide types
int i; // each variable must have a type
for (i = 1; i < n; i++) { // for-loop syntax
int element = array[i];
int j = i-1;
while (j >= 0 && array[j] > element) { // logical AND
array[j+1] = array[j];
j--; // abbreviated assignment j=j-1
}
array[j+1] = element; // statements terminated by ;
} // code blocks enclosed in { }
}
int main(void) { // main: program starts here
int numbers[SIZE] = { 3, 6, 5, 2, 4, 1 }; /* array declaration
and initialisation */
int i;
insertionSort(numbers, SIZE);
for (i = 0; i < SIZE; i++)
printf("%d\n", numbers[i]); // printf defined in <stdio>
return 0; // return program status (here: no error) to environment
}
❖ Compiling with gcc |
| C source code: | prog.c | |
| ↓ | a.out | (executable program) |
To compile a program prog.c
gcc prog.c
To run the program, type:
./a.out
❖ Compiling with gcc |
Command line options:
gccgcc -Wall prog.c
which reports all warnings to anything it finds that is potentially wrong or non ANSI compliant
-ogcca.outgcc -o prog prog.c
❖ Sidetrack: Printing Variable Values with printf() |
Formatted output written to standard output (e.g. screen)
printf(format-string, expr1, expr2, …);
format-string
%d | decimal | %f | floating-point | |||
%c | character | %s | string | |||
\n | new line | \" | quotation mark |
Examples:
num = 3;
printf("The cube of %d is %d.\n", num, num*num*num);
The cube of 3 is 27.
id = 'z';
num = 1234567;
printf("Your \"login ID\" will be in the form of %c%d.\n", id, num);
Your "login ID" will be in the form of z1234567.
printf("%8.3f\n", 3.14159);
3.142
❖ Basic Elements |
Algorithms are built using
❖ Assignments |
;{ }+, -, *, /, %=, +=, -=, *=, /=, %=++--
// suppose k=6 initially
k++; // increment k by 1; afterwards, k=7
n = k--; // first assign k to n, then decrement k by 1
// afterwards, k=6 but n=7
// again, suppose k=6 initially
++k; // increment k by 1; afterwards, k=7
n = --k; // first decrement k by 1, then assign k to n
// afterwards, k=6 and n=6
❖ Assignments (cont) |
C assignment statements are really expressions
v = 5; //The value of the expression is 5.
Useful because it lets you combine: (1) collecting a value (2) testing that value, into a single expression.
Frequently, assignment is used in loop continuation tests
v = getNextItem();
while (v != 0) {
process(v);
v = getNextItem();
}
is often written as
while ((v = getNextItem()) != 0) {
process(v);
}
❖ Exercise: What are the final values of ab |
a = 1; b = 5;
while (a < b) {
a++;
b--;
}
a = 1; b = 5;
while ((a += 2) < b) {
b--;
}
❖ Conditionals |
if (expression) {
some statements;
}
if (expression) {
some statements1;
} else {
some statements2;
}
some statementsexpressionsome statements1expressionsome statements2expression{ }
❖ Conditionals (cont) |
Indentation is very important in promoting the readability of the code
Each logical block of code is indented:
// Style 1
if (x)
{
statements;
}
|
// Style 2 (my preference)
if (x) {
statements;
}
|
// Preferred else-if style
if (expression1) {
statements1;
} else if (exp2) {
statements2;
} else if (exp3) {
statements3;
} else {
statements4;
}
|
❖ Conditionals (cont) |
Relational and logical operators
a > b | ab | |
a >= b | ab | |
a < b | ab | |
a <= b | ab | |
a == b | ab | |
a != b | ab | |
a && b | ab | |
a || b | ab | |
! a | logical not a |
A relational or logical expression evaluates to 10
❖ Exercise: Conditionals |
if ((x > y) && !(y-x <= 0)) {
printf("Aye\n");
} else {
printf("Nay\n");
}
xx = (x >= 0) + (x < 0);
Nay
x10x == 1
❖ Loops |
C has two different "while loop" constructs
// while loop
while (expression) {
some statements;
}
|
// do .. while loop
do {
some statements;
} while (expression);
|
|
int x = 5;
while (x < 3) {
printf("%d\n", x);
x++;
}
//output: nothing
|
int x = 5;
do {
printf("%d\n", x);
x++;
} while (x < 3);
//output: 5
|
The do .. while
❖ Loops (cont) |
The "for loop" in C
for (expr1; expr2; expr3) {
some statements;
}
expr1expr2expr3
| Example: |
for (i = 1; i < 10; i++) {
printf("%d %d\n", i, i * i);
}
|
❖ Exercise: What is the output of this program? |
int i, j;
for (i = 8; i > 1; i /= 2) {
for (j = i; j >= 1; j--) {
printf("%d%d\n", i, j);
}
printf("\n");
}
❖ Functions |
Functions have the form
return-type function-name(parameters) {
declarations
statements
return …;
}
return_typevoidparametersvoid
❖ Functions (cont) |
When a function is called:
return
❖ Functions (cont) |
When a return
return expression;
expression
// Euclid's gcd algorithm (recursive version)
int euclid_gcd(int m, int n) {
if (n == 0) {
return m;
} else {
return euclid_gcd(n, m % n);
}
}
The return statement can also be used to terminate a function of return-type void
return;
❖ Basic Data Types |
char | character | 'A''e''#' | ||
int | integer | 217-5 | ||
float | floating-point number | 3.14159 | ||
double | double precision floating-point | 3.14159265358979 |
There are other types, which are variations on these
float x; char ch = 'A'; int j = i;
❖ Aggregate Data Types |
Families of aggregate data types:
char s[50]int v[100]struct student { char name[30]; int zID; }
❖ Arrays |
An array is
int a[20]; // array of 20 integer values/variables char b[10]; // array of 10 character values/variables
❖ Arrays (cont) |
Larger example:
#define MAX 20 int i; // integer value used as index int fact[MAX]; // array of 20 integer values fact[0] = 1; for (i = 1; i < MAX; i++) { fact[i] = i * fact[i-1]; }
❖ Sidetrack: C Style |
We can define a symbolic constant at the top of the file
#define SPEED_OF_LIGHT 299792458.0 #define ERROR_MESSAGE "Out of memory.\n"
Symbolic constants make the code easier to understand and maintain
#define NAME replacement_text
NAMEreplacement_textNAME"…"
❖ Sidetrack: C Style (cont) |
UNSW Computing provides a style guide for C programs:
C Coding Style Guide (http://wiki.cse.unsw.edu.au/info/CoreCourses/StyleGuide)
Not strictly mandatory for COMP9024, but very useful guideline
Style considerations that do matter for your COMP9024 assignments:
❖ Sidetrack: C Style (cont) |
C has a reputation for allowing obscure code, leading to …
The International Obfuscated C Code Contest
www.ioccc.org
❖ Sidetrack: C Style (cont) |
Most artistic code (Eric Marshall, 1986)
extern int
errno
;char
grrr
;main( r,
argv, argc ) int argc ,
r ; char *argv[];{int P( );
#define x int i, j,cc[4];printf(" choo choo\n" ) ;
x ;if (P( ! i ) | cc[ ! j ]
& P(j )>2 ? j : i ){* argv[i++ +!-i]
; for (i= 0;; i++ );
_exit(argv[argc- 2 / cc[1*argc]|-1<4 ] ) ;printf("%d",P(""));}}
P ( a ) char a ; { a ; while( a > " B "
/* - by E ricM arsh all- */); }
❖ Sidetrack: C Style (cont) |
Just plain obscure (Ed Lycklama, 1985)
#define o define
#o ___o write
#o ooo (unsigned)
#o o_o_ 1
#o _o_ char
#o _oo goto
#o _oo_ read
#o o_o for
#o o_ main
#o o__ if
#o oo_ 0
#o _o(_,__,___)(void)___o(_,__,ooo(___))
#o __o (o_o_<<((o_o_<<(o_o_<<o_o_))+(o_o_<<o_o_)))+(o_o_<<(o_o_<<(o_o_<<o_o_)))
o_(){_o_ _=oo_,__,___,____[__o];_oo ______;_____:___=__o-o_o_; _______:
_o(o_o_,____,__=(_-o_o_<___?_-o_o_:___));o_o(;__;_o(o_o_,"\b",o_o_),__--);
_o(o_o_," ",o_o_);o__(--___)_oo _______;_o(o_o_,"\n",o_o_);______:o__(_=_oo_(
oo_,____,__o))_oo _____;}
❖ Strings |
"String" is a special word for an array of characters
'\0'char
If a character array s[11]"hello"
0 1 2 3 4 5 6 7 8 9 10 --------------------------------------------- | h | e | l | l | o | \0| | | | | | ---------------------------------------------
❖ Array Initialisation |
Arrays can be initialised by code, or you can specify an initial set of values in declaration.
Examples:
char s[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
char t[6] = "hello";
int fib[20] = {1, 1};
int vec[] = {5, 4, 3, 2, 1};
In the third case, fib[0] == fib[1] == 1fib[2] .. fib[19]
In the last case, C infers the array length (as if we declared vec[5]
❖ Exercise: What is the output of this program? |
1 #include <stdio.h>
2
3 int main(void) {
4 int arr[3] = {10,10,10};
5 char str[] = "Art";
6 int i;
7
8 for (i = 1; i < 3; i++) {
9 arr[i] = arr[i-1] + arr[i] + 1;
10 str[i] = str[i+1];
11 }
12 printf("Array[2] = %d\n", arr[2]);
13 printf("String = \"%s\"\n", str);
14 return 0;
15 }
❖ Sidetrack: Reading Variable Values with scanf()atoi() |
Formatted input read from standard input (e.g. keyboard)
scanf(format-string, expr1, expr2, …);
Converting string into integer
int value = atoi(string);
Example:
#include <stdio.h> // includes definition of BUFSIZ (usually =512) and scanf() #include <stdlib.h> // includes definition of atoi() ... char str[BUFSIZ]; int n; printf("Enter a string: "); scanf("%s", str); n = atoi(str); printf("You entered: \"%s\". This converts to integer %d.\n", str, n);
Enter a string: 9024 You entered: "9024". This converts to integer 9024.
❖ Arrays and Functions |
When an array is passed as a parameter to a function
int total, vec[20]; … total = sum(vec);
Within the function …
❖ Arrays and Functions (cont) |
Since functions do not know how large an array is:
int total, vec[20]; … total = sum(vec,20);
Also, since the function doesn't know the array size, it can't check whether we've written an invalid subscript (e.g. in the above example 100 or 20).
❖ Exercise: Arrays and Functions |
Implement a function that sums up all elements in an array.
Use the prototype
int sum(int[], int)
int sum(int vec[], int dim) {
int i, total = 0;
for (i = 0; i < dim; i++) {
total += vec[i];
}
return total;
}
❖ Multi-dimensional Arrays |
Examples:
Note: q[0][1]==2.7r[1][3]==8q[1]=={3.1,0.1}
Multi-dimensional arrays can also be initialised (must provide # of columns):
float q[][2] = {
{ 0.5, 2.7 },
{ 3.1, 0.1 }
};
❖ Sidetrack: Defining New Data Types |
C allows us to define new data type (names) via typedef
typedef ExistingDataType NewTypeName;
Examples:
typedef float Temperature; typedef int Matrix[20][20];
❖ Sidetrack: Defining New Data Types (cont) |
Reasons to use typedef
TemperatureDollarsVolts
typedef float Real;
Real complex_calculation(Real a, Real b) {
Real c = log(a+b); … return c;
}
Matrix
❖ Structures |
A structure
struct
typedef struct {
char name[30];
int zID;
} StudentT;
❖ Structures (cont) |
One structure can be nested inside another:
typedef struct {
int day, month;
} DateT;
typedef struct {
int hour, minute;
} TimeT;
typedef struct {
char plate[7]; // e.g. "DSA42X"
double speed;
DateT d;
TimeT t;
} TicketT;
❖ Structures (cont) |
Possible memory layout produced for TicketT
--------------------------------- | D | S | A | 4 | 2 | X | \0| | 7 bytes + 1 padding --------------------------------- | 68.4 | 8 bytes --------------------------------- | 2 | 6 | 8 bytes --------------------------------- | 20 | 45 | 8 bytes ---------------------------------
Note: padding is needed to ensure that
plateDon't normally care about internal layout, since fields are accessed by name.
❖ Structures (cont) |
Defining a structured data type itself does not allocate any memory
We need to declare a variable in order to allocate memory
DateT christmas;
The components of the structure can be accessed using the "dot" operator
christmas.day = 25; christmas.month = 12;
❖ Structures (cont) |
With the above TicketT
#define NUM_TICKETS 1500
typedef struct {…} TicketT;
TicketT tickets[NUM_TICKETS]; // array of structs
// Print all speeding tickets in a readable format
for (i = 0; i < NUM_TICKETS; i++) {
printf("%s %6.2f %d/%d at %d:%d\n", tickets[i].plate,
tickets[i].speed,
tickets[i].d.day,
tickets[i].d.month,
tickets[i].t.hour,
tickets[i].t.minute);
}
// Sample output:
//
// DSA42X 68.40 2/6 at 20:45
❖ Structures (cont) |
A structure can be passed as a parameter to a function:
void print_date(DateT d) {
printf("%d/%d\n", d.day, d.month);
}
int is_winter(DateT d) {
return ( (d.month >= 6) && (d.month <= 8) );
}
❖ Abstract Data Types |
A data type is …
e.g. integer stacks/ e.g. push, pop, isEmpty?
❖ Abstract Data Types (cont) |
Users of the ADT see only the interface
Builders of the ADT provide an implementation
ADT interface provides
❖ Abstract Data Types (cont) |
ADT interfaces are opaque
❖ ADOs and ADTs |
We want to distinguish …
❖ Example: Abstract Stack Data Object |
Stack, aka pushdown stack or LIFO data structure (last in, first out)
Assume (for the time being) stacks of char
Operations:
❖ Example: Abstract Stack Data Object (cont) |
Example of use:
| Stack | Operation | Return value | ||
| ? | create | - | ||
| - | isempty | true | ||
| - | push a | - | ||
| a | push b | - | ||
| a b | push c | - | ||
| a b c | pop | c | ||
| a b | isempty | false |
❖ Stack vs Queue |
Queue, aka FIFO data structure (first in, first out)
Insert and delete are called enqueue and dequeue
Applications:
❖ Exercise: Stack vs Queue |
Consider the previous example but with a queue instead of a stack.
Which element would have been taken out ("dequeued") first?
❖ Stack as ADO |
Interface (a file named Stack.h
// Stack ADO header file #define MAXITEMS 10 void StackInit(); // set up empty stack int StackIsEmpty(); // check whether stack is empty void StackPush(char); // insert char on top of stack char StackPop(); // remove char from top of stack
Note:
❖ Stack as ADO (cont) |
Implementation (in a file named Stack.c
#include "Stack.h" #include <assert.h> // define the Data Structure typedef struct { char item[MAXITEMS]; int top; } stackRep; // define the Data Object static stackRep stackObject; // set up empty stack void StackInit() { stackObject.top = -1; } // check whether stack is empty int StackIsEmpty() { return (stackObject.top < 0); }
|
// insert char on top of stack void StackPush(char ch) { assert(stackObject.top < MAXITEMS-1); stackObject.top++; int i = stackObject.top; stackObject.item[i] = ch; } // remove char from top of stack char StackPop() { assert(stackObject.top > -1); int i = stackObject.top; char ch = stackObject.item[i]; stackObject.top--; return ch; }
|
assert(test)static Type VarVarStack.c
❖ Exercise: Bracket Matching |
Bracket matching … check whether all opening brackets such as '(', '[', '{' have matching closing brackets ')', ']', '}'
Which of the following expressions are balanced?
(a+b) * ca[i]+b[j]*c[k])(a[i]+b[j])*c[k]a(a+b]*cvoid f(char a[], int n) {int i; for(i=0;i<n;i++) { a[i] = (a[i]*a[i])*(i+1); }}a(a+b * c
❖ Exercise: Bracket Matching (cont) |
Bracket matching algorithm, to be implemented as a client for Stack ADO:
bracketMatching(s): | Input stream s of characters | Output true if parentheses in s balanced, false otherwise | | for each ch in s do | | if ch = open bracket then | | push ch onto stack | | else if ch = closing bracket then | | | if stack is empty then | | | return false // opening bracket missing (case 1) | | | else | | | pop top of stack | | | if brackets do not match then | | | return false // wrong closing bracket (case 2) | | | end if | | | end if | | end if | end for | if stack is not empty then return false // some brackets unmatched (case 3) | else return true
❖ Exercise: Bracket Matching (cont) |
Execution trace of client on sample input:
( [ { } ] )
| Next char | Stack | Check | ||
| - | empty | - | ||
| ( | ( | - | ||
| [ | ( [ | - | ||
| { | ( [ { | - | ||
| } | ( [ | { vs } ✓ | ||
| ] | ( | [ vs ] ✓ | ||
| ) | empty | ( vs ) ✓ | ||
| eof | empty | - |
❖ Exercise: Bracket Matching Algorithm |
Trace the algorithm on the input
void f(char a[], int n) {
int i;
for(i=0;i<n;i++) { a[i] = a[i]*a[i])*(i+1); }
}
| Next bracket | Stack | Check | ||
| start | empty | - | ||
| ( | ( | - | ||
| [ | ( [ | - | ||
| ] | ( | ✓ | ||
| ) | empty | ✓ | ||
| { | { | - | ||
| ( | { ( | - | ||
| ) | { | ✓ | ||
| { | { { | - | ||
| [ | { { [ | - | ||
| ] | { { | ✓ | ||
| [ | { { [ | - | ||
| ] | { { | ✓ | ||
| [ | { { [ | - | ||
| ] | { { | ✓ | ||
| ) | { | false |
❖ Exercise: Implement Bracket Matching Algorithm in C |
#include "Stack.h"
<stdio.h>int getchar(void);
intEOFint putchar(int ch);
chEOF
❖ Compilers |
Compilers are programs that
gcc
❖ Compilers (cont) |
Compilation/linking with gcc
gcc -c Stack.c produces Stack.o, from Stack.c and Stack.h gcc -c brackets.c produces brackets.o, from brackets.c and Stack.h gcc -o rbt brackets.o Stack.o links brackets.o, Stack.o and libraries producing executable program called rbt
Note that stdio,assert
gcc
-c-o
❖ Summary |
gcccharintfloatifelsewhilefor
Produced: 19 Feb 2026