fill in lab request form now cosc 208/ence 208 c & c++ ...• contain a list of pointers...
TRANSCRIPT
C/C++
COSC 208/ENCE 208COSC 208/ENCE 208
C & C++ Programming
Richard Lobb, room 211
Email: [email protected]
Web: www.cosc.canterbury.ac.nz/richard.lobb
Slide # 1COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
0. Administrivia
• Fill in Lab Request Form NOW
– Late entries to Phil Holland– Late entries to Phil Holland
• Labs this week:
– M/W: no labs
– Th/F: Lab #1.
Slide # 2COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
1. Course Intro
See Initial Course Handout
• Who am I?
• Goals
• Assessment
• Textbooks
• Timetable
Slide # 3COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Timetable
NB: COSC 208 is no longer a graduating requirement for Computer Science
C/C++
Goals of 208
• To teach you CBoth still widely used.
• To teach you C++
• To improve your programming skills
– More practice
– Learning different languages
– Use of various tools
Both still widely used.
Slide # 5COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Use of various tools
• To expose you to Linux and Visual Studio
C/C++
Goals of 208 (cont’d)
• To give you a lower-level understanding of • To give you a lower-level understanding of
computers and programming
– No virtual machine in the way
– You get to see:
• Compilation to raw machine code
• Layout of code in memory
• Linking and loading
Slide # 6COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Linking and loading
• Dynamic memory management
• Calls to the operating system
C/C++
Assessment
• Lab quizzes (Learn): 10%• Lab quizzes (Learn): 10%
• C programming assignment: 15%
• C++ programming assignment: 15%
• Final exam: 60%Need >= 45% in this to get full pass
Slide # 7COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
Note:
• quizzes are worth marks
• no written test.
C/C++
Textbooks
• For C & Linux (term 1):
– C Programming, A Modern Approach K.N. King (pref. 2nd edition)
• Excellent book
– RUTE (Rute Users Tutorial and Exposition). Paul Sheer
• Good Linux reference
• Available electronically from
www.cosc.canterbury.ac.nz/resources/software/linux/rute/index.html
• For C++/Visual Studio (term 2)
– I’ll give links to web tutorials, reference material
Slide # 8COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Bjarne Stroustrup, “The C++ Programming Language”, 3rd edition, is
recommended for advancing students
– Series of books by Scott Meyers (“Effective C++” etc) also recommended
C/C++
Timetable
• See next slide for draft lecture and lab timetable
• Two lectures and two labs are scheduled per week• Two lectures and two labs are scheduled per week
– But we don’t use them all
– Total of 15 labs
– Total of about 18 lectures
• Unused slots are designated as “tutorial”
• I'll come along to answer questions or give an impromptu lecture as
Slide # 9COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• I'll come along to answer questions or give an impromptu lecture as
required.
• Changes will be announced on Learn
– You are required to login regularly (e.g. daily)
C/C++Tentative timetable
Slide # 10COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Getting help
• On line help
– Under Linux:
• The man program displays manual pages
– man ls displays the manual for the ls command
– man -k blah displays all manual pages containing the keyword blah
– Under Windows
• The Visual Studio on-line help facility is excellent
• Website www.cplusplus.com good for C++ library functions
Slide # 11COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Website www.cplusplus.com good for C++ library functions
• Textbooks (King & Rute for C; Stroustrup for C++)
• Class forum (Learn) – see Initial Course Handout
• Talk to or email tutors or me
C/C++
Doing labs at home• You are strongly advised to attend scheduled labs
– Keeps you in touch with the course
– Learn extra stuff from tutors and me.
• But you can do extra lab work at home:– Term 1 (linux/C)
1. Run linux (e.g. Ubuntu) under Windows via vmware or Sun VirtualBox
– Possibly the best solution, but need > 3GB ram, > 2GHz CPU
2. Install linux on home machine instead of Windows
– Good soln for term 1 but a bit drastic for most?
3. Install linux as well as Windows (dual-boot)
– Good soln but need to partition disk or need 2 disks
Slide # 12COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Good soln but need to partition disk or need 2 disks
4. Install cygwin
– Good solution for most labs but some tools missing (e.g. ddd)
– Term 2 (Visual Studio/C++)
• Install Visual Studio Express 2008 on a Windows machine
– Free from http://www.microsoft.com/Express/
C/C++
Hey You!!
• This is primarily a laboratory course not a lecture course.
– Skill acquisition not book learning
• Learning lecture notes won’t work
• Rote learning is a useless skill anyway
• But lectures are still important!
– Introduce concepts
Slide # 13COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Introduce concepts
– Provide context
– Keep you in touch with the course
C/C++
Introduction to week 1’s lab
• Only one lab in week 1: 01_unix_basics
• Covers how to:• Covers how to:
– Use bash in a terminal window
• Commands: ls, mkdir, rm, cp, mv, echo, alias, man
• File paths
• I/O redirection
• Environment variables
– Use a text editor to edit C files
Slide # 14COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Use a text editor to edit C files
– Compile and run a trivial C program
– Use Learn and do quiz
C/C++
2. Intro to GNU/Linux
• History of Unix• History of Unix
• Structure of a modern Unix
• The terminal+bash interface
• The file system
• A bit of X
Slide # 15COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• A bit of X
• Getting help
C/C++
History of Unix
• 1971. Unix version 1 released within Bell Labs.
See www.levenez.com/unix for real detail!
• 1971. Unix version 1 released within Bell Labs.
– Main developers: Ken Thompson, Dennis Ritchie
– Written in high level language B.
– A time-sharing system
– For use by programmers
CPU running users
Slide # 16COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
CPU running
Unix
Terminals
teletypes (ttys) or VDUs
users
C/C++
History of Unix (cont'd)
• 1972-1976. Versions 1 – 6 in Bell Labs
– Versions 3 onwards written in C, a derivative of B, a – Versions 3 onwards written in C, a derivative of B, a
stripped down BCPL (Basic Combined Prog. Language)
• 1976 – 1991. A plethora of Unices
– BSD, SCO Unix, Irix, HP-UX, AIX, Solaris, ...
• 1985. The GNU Manifesto published
– Richard Stallman's project to develop a freely
Slide # 17COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Richard Stallman's project to develop a freely
distributable Unix. Led to Free Software Foundation
(FSF)
• 1988 MIT release X-windows system (X11 release 2)
C/C++
History of Unix (cont'd)
• 1991. Linux version 0.01
• 1991....
– “And the rest is history ...”
“Hello everybody out there using minix. I'm doing a (free) operating
system (just a hobby, won't be big and professional like gnu) for
386(486) AT clones”. -- Linus Torvalds, posting to comp.os.minix
newsgroup, 1991.
Slide # 18COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
In fairness to Richard Stallman, Linux really
should be called GNU/Linux.
C/C++
Structure of a modern Unix
Kernel (CPU scheduling, memory management, I/O, ...)
Utility programs
(non-GUI).
bash, man, tar, gcc, ...
(~3000)
X-windows
X-windows applications
(xclock, ...., GNOME,
mozilla, ...)
Slide # 19COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
Hardware
Kernel (CPU scheduling, memory management, I/O, ...)(1.5 million lines of C in case of Linux)
C/C++
The terminal+bash interface
• To access the 3000-odd utilities, need to start a virtual • To access the 3000-odd utilities, need to start a virtual
terminal (or virtual console).
• Then interact with a shell
– A shell is a program that reads command lines (text) and
executes them
– We use bash (“Bourne again shell”)
Slide # 20COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
The bash shell
• Brief intro in first lab• Brief intro in first lab
– Learn about:
• Command-line syntax
• Environment variables
• Pattern matching
• I/O redirection
• Aliases
Slide # 21COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Aliases
• Other stuff:
– Teach yourself! [RUTE is good.]
C/C++
Directories
• Contain a list of pointers (references) to files
• Hierarchically structured
• A single file can have multiple directory entries
– See ln command (“link”)
• e.g. ln existingFile newLinkToExistingFile
– Actual file is deleted when no links remain
• cf garbage collection in Java
Slide # 22COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• cf garbage collection in Java
– Also have “symbolic links” -- subtly different!
• Roughly like MS Windows “shortcuts”
– Do man ln to find out more
C/C++
Some Linux Directories
/bin “Core” executables (“binaries”)/bin “Core” executables (“binaries”)
/sbin System startup and maintenance binaries
/usr/bin Other binaries
/proc Processor and process info
/home/cosc/student/{login} home directories
Slide # 23COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
/dev Hardware devices
C/C++
Files
• Consist of 0 or more 8-bit bytes (characters)
• Text and binary same to filesystem• Text and binary same to filesystem
• Referred to by pathname
– e.g. /home/cosc/staff/rjl83/lectures/rhubarb.ppt
• Filename “extensions” (e.g. thing.c) are just an ad hoc convention of application programs
– '.' is just another filename character.
Slide # 24COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– '.' is just another filename character.
• Files in “/dev” directory are “special files”
– Contain “internal name” of device-handling code
C/C++
File Protectioncosc492:208$ ll
total 16
drwx------ 3 rjl83 staff 512 Jan 21 16:02 Experiments/
drwx------ 2 rjl83 staff 512 Feb 15 09:50 InitialCourseHandout/
-rw-r--r-- 1 rjl83 staff 11264 Feb 2 10:19 LabList.xls-rw-r--r-- 1 rjl83 staff 11264 Feb 2 10:19 LabList.xls
drwx------ 5 rjl83 staff 512 Feb 16 11:24 labs/
drwx------ 13 rjl83 staff 512 Feb 17 13:49 lectures/
drwxr-xr-x 2 rjl83 staff 512 Feb 15 09:50 thoughts from 2004/
No. of links
(or no. of
files for a
directory)
Owner
Group Size on disk When last modified
Slide # 25COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
directory)
3-bit rwx (read/write/execute) code for each of owner, group others
• See chmod command
• Execute right is interpreted as search right in case of directories
C/C++
Processes
• A process is a program in execution
• ps and top commands list current processes• ps and top commands list current processes
– Same info also available (to root) in /proc directory
• kill command is used to send signals to processes, e.g.
– SIGINT (#2) to interrupt it
• Bash command: kill -2 processID
• Typing ^C to shell does this to current foreground process
Slide # 26COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Typing ^C to shell does this to current foreground process
– SIGKILL (#9) to kill the process
• Bash command: kill -9 processID
C/C++
A Bit of X
See: RUTE chapter 43 (parts 1 – 3); man X output
• X Architecture
– X server
– Window manager
– Desktop manager
Slide # 27COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
X Architecture (sort of)
Desktop Managerkdesktop, gnome-session, ...
User Applications
GUI ToolkitMotif, GTK+, Qt, etc
Window Managertwm, kwin, metacity, icewm, ...
User Applicationsxemacs, xclock, xfig, nautilus, etc
Slide # 28COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
X (or X-server or xlib)
Low level network-transparent windowing layer.
C/C++
X Server
• A server that manages screen real estate for clients• A server that manages screen real estate for clients
(the application programs doing I/O)
– Confusing: usually users interact with clients that talk to
servers; here user interacts with server.
• Programs connect through network sockets
• Hence “network transparent”
Slide # 29COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Hence “network transparent”
– Client can be anywhere on the Internet
C/C++
Desktop (e.g. GNOME or KDE)• The set of components that manages the screen real estate
Provides:Provides:
– Panel for menus,
quicklaunch icons,
date
– Icons for common
tasks like opening
home directory
– Window manager to
allow user interaction
with windows
Slide # 30COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
with windows
– Panel showing all
current tasks
– Panel for managing
multiple workspaces
C/C++
An introduction to week 2’s lab
• 02_C_basics (first 7 chapters of King!)
– pun.c– pun.c
• cpp and #include
• printf
• main
• make
– celsius.c
• #define
Slide # 31COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• scanf
• scalar datatypes
• assignment, if statements, loops
– Your first programming exercise (solving quadratics)
C/C++
3. An Introduction to C
• Why C?• Why C?
• History of C
• C versus Java
• A quick overview of C
Slide # 32COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Why C?
• Used in other courses (e.g. 221)
• Close relationship to Unix/Linux• Close relationship to Unix/Linux
– All the “classic” Unix system software is written in
C (including kernel)
– Extensive set of tools for support of C programming
• Widely used in industry
– Embedded systems
Slide # 33COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Embedded systems
– Legacy applications development
Note: above motivations are not based on C's qualities as a programming language!
C/C++
History of C
• BCPL → B (Ken Thompson, 1970) → C (Dennis Ritchie, 1973)
• Developed specifically for implementing Unix
– Easier and more portable than assembler
• Book by Kernighan and Ritchie (1978) defined “Classic C” (K&R C)
– But “loose” spec
• ANSI standardisation 1989 (C89)
– And a newer standard, 1999 (C99)
We do this (mostly)
Slide # 34COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– And a newer standard, 1999 (C99)
• C++ 1980's onwards (Bjarne Stroustrup)
– Classes, overloaded operators, templates, exceptions, library classes, ...
C/C++
Strengths and weaknesses of C
• Strengths • Weaknesses
See King, section 1.2
• Strengths
– Efficiency
– Portability
– Power (?)
– Flexibility
– Standard library (?)
– Integration with Unix
• Weaknesses
– Error-prone
– Hard to understand
– Hard to maintain
Slide # 35COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Integration with Unix
int v,i,j,k,l,s,a[99];main(){for(scanf("%d",&s);*a-s;v=a[j*=v]-a[i],k=i<
s,j+=(v=j<s&&(!k&&!!printf(2+"\n\n%c"-(!l<<!j)," #Q"[l^v?(l^j)&1:2])&&++
l||a[i]<s&&v&&v-i+j&&v+i-j))&&!(l%=s),v||(i==j?a[i+=k]=0:++a[i])>=s*k&&
++a[--i]);printf("\n\n");}
Obfuscated C contest winner: input n and it prints all solutions to n-queens problem (see King):
C/C++
C versus Java
• C is a procedural language (like Pascal, FORTRAN etc)
– All statements occur within procedures/functions– All statements occur within procedures/functions
– No classes/objects/methods
– Data is either global (accessible from everywhere) or inside one file or
inside one function
• Like writing a single nameless Java class with all methods
being static
– The class fields (also static) are all the global variables
Slide # 36COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– The class fields (also static) are all the global variables
• C compiles to run on CPU, not on a virtual machine.
C/C++
C versus Java (cont'd)
• Don't have reference variables
– Instead have to use explicit pointer variables– Instead have to use explicit pointer variables
– Parameters are always passed by value
• Few safety nets.
– Variables aren't initialized
– Array bounds not checked
– Pointer references not checked
Slide # 37COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Easy to crash
• Do-it-yourself dynamic memory allocation/deallocation
– No “garbage collector”
– Errors lead to “memory leaks” or heap corruption and crash
C/C++
A quick overview of C
• pun.c
• Standard layout of a C Program
• Data types
• Data definitions
• Operators
• Statements
Slide # 38COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Statements
• Formatted I/O
C/C++
pun.c (extended version)
#include <stdio.h>
#define RETURN_VALUE 0
char *negation = "not";
int main(void)
{
char *language = "C";
printf("To %s or %s to %s?\n", language, negation, language);
return RETURN_VALUE;
}
Slide # 39COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
$ make pun
gcc -g -ansi -Wall -o pun pun.c
$ pun
To C or not to C?
terminal I/O to ‘make’ and run pun
C/C++
Standard layout of a C Program
1. #include header files1. #include header files
2. #define constants
3. Declare global variables
4. Declare and define all the functions, each being:
– Signature declaration (function name and parameters)
– Body:
Slide # 40COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Body:
• Local variables
• Function code
C/C++
The C preprocessor (cpp)• cpp is a “macro preprocessor”
• Before compilation begins, cpp transforms your source program
• Lines beginning with ‘#’ are cpp commands
– #include <blah.h> inserts the file /usr/include/blah.h
cpp gcc ld
source file Linux C compilerC preprocessor link editorexecutable code
Slide # 41COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– #include <blah.h> inserts the file /usr/include/blah.h
– #include “blah.h” inserts the file ./blah.h
– #define BLAH thing replaces all BLAHs with string thing
• cpp just does simple text transformations
– no syntax or semantics checks
C/C++
Basic data types
• Integers: [unsigned | signed] [long | short] int
– Platform dependent!!
• In our labs (64-bit linux) short is 16 bits; int is 32 bits; long is 64 bits.
• Characters: char
– Always 8 bit ASCII
– Treated as 8-bit ints (tho' may be signed or unsigned dep. on compiler!)
– char constants like Java, e.g. 'x', '='
• Backslash codes for special ASCII chars e.g. '\n' is newline character
Slide # 42COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Backslash codes for special ASCII chars e.g. '\n' is newline character
• Floating point types (float and double)
• C does not have boolean or byte
– Use int (0 => false, anything else => true) and char respectively
C/C++
Data definitions
• Variables declared as in Java:
int distance = 0, area = 5;
– As in Java can include an initialiser to set initial value
– We will require that you always initialise variables in 208!!
• C doesn't check for uninitialized variables
• Causes lots of problems in assignments!
• Constants declared with #define or const
const int daysInWeek = 7; /* Initialiser reqd */
Slide # 43COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
const int daysInWeek = 7; /* Initialiser reqd */
#define HOURS_IN_DAY 24 /* Done by preprocessor */
• Can use typedef to create type aliastypedef int Height; /* Style: use capital letter at start or _t suffix */
Height treeHeight;
C/C++
Data definitions (cont'd)
• In C89 all declarations must come before all statements in a block
– Can't do:– Can't do:
int i; /* Declaration */
i = 10; /* Statement */
int j = 3; /* Another declaration */
• Can't declare new variable within for
for (int i = 0; i < 10; i++) { ... /* Illegal in C89 */
• ‘*’ is used to define a pointer variable (one that contains the memory
address of some data rather than the data itself).
Slide # 44COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
address of some data rather than the data itself).
– '&' operator means “the address of” the operand rather than its value
– This is tricky – we'll cover it in much more detail later
C/C++
C99 versus C89
• C99 has many extras familiar to you from Java, e.g.
– ‘//’ comments
– mixed statements and declarations In C++ too– mixed statements and declarations
– for loops that declare their own loop variable
– runtime-computable array sizes
• C89 requires sizes to be known at compile time
• But:
– It’s not “ANSI” C.
– Many/most compilers support only a subset of C99
• So you lose portability
In C++ too
Slide # 45COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• So you lose portability
– Microsoft Visual Studio supports only C89 or C++.
– Textbook describes both C89 and C99
• So: I teach C89 but you may use C99 constructs if you wish
– Because it's too much hassle to stop you!
C/C++
Operators
• 44 operators, 16 levels of precedence
– See King, Appendix B
• Usual arithmetic/logic (+ - * / && || ^ < > >> << )
• Manipulate structures (. and ->)
• Manipulate pointers (*, &, arithmetic)
• sizeof to find size of a structure
• No string type – C uses arrays of characters, terminated by 0
• Boolean operators (e.g. &&) take int operands
– 0 is false, anything else is true, e.g.
Slide # 46COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– 0 is false, anything else is true, e.g.
int i = 3 + 2;if (i) {
printf("i is nonzero\n"); /* This will get executed */}
C/C++
Statements
• Very similar to Java
– Assignment, if/else, switch, case, for, while, – Assignment, if/else, switch, case, for, while,
do, break, continue
• Actually, in C, an expression is a valid statement, and the assignment
operator is just another binary operator.
• So can write, say,
int c = 0;
while ((c = getchar()) != EOF) { ...
Slide # 47COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
while ((c = getchar()) != EOF) { ...
• C doesn't have exceptions
An expression that reads a character
from stdin and assigns it to the
character c
C/C++
Formatted I/O• printf(string, expr1, expr2, ...)
• Format string contains ordinary characters plus conversion specifications
– %[number][l]letter e.g. %4d , %5.2f, %.3lf– %[number][l]letter e.g. %4d , %5.2f, %.3lf
– d, f, c, s for int, float, char, string (= char array)
– l is for long e.g. long int or double
• A conversion spec causes the next expression parameter to be appropriately formatted in its place
– e.g., see pun.c
• scanf reads values from stdin into variables similarly
Slide # 48COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• scanf reads values from stdin into variables similarly
– scanf("%d %f\n", &intVar, &floatVar);
– Note the '&' preceding the variables!
– scanf is potentially very confusing – I suggest you use it only for input of
numeric data, not chars and strings.
C/C++
4. Arrays and functions
• Arrays: backwards.c• Arrays: backwards.c
• Functions: average.c
• Exchanging data via globals: twiddle.c
– DON’T!!! (well, rarely, anway)
• Arrays as parameters: twiddle2.c
Slide # 49COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Arrays as parameters: twiddle2.c
C/C++backwards.c
#include <stdio.h>#include <stdlib.h> /* Defines EXIT_SUCCESS */#define N_MAX 100int main() {
char line[N_MAX] = {'\0'}; /* An array of char. */char line[N_MAX] = {'\0'}; /* An array of char. */int c = 0; /* A character, cast to an int */int n = 0, i = 0; /* More locals */printf("Variable n requires %d bytes of memory\n", sizeof(n)); /* Demo of sizeof */printf("Array line occupies %d bytes of memory\n", sizeof(line));printf("Enter a line of text, terminated by 'Enter'\n");c = getchar(); /* Get char (cast to int) or EOF */while (c != EOF && c != '\n' && n < N_MAX) { /* Read a line */
line[n++] = c;c = getchar();
}
Slide # 50COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
}for (i = n - 1; i >= 0; i--) { /* Print it out backwards */
putchar(line[i]);}putchar('\n');return EXIT_SUCCESS; /* Return value from main is 0 for success */
}
C/C++
Notes on backwards.c
Array declaration roughly like
Java’s BUT
Possible Stack
Frame for main
Java’s BUT
– The array line is in a block of
memory on the stack, NOT on the
heap
• No new required to allocate space
• We don’t use the heap until lab. 7!
– Size must be known at compile time
saved stuff
(return address, registers)
parameters
line
array
.
.
Slide # 51COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Size must be known at compile time
(C89, pedantic mode)
– Get zero fill after initialiser runs out
• But if no initialiser get no initialisation!
.
.
c
n
i
C/C++
Notes on backwards (cont’d)
• Syntax to index array same as in Java but ...
– No runtime subscript checking– No runtime subscript checking
• If you run off the end of the array anything may happen!
– e.g., with stack frame picture on prev. slide, you’ll read/write the local
variables c, n and i.
– But stack frame layout not predictable. Varies with compiler version
and even from run to run (memory-layout randomisation)!
• getchar() get char from stdin. RETURNS AN INT!!
Slide # 52COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• getchar() get char from stdin. RETURNS AN INT!!
– Because EOF is an int value (-1) not a char from the file!
• putchar(c) outputs a char to stdout
C/C++
average.c
#include <stdio.h>#include <stdlib.h> /* EXIT_SUCCESS is defined in here */#include <stdlib.h> /* EXIT_SUCCESS is defined in here */
float average(float a, float b) { /* Declare and define this before using it */return (a + b) / 2;
}
int main() {float x = 0.0, y = 0.0, z = 0.0;printf("Enter three numbers: ");scanf("%f%f%f", &x, &y, &z);printf("Average of %g and %g: %g\n", x, y, average(x,y));
Slide # 53COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
printf("Average of %g and %g: %g\n", x, y, average(x,y));printf("Average of %g and %g: %g\n", y, z, average(y,z));printf("Average of %g and %g: %g\n", x, z, average(x,z));return EXIT_SUCCESS;
}
C/C++
OR (average2.c)
#include <stdio.h>#include <stdlib.h> /* EXIT_SUCCESS is defined in here */
float average(float a, float b); /* DECLARATION */
int main() {float x = 0.0, y = 0.0, z = 0.0;printf("Enter three numbers: ");scanf("%f%f%f", &x, &y, &z);printf("Average of %g and %g: %g\n", x, y, average(x,y));printf("Average of %g and %g: %g\n", y, z, average(y,z));printf("Average of %g and %g: %g\n", x, z, average(x,z));
Slide # 54COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
printf("Average of %g and %g: %g\n", x, z, average(x,z));return EXIT_SUCCESS;
}
float average(float a, float b) { /* DEFINITION */return (a + b) / 2;
}
C/C++
Notes on functions
• Functions are like static methods
• They’re the only way to break your code into pieces!• They’re the only way to break your code into pieces!
– But you can (and should) put related functions into separate
files and compile them separately (see later)
• Can’t nest functions
• Declare functions before using them
– DON’T run with the compiler’s guesses at types!
Slide # 55COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– DON’T run with the compiler’s guesses at types!
– DO enable all warnings in the compiler [gcc –Wall ...]
• In C, a warning is usually an error in your program!
– At very least it’s a style error.
C/C++
(Mis)use of globals: twiddle.c
#include <stdio.h>#include <stdlib.h>#include <ctype.h> /* Various character-handling functions defined here */
#define MAX_NAME_LENGTH 80char name[MAX_NAME_LENGTH]; /* declares a global (aka “external”) variable */
/* Read a name (or any string) into the "name" array. Terminate it with null. */
void readName() {char c = '\0';int i = 0;printf("Enter your name: ");
Slide # 56COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
c = getchar();while (c != '\n' && i < MAX_NAME_LENGTH - 1) {
name[i++] = c;c = getchar();
}name[i++] = '\0'; /* terminator */
}
C/C++
twiddle.c (cont’d)
/* Convert the global "name" string to upper case */void convertNameToUpper() {
int i = 0;int i = 0;while (name[i] != '\0') {name[i] = toupper(name[i]);i++;
}}
int main() {readName();
Slide # 57COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
readName();convertNameToUpper();printf("Your name in upper case: %s\n", name);return EXIT_SUCCESS;
}
C/C++
Notes on twiddle
• Global variables are visible to all functions
– Lazy! Don’t use them!– Lazy! Don’t use them!
• Strings are char arrays, in which a null character ('\0')
denotes end of string.
– Can be output with '%s' format specifier
• readName loop can also be written:
Slide # 58COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
while ((c = getchar()) != '\n' && i < MAX_NAME_LENGTH - 1) {name[i++] = c;
}
C/C++
Down with globals! (twiddle2.c)/* Read a name (or any string) into the parameter array. Terminate with null. */void readName(int maxLen, char name [ ]) {
char c = '\0';int i = 0;int i = 0;printf("Enter your name: ");c = getchar();while (c != '\n' && i < maxLen - 1) {
name[i++] = c;c = getchar();
}name[i++] = '\0'; /* terminator */
}
function convertStringToUpper
T.B.S.
Slide # 59COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
int main() {char name[MAX_NAME_LENGTH];readName(MAX_NAME_LENGTH, name);convertStringToUpper(name);printf("Your name in upper case: %s\n", name);return EXIT_SUCCESS;
}
C/C++
Notes on twiddle2.c
• Arrays are just chunks of memory – when you pass
an array as a parameter you pass a pointer to that an array as a parameter you pass a pointer to that
memory (as in Java)
– Pointers are covered in the next section
– The whole array is not copied
– The parameter type doesn’t include the array dimension
• No way to determine the length of an array so ...
Slide # 60COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• No way to determine the length of an array so ...
– Must either pass its length as a parameter too, or
– Mark the end of the data somehow
• e.g. the string-terminating null byte.
C/C++
Memory layout
(linux)
• In twiddle2:
Linux Kernel(1 GB)
0xc0000000
0xbfffffffStack
0xffffffff
• In twiddle2:
• In twiddle:Initialised data
Uninitialised data(zeroed at start)
Heap
Stack(randomised base addr)
Unused
stack frame for
convertNameToUpper
stack frame
for main
name (parameter)
name array
(in stack frame)
Slide # 61COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• In twiddle:
0x08000000
0x00000000 Unused
Program code("text" segment)
Initialised data(strings etc + init'ed globals)
Fig. from pointers lab
stack frame
for main
stack frame for
convertNameToUpper
name array is a
global.
Stack frames
contain neither the
array nor a pointer
to it
C/C++
Preview of lab #3: arrays_and_functions
• Looks at backwards.c
• You get to write a whole useful C program:• You get to write a whole useful C program:
– Prints letter frequencies in an input file
• Looks at twiddle.c
• You write convertStringToUpper
Slide # 62COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
5. Pointers
“The C language ... then taught two entire “The C language ... then taught two entire
generations of programmers to ignore
buffer overflows, and nearly every other
exceptional condition, as well.”
-- Henry Baker
Slide # 63COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
-- Henry Baker
in “Buffer Overflow Security Problems”.
C/C++
Crash alert!!
• In C, all of memory is just one huge array
• There are no run-time checks• There are no run-time checks
– Except the memory protection provided by the OS
• Stops you accessing device registers, other people's programs, etc
• Programming errors with pointers/arrays usually
results in a crash!
– “Segmentation fault, core dumped” [Linux]
Slide # 64COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– “Segmentation fault, core dumped” [Linux]
– “This program has encountered a problem and needs to
close” [Windows]
– Sometimes a corrupted memory location causes a problem
much later in the execution
C/C++
• A pointer stores the address of another variable (or function)
Pointers
int i = 10;
int j = 20;
int *p = NULL;
p = &i;
*p = j; /* i = j */
10
20
i
j
To memory location 0 (illegal reference)
Slide # 65COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
0p
At this stage, any reference to *pwill generate a segmentation fault.
C/C++
• A pointer stores the address of another variable (or function)
Pointers
int i = 10;
int j = 20;
int *p = NULL;
p = &i;
*p = j; /* i = j */
10
20
i
j
Slide # 66COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
p
C/C++
• A pointer stores the address of another variable (or function)
Pointers
int i = 10;
int j = 20;
int *p = NULL;
p = &i;
*p = j; /* i = j */
20
20
i
j
Slide # 67COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
p
C/C++
Uses of pointers
1. As references to other variables (or functions)
(a) Reference parameters (a) Reference parameters
– e.g. scanf; swap (next slide); getTwoRandoms
(b) References to dynamically-allocated data structures
– See later
2. For fast and compact array/string manipulation.
Except:
Slide # 68COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
Except:
– it’s probably not faster
– “compact” => “unreadable”!
• Discouraged!
C/C++
Pointers as reference variables
void swap(int *p1, int *p2) {
// Swap the values pointed to by p1 and p2
/* UDOO! *//* UDOO! */
}
int data1[ ] = { ..... /* numbers */ ... }
int data2[ ] = { .... /* more numbers */ .... }
int longer = sizeof(data1) / sizeof(int); /* length of data1 */
int shorter= sizeof(data2) / sizeof(int); /* length of data2 */
Slide # 69COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
if (longer < shorter) swap(&longer, &shorter);
/* Now variable longer is the length of the longer of the two arrays,
and variable shorter is the length of the shorter. */
C/C++
Pointers and arrays
• An array name is almost exactly the same as a
pointer to the zeroth element, except it's constpointer to the zeroth element, except it's const
int x, a[5], b[5];
int *pa = NULL, *pb = NULL;
pa = a; /* Same as pa = &a[0] */
x = *pa; /* Same as x = a[0], x = *a or x = pa[0]! */
x = *(pa+2); /* Same as x = a[2], x = *(a+2), x = pa[2] */
a++; /* Illegal – a is const */
pa++; /* OK – steps to next element in array */
b = a; /* Illegal. b is const. Use memcpy. */
Slide # 70COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
b = a; /* Illegal. b is const. Use memcpy. */
pb = pa; /* OK */
for (pa = a; pa < &a[5]; pa++) { /* OK, but why not ... */
*pa = 0; /* ... use subscripts? */}
C/C++
C doesn’t really have arrays
• It only has subscripting
int b[10];
b[3] = 17; /* Just a shorthand for ... */
*(b + 3) = 17; /* ... this! */
3[b] = 17; /* So this is legal too!!! */
• Remember: no way of knowing how large an array is, so no
way of checking for subscript or pointer out-of-range.
Slide # 71COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
way of checking for subscript or pointer out-of-range.
– But obviously program that declares array knows its size
– sizeof b is 10, c.f. sizeof(char*) which is 8 (on 64-bit machine).
C/C++
Array parameters
• Array name a passed as actual parameter is equivalent to
passing &a[0]
• In formal parameter declarations, and • In formal parameter declarations, char p[] and char *p
are equivalent. [This could be int *data]
int max(int n, int data[ ] ) {int max = data[0];int i = 1;for (; i < n; i++) {
if (data[i] > max) {max = data[i];
int max(int n, int *pData) {int *endOfData = pData + n;int max = *pData++;for (;pData < endOfData; pData++) {
if (*pData > max) {max = *pData ;
=
Slide # 72COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
max = data[i];}
}return max;
}
max = *pData ;}
}return max;
}
int nums[ ] = {1, 4, 11, -19, 21, 99, 44};printf(“Maximum value of nums = %d\n”, max(7, nums));
C/C++
Style: use of const
• When passing arrays as parameters, use const in signature if
function doesn't modify array.function doesn't modify array.
– You can't write to something that a const pointer points at
• You can still modify the pointer though!
• Stops inadvertent modifying
of array
• Makes it clear to user that
array is for input only
int max(int n, const int *pData) {const int *endOfData = pData + n;int max = *pData++;for (;pData < endOfData; pData++) {
if (*pData > max) {
Slide # 73COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
array is for input only
• Prevents wrong calls when
have one input array and one
output array
if (*pData > max) {max = *pData ;
}}return max;
}
C/C++
Preview of lab #4: pointers
• Just some simple exercises with pointers:
– Write swap– Write swap
– Write findTwoLargest
– Modify functions that print an array in various different
ways.
• If you finish before the end of the lab, get started on
lab #5
Slide # 74COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
lab #5
– Labs 4 & 5 are closely related
C/C++
6. Strings
• No built-in String type in C
• A string is (usually) implemented using a null-terminated
('\0') array of char('\0') array of char
• NB: null pointer (4 or 8 bytes) ≠ null character (1 byte)
#include <string.h>
char alphabet6[]= ″abcdef″;
char *p = ″blarg″, *q = alphabet6;
strncpy(q, p, 6); /* NOT q = p! [What would that do?]*/
Slide # 75COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
strncpy(q, p, 6); /* NOT q = p! [What would that do?]*/
strncpy(q, ″longerString″, 6);
/* Won't fit! Hence q will not be null terminated! */
char str[] = {'h', 'i', '!', '\0'};
printf(″str: %s\n″, str);
C/C++
strings (cont'd)
• String are just arrays, so are modifiable (unlike Java
strings)strings)
– Be extremely careful not to run off end of array
• “buffer overrun”
– Use the “strn...” functions, not the older “str...” versions
• Or – better – use C++ !!
• Use man 3 string, man 3 strncpy etc for documentation
Slide # 76COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
of library functions
– And/or read King, Appendix D
C/C++
Library functions <string.h>
char *strcat(char *dest, const char *src);
char *strchr(const char *s, int c); Don’t use the
int strcmp(const char *s1, const char *s2);
int strcoll(const char *s1, const char *s2);
char *strcpy(char *dest, const char *src);
size_t strcspn(const char *s, const char *reject);
char *strdup(const char *s);
char *strfry(char *string);
size_t strlen(const char *s);
Don’t use the
crossed-out ones!
(see next slide)
This one would be really useful
(once we've done dynamic memory)
but isn't ANSI �
Slide # 77COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
char *strncat(char *dest, const char *src, size_t n);
int strncmp(const char *s1, const char *s2, size_t n);
char *strncpy(char *dest, const char *src, size_t n);
Note how use of const prevents mix-up of src and dest
C/C++
Library functions <string.h> (cont’d)
char *strpbrk(const char *s, const char *accept);
char *strrchr(const char *s, int c);char *strrchr(const char *s, int c);
char *strsep(char **stringp, const char *delim);
size_t strspn(const char *s, const char *accept);
char *strstr(const char *haystack, const char *needle);
char *strtok(char *s, const char *delim);
size_t strxfrm(char *dest, const char *src, size_t n);
Slide # 78COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Why not use strcpy, strcat etc?
• Consider:
char buff[6]; Crashes the computer!char buff[6];
strcpy(buff, "Hello world!");
• No length check so entire 12-bytes-plus-null string gets
copied into 6-char array.
– That'll work. Yeah, right.
• strncpy(buff, "Hello world", 6) doesn't overflow buffer
– But nor does it terminate the string. AARGGHHHH!!
Crashes the computer!
Or, worse, corrupts other variables on the stack.
Slide # 79COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– But nor does it terminate the string. AARGGHHHH!!
– Still, it's MUCH safer.
• BUT: strncpy(buff, s, strlen(s)) is worse than useless
– Doesn't check buffer size AND doesn't terminate the string!!!
C/C++
Note on strlen
• It’s important to remember that library functions are just
ordinary pre-compiled C functions, e.g., strlen might be:ordinary pre-compiled C functions, e.g., strlen might be:
int strlen(const char* s) {
int len = 0;
for (; s[len] != ‘\0’; len++) {}
return len;
}
– Note that this traverses the entire string, just to find its length!
• Valuable exercise:
or
int strlen(const char* s) {
char *p = s;
for (; *p != ‘\0’; p++) {}
return p – s;
}
Slide # 80COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Valuable exercise:
– Write your own versions of the following library functions:
• strchr, strncat, strncmp, strstr
C/C++
Arrays of strings
• Actually arrays of pointers to charchar *weekdays[] = {″Monday″, ″Tuesday″, ″Wednesday″,
″Thursday″, ″Friday″};
char *weekdays[] is equivalent to char **weekdays
Monday'\0' Tuesday'\0'
Slide # 81COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
Wednesday'\0'
Thursday'\0'
Friday'\0'
weekdaysweekdays
C/C++
Command-line arguments
bash command: silly -l this that
where silly is:where silly is:int main(int argc, char *argv[]) {...}
At run time:
silly'\0' -l'\0'
4argc
params
on stack
stuff on heap
Slide # 82COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
this'\0'
that'\0'
argv 0
C/C++
Example: program args.c
#include <stdio.h>
#include <stdlib.h>
/* Print out all the command line arguments */
int main(int argc, char *argv[])
{
int i;
printf("The command line arguments are:\n");
Slide # 83COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
for (i = 0; i < argc; i++) {
printf("%d: %s\n", i, argv[i]);
}
return EXIT_SUCCESS;
}
C/C++
Program mygrep.c#include <stdio.h>#include <stdlib.h>#include <string.h>/*/** mygrep is a simple version of grep. It prints lines from standard input that contain a* specified search string. If the -e option is specified, then the line must exactly match* the search string, rather than simply containing it. If the -n option is specified, the line* number of the matching line is printed rather than the line itself.*/
#define LINE_BUFF_SIZE 256#define USAGE "Usage: %s [-e] [-n] searchString\n"
Slide # 84COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
void mygrep(const char *searchString, int exact, int lineNumber); /* Forward refce */
/** Function: main* Checks the command line for the -e and -n options, and gets the search string from* the command line. Calls the mygrep function to do the real work.*/
C/C++Program mygrep.c (cont’d)
int main(int argc, char *argv[]){
int lineNumberDisplay = 0; /* True if displaying line numbers */int exactMatch = 0; /* True if doing exact match on each line */char *searchString = NULL; /* The string to search for */int error = 0;int error = 0;int i = 0; /* Every home should have one */
if (argc < 2) {error++;
}for (i = 1; i < argc - 1; i++) { /* Process option arguments */
if (strcmp(argv[i], "-e") == 0) {exactMatch = 1;
}else if (strcmp(argv[i], "-n") == 0) {
Slide # 85COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
else if (strcmp(argv[i], "-n") == 0) {lineNumberDisplay = 1;
}else {
printf("Unrecognised argument '%s'\n", argv[i]);error++;
}}
C/C++Program mygrep.c (cont’d)
if (error) {printf(USAGE, argv[0]);
}else {else {
searchString = argv[argc-1];mygrep(searchString, exactMatch, lineNumberDisplay);
}return error ? EXIT_FAILURE : EXIT_SUCCESS;
}
/** Function: mygrep* Parameters: searchString - string to look for* exact - whether exact matches with a whole line are required.
Slide # 86COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
* exact - whether exact matches with a whole line are required.* lineNumberDisplay - true to display line numbers rather than* matching lines themselves.** Read the standard input line by line. If a line contains the search* string then print it out (or its line number).*/
C/C++Program mygrep.c (cont’d)
void mygrep(const char *searchString, int exact, int lineNumberDisplay) {int matched = 0;size_t lastCharPos = 0;char line[LINE_BUFF_SIZE] = {'\0'};int lineNum = 0;int lineNum = 0;while (fgets(line, LINE_BUFF_SIZE, stdin) != 0) {
lastCharPos = strlen(line) - 1;if (line[lastCharPos] == '\n') { /* Strip newline off end */
line[lastCharPos] = '\0';lineNum++;
}if (exact) { matched = strcmp(line, searchString) == 0; } /* bad layout to fit slide! */else { matched = strstr(line, searchString) != 0; }if (matched) {
if (lineNumberDisplay) {
Slide # 87COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
if (lineNumberDisplay) {printf("%d\n", lineNum);
}else {
printf("%s\n", line);}
}}
}
C/C++
Preview of Lab #5: strings
• Use library functions in <string.h>
• Appreciation of implications of null-terminated • Appreciation of implications of null-terminated
strings
– no explicit length and it’s O(n) to compute it
• Arrays of strings and command line arguments
– You write some code to process arguments
• Look through and play with mygrep.c
Slide # 88COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Look through and play with mygrep.c
C/C++
7. Structuring data
• C doesn’t have classes but does allow you to group • C doesn’t have classes but does allow you to group
data items together
• Has a “data record” called a struct
• Think of it as an object without methods
Slide # 89COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
structExample1.c
struct student {
char *name;
int age;int age;
struct student *next; /* Pointer to next student in a list */
} aStudent; /* ‘aStudent’ is a global variable of type ‘struct student’ */
/* 'struct student' is now a type */
struct student anotherStudent; /* Another global variable of that type */
void printStudents(struct student *studPtr) {
/* Print all students in a list of students */
Slide # 90COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
/* Print all students in a list of students */
while (studPtr != NULL) {
printf("%s (%d)\n", studPtr->name, studPtr->age);
studPtr = studPtr->next;
};
}
C/C++
structExample1.c (cont’d)
/* main just defines the two students’ fields,
* links them together into a list, and prints the list. */aStudent
int main(void)
{
aStudent.name = "Agnes McGurkinshaw";
aStudent.age = 97;
aStudent.next = &anotherStudent;
anotherStudent.name = "Jingwu Xiao";
anotherStudent.age = 21;
anotherStudent.next = NULL;
anotherStudent
97
21
Slide # 91COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
anotherStudent.next = NULL;
printStudents(&aStudent);
return 0;
}
Agnes McGurkinshaw\0
Jingwu Xiao\0
0 (NULL)
C/C++
Points to note
• Weird syntax:
– struct <tag> { <field> ... } <identifier> ...– struct <tag> { <field> ... } <identifier> ...
• Like arrays, struct variables are not references
– They’re allocated memory when they’re declared/defined
• Either globally or within the stack frame
a type variables of that type
Slide # 92COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Either globally or within the stack frame
– They’re not in the heap
• Unless you malloc space for them – see later
C/C++
Points to note (cont’d)
• Dot notation selects fields of struct, e.g., aStruct.field
• aStructPtr->field is short for (*aStructPtr).field• aStructPtr->field is short for (*aStructPtr).field
Slide # 93COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
structExample2.c
Uses typedefs and initialisers to make the code more readable. Variables now local to main.
typedef struct student Student;
struct student {
char *name;
int age;
Student *next;
};
int main(void){
/* Declare and initialise the students * and the list of students */Student aStudent =
{"Agnes McGurkinshaw", 97, NULL};Student anotherStudent =
{"Jingwu Xiao", 21, NULL};Student *studentList = NULL;
Slide # 94COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
void printStudents(Student *studPtr) {
/* ... as before ... */
}
Student *studentList = NULL;aStudent.next = &anotherStudent;studentList = &aStudent;printStudents(studentList);return 0;
}
C/C++
structExample3.c
typedef struct student Student;struct student {
char name[MAX_NAME_SIZE]; /* NB – whole array name now part of struct */int age;
Reads an arbitrary no. of students from a file.
Allocates student structs from a pool
int age;Student *next;
};
Student studentPool[MAX_NUM_STUDENTS]; /* Pool of Student structs */int firstFree = 0;
Student *newStudent(const char *name, int age){Student *student = NULL;if (firstFree < MAX_NUM_STUDENTS) {
student = &studentPool[firstFree++];
Slide # 95COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
student = &studentPool[firstFree++];strncpy(student->name, name, MAX_NAME_SIZE);student->name[MAX_NAME_SIZE-1] = '\0'; /* Make sure it's terminated */student->age = age;student->next = NULL;
}return student;
}
C/C++
structExample3.c (cont’d)
Student *readOneStudent(FILE * fp) { /* Read a student from file fp */char buffer[MAX_LINE_LENGTH];Student *sp = NULL;
char *cp = fgets(buffer, MAX_LINE_LENGTH, fp);if (cp != NULL) { /* Proceed only if we read something */
int nameLength = strcspn(buffer, "0123456789");int age = atoi(&buffer[nameLength]);while (nameLength > 0 && buffer[nameLength - 1] == ' ') {
buffer[--nameLength] = '\0';}if (nameLength > 0 && age > 0) {
sp = newStudent(buffer, age);
Slide # 96COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
sp = newStudent(buffer, age);}
}return sp;
}
C/C++
structExample3.c (cont’d)Student *readStudents(FILE* fp) {
Student *first = NULL; /* Pointer to the first student in the list */Student *last = NULL; /* Pointer to the last student in the list */Student *sp = readOneStudent(fp);Student *sp = readOneStudent(fp);first = last = sp;while (sp != NULL) {
sp = readOneStudent(fp);last->next = sp;last = sp;
};return first;
}
void printStudents(const Student *studPtr){
Slide # 97COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
void printStudents(const Student *studPtr){while (studPtr != NULL) {
printf("%s (%d)\n", studPtr->name, studPtr->age);studPtr = studPtr->next;
}}
C/C++
structExample3.c (cont’d)
int main(void) {Student *studentList = readStudents(stdin);/* Presumably do various other clever things with our list of students here *//* Presumably do various other clever things with our list of students here */printStudents(studentList);return EXIT_SUCCESS;
}
UDOO: change it so list is
kept in alphabetical order
Slide # 98COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
kept in alphabetical order
C/C++
8. Structuring Code
• Separate compilation
• Header files• Header files
• Examples
Slide # 99COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Separate compilation
• So far, when using gcc/make we have translated a
source program to an executable code file.source program to an executable code file.
• Actually, this has involved 4 separate programs:
– cpp to pre-process the source file
– gcc to translate C to assembly language
– as to translate assembly language to a relocatable
binary object code file
Slide # 100COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
binary object code file
– ld to link your code with the library code and build an
executable code file
C/C++
Separate compilation (cont’d)
• If we pass a –c flag to gcc it stops after the third
stepstep
• Output is a relocatable object module
– Binary code plus:
• a table of all locations that need to be changed when the code is
moved in memory during linking
• a table of all locations that reference externally defined symbols
Slide # 101COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• a table of all locations that reference externally defined symbols
(e.g. calls to printf)
• a table of all locations that define externally-referencable
symbols (e.g. callable functions)
C/C++
Example
• Suppose we have a source code file silly.c:
int myTerriblyUsefulFunction(int arg) {
return arg;
}
• Then could compile with:gcc –c $CFLAGS silly.c –o silly.o
• Now have an object file called silly.o which contains
Slide # 102COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Now have an object file called silly.o which contains
a function that can be used by other programs.
C/C++
Using that object file
• Can use silly.o from program prog.c as follows:
int myTerriblyUsefulFunction(int arg); /* So compiler knows its type */
int main() {
int n = 10;
printf(“%d\n”, myTerriblyUsefulFunction(n)); /* Prints 10! */
}
• Compile prog.c with:
Slide # 103COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Compile prog.c with:
– gcc $CFLAGS prog.c silly.o –o prog
Gets passed straight through to the linker
C/C++
Header files
• Don’t want to have to declare the signature of all external
functions
• So instead, put all signatures of an external .o file in a separate
C file with the extension .h
– Called a header file
• For example, silly.h would contain just the lineint myTerriblyUsefulFunction(int arg);
• prog.c would then be
Slide # 104COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
#include “silly.h”
int main() {
int n = 10;
printf(“%d\n”, myTerriblyUsefulFunction(n)); /* Prints 10! */
}
C/C++
Lab 6 example
Breaks the code of structExample3.c into 3 modules:
1. The Studentmodule: student.c, student.h
– Typedef for Student; function newStudent, readOneStudent; student pool– Typedef for Student; function newStudent, readOneStudent; student pool
2. The StudentListmodule: studentList.c, studentList.h
– Typedef for StudentList; functions readStudents, addStudent
– Abstracts out the idea of a student list (which structExample3.c didn't do)
3. The main program, processStudents.c
– Begins:#include ″student.h″
#include ″studentList.h″
Slide # 105COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
#include ″studentList.h″
– Reads students from file, prints the list
C/C++
Dependency graph
student.c
student.o
student.h
studentList.h
studentList.c
studentList.o processStudents
Slide # 106COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
processStudents.c
processStudents.o
compilation linking
C/C++
Makefiles
• To reap full benefit of separate compilation, want to recompile
only the changed modules, then relink.only the changed modules, then relink.
• Done by make
– Takes a make file as a parameter
• Default name is Makefile or makefile
– A make file is a textual description of the dependency graph plus the
commands that make each arc
– Consists of a set of node descriptions of form
Slide # 107COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Consists of a set of node descriptions of formtargetNodeName: sourceNode1 sourceNode2 ...
<tab>Rule to make target node if source nodes all made
– Most rules can be omitted, as default rule to make a .o file is to compile
the corresponding .c file
C/C++
Example makefile (full)
processStudents: processStudents.o student.o studentList.oprocessStudents: processStudents.o student.o studentList.o
gcc processStudents.o student.o studentList.o -o processStudents
processStudents.o: processStudents.c student.h studentList.h
gcc $(CFLAGS) -c processStudents.c
student.o: student.c student.h
gcc $(CFLAGS) -c student.c
Slide # 108COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
studentList.o: studentList.c student.h studentList.h
gcc $(CFLAGS) -c studentList.c
C/C++
Example makefile (minimised)
OBJECTS = processStudents.o studentList.o student.oOBJECTS = processStudents.o studentList.o student.o
processStudents: $(OBJECTS)
$(CC) -o processStudents $(OBJECTS)
processStudents.o studentList.o: studentList.h
processStudents.o studentList.o student.o: student.h
Slide # 109COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Preview of lab 6 (structure)
• Covers previous two chapters of notes• Covers previous two chapters of notes
– Data structures
• structExamples 1 .. 3
– Code structure
• Separate compilation
Slide # 110COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
9. Dynamic memory allocation
• Motivation
• malloc/calloc• malloc/calloc
• free
• How it works
• realloc
• Memory leaks
Slide # 111COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Memory leaks
• Heap corruption
C/C++
Motivating example
• Consider a simulation of a community of rabbits:
forever {forever {
simulationTime += deltaT;
numRabbitsBorn = currentNumRabbits * birthRate * deltaT;
for each new rabbit {
construct new Rabbit record and add to population
}
for each rabbit in population {
if (deathProbability * deltaT * randomInRange(0,1) > 0.5) {
Destroy rabbit
Slide # 112COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
else
Have rabbit do something for its deltaT
}
}How do we do these steps?
NB: The lab exercise uses Students rather than Rabbits ☺
C/C++
The “Rabbit Pool” solutiontypedef struct rabbit { .... } Rabbit;
Rabbit pool[MAX_NUM_RABBITS];
Rabbit *freeRabbits = NULL;
void initialise() {
Link all rabbits in pool onto “freeRabbits” list
}
Rabbit *newRabbit(... rabbit initialisation info ...) {
if (freeRabbits == NULL) crash("Out of rabbits");
Rabbit rabbit = freeRabbits;
... fill in rabbit initialisation data ...
freeRabbits = rabbit -> next;
Slide # 113COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
freeRabbits = rabbit -> next;
}
void freeRabbit(Rabbit *rabbitPtr) {
rabbitPtr->next = freeRabbits;
freeRabbits = rabbitPtr;
}
This is a rudimentary (but
highly efficient) single-entity
dynamic memory system.
C/C++
Problems
• How big is MAX_NUM_RABBITS?
– If we choose it too low, program crashes
– If we choose it too high, program wastes memory– If we choose it too high, program wastes memory
• May lead to unnecessary thrashing
• If we have other dynamic items to deal with (fleas, trees,
grass, ...) it becomes impracticable to find good pool-size
constants for all.
• SO:1. Allocate all new entities from a single pool of available memory
Slide # 114COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
1. Allocate all new entities from a single pool of available memory
– malloc and free library function calls
2. Grow that pool by calls to the operating system as necessary.
– brk/sbrk system calls (hidden inside malloc)
C/C++
The student2 module
typedef struct student Student;
struct student {
Student *newStudent(char *name, int age) {Student *sp = NULL;int nameSize = 0;struct student {
char *name;int age;Student *next;
};
/* Free the student struct, making* it available for reuse */void freeOneStudent(Student *sp) {
free(sp->name);free(sp);
}
int nameSize = 0;sp = malloc(sizeof(Student));if (sp != NULL) {
/* if we're not out of memory */nameSize = strlen(name);sp->name = malloc(nameSize + 1); if (sp->name == NULL) { /* Out of memory? */
free(sp); /* Give back Student struct */sp = NULL; /* Function returns null*/
}else {
strncpy(sp->name, name, nameSize + 1);
NB!
Slide # 115COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
} strncpy(sp->name, name, nameSize + 1);sp->age = age;sp->next = NULL;
}}return sp;
}
C/C++
Points to note
• malloc allocates a chunk of heap memory of the
specified size (in bytes).specified size (in bytes).
– Returns a (void*) pointer (0 if out of memory)
• Use it wisely!
• For strings, must malloc (length+1) bytes
• free returns a malloc’d chunk of memory to the heap
free list
Slide # 116COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
free list
– Freed memory is a boojum1
– Looking at it will kill you.
C/C++
How not to allocate dynamic memory
• The following seems like a much easier approach.
– And it compiles, too.– And it compiles, too.
• But it's CATASTROPHIC (twice over).
• Why?
Student *newStudent(char *name, int age) {Student stud;stud.age = age;stud.name = name;stud.next = NULL;
Bad!
Bad!
Bad!
Bad!
Bad!
Bad!
Bad!
Slide # 117COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
stud.next = NULL; return &stud;
}
It's really really IMPORTANT that you know the answer to this(BOTH reasons).
Bad!
Bad!
Bad!
Bad!
Bad!
C/C++
A simplistic view of malloc/free
Free memory pool, say (100M + 8) bytesInitial heap state
freeList:
size next
100Mb 0
freeList:
99Mb 01048568 0p:
State after char *p = malloc(1048568); // 1 Mb – 8.
Slide # 118COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
size next
99Mb 0
size next
1048568 0p:
freeList:size next
99Mb 0
size next
1048568
State after free(p)
C/C++
Growing malloc’d blocks
• Often need to increase size of an allocated block
• Use function void *realloc(void *memPtr, int newSize)• Use function void *realloc(void *memPtr, int newSize)
– e.g. [Danger: bad code ahead!]
char *readLine() {
char *buff = NULL;
int numBytes = 0;
int c = 0;
while ((c = getchar()) != EOF && c != '\n') {
buff = realloc(buff, numBytes + 1); /* Gets a new bigger block */
buff[numBytes++] = c;
Ptr to a malloc'd block
If null, realloc = malloc
Slide # 119COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
buff[numBytes++] = c;
}
if (buff != NULL) {
buff[numBytes++] = '\0';
}
return buff; /* NULL if no data read */
}
NB: DON'T assume new block
is at same place as old block!
C/C++
BUT ...• There are at least three things wrong with that code:
1. It has a catastrophic bug (leading to a segment fault)
– UDOO: FIX IT!– UDOO: FIX IT!
2. reallocing memory blocks is potentially expensive
– may copy whole buffer if old one can’t just be grown
– doing it for every char is too inefficient for even me to tolerate
3. The specs of that function aren’t defined at the start and probably aren’t
what you want!
– What are they, i.e., exactly what does the function return? [Consider blank
lines, unterminated last lines, empty files, ...]
Slide # 120COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
lines, unterminated last lines, empty files, ...]
– Write a better function (see fgets for possible spec ideas)
• Also, should be checking for null return from realloc
– But hard to recover from it.
C/C++
A better realloc strategy
• Better to realloc only intermittently
• Allocate an initial buffer big enough for the average case• Allocate an initial buffer big enough for the average case
• Double the buffer size, or increment it by some non-trivial
amount, when necessary.
char *buff = malloc(INITIAL_BUFF_SIZE);
int buffSize = INITIAL_BUFF_SIZE;
int numBytes = 0;
while (...) {
Slide # 121COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
if (numBytes >= buffSize – 1) {
buffSize += BUFF_INCREMENT;
buff = realloc(buff, buffSize);
}
etc
}
C/C++
Memory leaks
• Programs that don’t free malloc’d memory have memory leaks
• Their memory footprint grows without bound
• To avoid this, every malloc should be matched to a
corresponding free.
• Similarly, every call to a function like newStudent must have a
matching call to the corresponding freeStudent.
• Need good clean multi-layered design
Slide # 122COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Need good clean multi-layered design
– Match allocation and deallocation at each level
C/C++
Example (from Lab 7, simplified)
for (rpt = 0; rpt < NUM_REPEATS; rpt ++) {
studs = readStudents(inputFile);
printStudents(&studs );
freeStudents(&studs );
Student *newStudent(char *name, int age) {...sp = malloc(sizeof(Student));buffSize = strlen(name) + 1;matchfreeStudents(&studs );
rewind(inputFile); }
buffSize = strlen(name) + 1;sp->name = malloc(buffSize);...strncpy(sp->name, name, buffSize);sp->age = age;sp->next = NULL;return sp;
}
void freeOneStudent(Student *sp) {
StudentList readStudents(FILE *fp) {StudentList studs = {NULL, NULL};Student *sp = readStudent(fp);while (sp != NULL) {
addStudent(&studs, sp);sp = readStudent(fp); match
match
Slide # 123COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
free(sp->name);free(sp);
}
sp = readStudent(fp); };return studs;
}
void freeStudents(StudentList *studs) { /* **** TBS **** */
}
match
match
must match
C/C++
Detecting memory leaks
• Need a tool for the job. Lots available. e.g.:
– valgrind – see http://valgrind.org/– valgrind – see http://valgrind.org/
• Installed on our lab machines
• Lots of capabilities
• Simplest:valgrind --leak-check=yes processStudents studlist.txt
• Large, slow, complex internally, but fairly easy to use
– memwatch – see http://www.linkdata.se/sourcecode.html
Slide # 124COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– memwatch – see http://www.linkdata.se/sourcecode.html
• Provides its own malloc/free functions
• Easy-to-understand log file
• Simple, lightweight, but has to be compiled into program
C/C++
Heap corruption
• Over-running a malloc’d buffer is fatal
– Probably– Probably
– Eventually
• Difficult to debug
– Solution: don’t bug! Not-bugging is easier than debugging!
• Again there are many tools to help you find heap corruptions
– valgrind checks every memory reference (but slow and cumbersome)
Slide # 125COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– electric fence (just add flag --lefence to the linking command) uses
hardware segmentation registers to check every heap memory access
– memwatch detects that heap blocks have been overrun but doesn’t tell
you where it happened
C/C++
10. File I/O
• I/O streams• I/O streams
• Character-by-character I/O
• Line-by-line I/O
• Formatted I/O
Slide # 126COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
I/O Streams
• An I/O stream abstracts the idea of a sequential file.
• Delivers (input stream) or accepts (output stream) a • Delivers (input stream) or accepts (output stream) a
stream of bytes.
• C type FILE* defined in stdio.h
• Open a file with fopen
FILE *fIn = fopen("sillyIn.txt", "r");
Slide # 127COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
File name "r" = open for reading
"w" = open for writing
C/C++
main I/O functions• Character-by-character
– int fgetc(FILE* fp) // Returns an int with char in low byte, or EOF
– int fputc(int c, FILE *fp) // Returns an int with c in low byte, or EOF– int fputc(int c, FILE *fp) // Returns an int with c in low byte, or EOF
– getchar() = fgetc(stdin)
– putchar(c) = fputc(c, stdout)
• Line-by-line– char *fgets(char *buffPtr, int size, FILE *fp)
– int fputs(const char *buffPtr, FILE *fp)
– puts(s) = fputs(s, stdout)
– There’s also a gets but you should NEVER use it!
Slide # 128COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– There’s also a gets but you should NEVER use it!
• Warning: line-termination is platform-dependent.– Linx, MacOS X: \n
– Windows: \r\n
– Old Mac: \r
Creates problems when moving text files between OSs
C/C++
main I/O functions (cont’d)
• Block-by-block (binary files)– size_t fread(void *buffPtr, int elemSize, int numElems, FILE *fp)
– size_t fwrite(const void *buffPtr, int elemSize, int numElems, FILE *fp)
• Formatted I/O– int fscanf(FILE *fp, const char *format, ...)
– int fprintf(FILE *fp, const char *format, ...)
– printf(s, ...) == fprintf(stdout, s, ...)
– scanf(s, ...) == fscanf(stdin, s, ...)
– sprintf(char *buffPtr, const char *format, ...) // DANGEROUS!
Slide # 129COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– sprintf(char *buffPtr, const char *format, ...) // DANGEROUS!
– snprintf(char *buffPtr, int buffsize, const char *format, ...) // not ANSI �
C/C++
Interlude
• As time permits, demos of ...• As time permits, demos of ...
– ddd
– valgrind
– memwatch
– electric fence
Slide # 130COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
11. C potpourri
• Some of the things about C that never got mentioned.
– Declaration qualifiers
• static, extern, volatile, register
– Conditional compilation
– enums
– Multidimensional arrays
– Passing functions as parameters
– Bit manipulation
Slide # 131COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Bit manipulation
– Other standard libraries
C/C++
Declaration qualifiers
• static
1. Applied to a global-level variable: means “visible only within this 1. Applied to a global-level variable: means “visible only within this
file”
– So isn’t passed to the linker within the .o file
2. Applied to a local variable: means isn’t an auto variable (i.e., within
the stack frame) but occupies space in the initialised data segment of
the program
– So holds its value over multiple calls to function
• extern
Slide # 132COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• extern
– Tells the linker that the definition of a variable is elsewhere (i.e., it’s
not allocated space within this module, but can be referenced).
C/C++
Declaration qualifiers (cont’d)
• volatile
– Tells the compiler that this variable’s value may change unpredictably – Tells the compiler that this variable’s value may change unpredictably
so don’t use the optimiser on it
• register
– Suggests to the compiler that this value could usefully be held in a
register (for maximum efficiency)
Slide # 133COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Conditional compilation
• Used in assignment
• “if” statements in preprocessor to control what gets passed to the compiler, e.g.:the compiler, e.g.:#ifdef DEBUG
printf("Allocated a new student, name = %s\n", stud.name);
#else
namelog[numStuds++] = name;
#endif
• Can define the symbol DEBUG at the top with#define DEBUG
Slide # 134COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
#define DEBUG
or at compilation time with the –D flag to gcc, e.g.
gcc $CFLAGS –DDEBUG sillyprog.c –o sillyprog
• Widely used through C library code, e.g., to enable special GNU language extensions
C/C++enums
Rather than this
write this
#define SPADES 0
#define DIAMONDS 1
#define CLUBS 2
#define HEARTS 3
Suit suit = HEARTS;
.
#define HEARTS 3
typedef enum {SPADES, HEARTS, DIAMONDS, CLUBS} Suit;
Can then write:
The enumeration constants are actually just
thinly disguised ints. Can still write:
Slide # 135COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
.
switch (suit) {
case SPADES: ...
cast HEARTS: ...
etc
}
thinly disguised ints. Can still write:
suit = 3; /* � */
[But not in C++ ☺]
C/C++
multidimensional arrays
Two sorts of 2D arrays:
(a) 1D arrays with fudged subscripting!
typedef enum{PAWN, BISHOP, KNIGHT, ROOK, KING, QUEEN} Piece;
void setPiece(int board[8][8], int row, int col, Piece piece) {
board[row][col] = piece;
}
int main() {
int board[8][8];
setPiece(board, 3, 5, ROOK);
return EXIT_SUCCESS;
Compiler needs at least second subscript to compute
actual 1D subscript as row*numCols + col
Slide # 136COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
return EXIT_SUCCESS;
}
board: ...
row 0 row 1 etc
C/C++
multidimensional arrays (cont'd)
(b) vectored arrays (Java style)
typedef enum{PAWN, BISHOP, KNIGHT, ROOK, KING, QUEEN} Piece;
void setPiece(int **board, int row, int col, Piece piece) {
board[row][col] = piece;
}
int main()
{
int *board[8]; /* an array of 8 pointers to ints */
int row = 0;
for (row = 0; row < 8; row++) {
Slide # 137COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
for (row = 0; row < 8; row++) {
board[row] = calloc(8, 4); /* Allocate space for a row */
}
setPiece(board, 3, 5, ROOK);
return EXIT_SUCCESS;
}board:
row 0
row 1
etc for other rows
C/C++
Functions as parameters
void sillyFunc1(const char *name) {
printf("Hello %s\n", name);
}}
void sillyFunc2(const char *name) {
printf("Goodbye %s\n", name);
}
void doSomethingElse(void (*f)(const char*), char* arg) {
f(arg);
}
Slide # 138COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
int main()
{
doSomethingElse(sillyFunc1, "Richard");
doSomethingElse(sillyFunc2, "Fred");
return EXIT_SUCCESS;
}
C/C++
Bit manipulation
• Operators '|', '&' and '^' are bitwise OR, AND and XOR
respectivelyrespectively
• Often used to encode booleans as bits of a "flag" word, e.g.#define INITED 1
#define ALIVE 2
#define ZOMBIE 4
#define HUNGRY 8
int status = ...
Slide # 139COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
if (status & HUNGRY) { ... }
• Can also pack n-bit fields into words in a struct, access 'em as
usual for struct fields
– But rare.
C/C++
Other standard libraries
• No time to cover.
• But at least be aware of their • But at least be aware of their
existence!
– assert.h
– ctype.h
– errno.h
– float.h
– limits.h
– signal.h
– stdarg.h
– stddef.h
– stdio.h
– stdlib.h
Slide # 140COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– limits.h
– locale.h
– math.h
– setjmp.h
– stdlib.h
– string.h
– time.h
– stddef.h
C/C++
12. Visual Studio
• Introductory burble
– Why you might like it.– Why you might like it.
– Why you might hate it.
• Demo
– Some of the panes
– Making a new project
• Getting those settings right!
Slide # 141COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Getting those settings right!
– A quick look at the debugger
C/C++
Note on using Visual Studio
• In labs, boot to Windows to use VS2008
• From Linux it is also possible to use COSCTERM• From Linux it is also possible to use COSCTERM
– CSSE > Servers > CSSEWindows
– But not intended for heavy usage and may fail if
overloaded.
Slide # 142COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
13. From C to C++“C makes it easy to shoot yourself in the foot; C++ makes it harder, but when
you do, it blows your whole leg off.”
-- Bjarne Stroustrup (C++ creator)
• Why/why not C++?
• Design principles
• Using C++ in 208
Slide # 143COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
References:
Stroustrup’s definitive book: “The C++ Programming Language”
The C++ tutorial available at www.cplusplus.com/doc/
Lots of other tutorials available via www.programmingtutorials.com/cplusplus.aspx
Series of books by Scott Meyers (“Effective C++” etc)
Your favourite other C++ textbook
C/C++
Why C++?
• OO-programming support
• Operator overloading
• Templates ("generic" classes)
• Exception handling
• Many minor syntax improvements
• More extensive library, particularly
– string support (ASCII or Unicode)
Slide # 144COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– string support (ASCII or Unicode)
– collections classes
• stacks, queues, lists, vector, map
C/C++
Why not C++?
• Complex
– Difficult semantics
– Lots of different ways of solving any given problem
• Confusing error messages
• Can be very inefficient if misused
• Less portable (?)
Slide # 145COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Stroustrup's C++ Design principles
• C++ is designed to be a statically typed, general-purpose language that is as
efficient and portable as C
• C++ is designed to directly and comprehensively support multiple
programming styles (procedural programming, data abstraction, object-
oriented programming, and generic programming)
• C++ is designed to give the programmer choice, even if this makes it
possible for the programmer to choose incorrectly
• C++ is designed to be as compatible with C as possible, therefore providing
a smooth transition from C
Slide # 146COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• C++ avoids features that are platform specific or not general purpose
• C++ does not incur overhead for features that are not used
• C++ is designed to function without a sophisticated programming
environment
C/C++
C++ in COSC208
• Treat as “enhanced C”
– Most C programs also valid C++ programs– Most C programs also valid C++ programs
– New features introduced incrementally
– Continue to use “not real C++” things like printf and malloc for a
lab or two.
Slide # 147COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Writing and compiling C++
• Just like writing and compiling C except
– File extension is “.cpp”, not “.c”– File extension is “.cpp”, not “.c”
• Still have .h files as before
– Visual studio automatically compiles .cpp files as C++
– In Linux, compiler is g++ rather than gcc
• e.g.: g++ -ansi -Wall -g thing.cpp
• Actually it’s the same program
– Can also use “gcc -x c++ ...”
Slide # 148COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Can also use “gcc -x c++ ...”
– Or even omit “-x c++” except when linking .o files
» Language inferred from file extension
C/C++
14. Your first C++ program
• Minor syntax enhancements• Minor syntax enhancements
• Declaring simple classes
• Stack objects (C++) versus heap objects (Java)
• Namespaces
• Assignment of objects
• Separating interface and implementation
Slide # 149COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
stack.cpp#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#define STK_MAX 100
#include <cstdlib>
#include <cstdio>
#include <cassert>
using namespace std;
or (better)
#define STK_MAX 100
class Stack {
int stk[STK_MAX]; // Use an array to store the stacked data
int stkIndex; // Index of the first free position in the stack
public: // Stuff before this is private, after it is public
Stack() { // The constructor
stkIndex = 0; // Just zero the stack index
};
void push(int i) { // Method to push i into the stack
assert(stkIndex < STK_MAX);
Slide # 150COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
assert(stkIndex < STK_MAX);
stk[stkIndex++] = i;
}
int pop() { // Method to return the result of popping the top item
assert(stkIndex > 0);
return stk[--stkIndex];
}
};
C/C++
stack.cpp (cont'd)
// A main program using the Stack class.
// It pushes all its arguments (interpreted as ints) onto the stack, then// It pushes all its arguments (interpreted as ints) onto the stack, then
// pops them off and displays them on stdout.
// e.g. example1 10 20 30 outputs "30 20 10\n"
int main(int argc, char *argv[]) {
Stack stack; // This is a stack
for (int i = 1; i < argc; i++) {
stack.push(atoi(argv[i]));
}
for (int i = 1; i < argc; i++) {
Slide # 151COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
for (int i = 1; i < argc; i++) {
printf("%d ", stack.pop());
}
printf("\n");
return 0;
}
C/C++
Points to note
• Minor syntax enhancements (as in C99)
– // comments– // comments
– for (int i …)
• And can declare variables anywhere that a statement is OK
• Declaration of a new class is similar to Java
– But variables and method are private by default
– public: changes default scope
Slide # 152COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– public: changes default scope
• In the main program Stack stack declares stack to be
an object of type Stack
C/C++
Points to note (cont'd)
• It also calls the default (parameterless) constructor • It also calls the default (parameterless) constructor
to initialize it.
– If you don't declare one, C++ will make one
• It sets everything to default values (typically zero/null)
• stack IS a Stack and not just a pointer to it!
– See next slide
Slide # 153COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– See next slide
C/C++
Slide # 154COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Points to note (cont'd)
• Since stack is a local variable (i.e. in the current • Since stack is a local variable (i.e. in the current
function’s “stack frame”, it disappears when function
returns.
– So don’t try returning a pointer to it!!
– No, the compiler will not warn you.
– The program will just crash at runtime.
Slide # 155COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– The program will just crash at runtime.
– Yes, you'll do this at least once.
• Calls to an object’s methods are as in Java
C/C++
Function name collision in C
A problem with C: all identifiers "global"
Module A: → collisionsModule A:
global variable datafunctions max, printData Module B:
global variable datafunctions max, sort
Module C:
functions sort, printData
→ collisions
Slide # 156COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
C++ solution: namespaces
• Identifiers generally of form namespace::identifier
• Standard library functions are in std namespace, e.g.
omit for global namespace
• Standard library functions are in std namespace, e.g.
#include <cstdio> // C++ version of stdio.h
.
.
.
std::printf("Goodbye cruel world\n");
OR insert here
using namespace std;
but slightly defeats the purpose
Slide # 157COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
std::printf("Goodbye cruel world\n");
• Also classes provide their own namespaces
– See later
but slightly defeats the purpose
C/C++
Assignment of objects
• Consider (C++):• Consider (C++):
Stack stack1;
stack1.push(20);
Stack stack2; // Default constructor called
stack2 = stack1; // Assignment
stack1.pop();
• What are the contents of stack1 and stack2?
Slide # 158COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• What are the contents of stack1 and stack2?
C/C++
Answer
• stack1 is empty
• stack2 contains the value 20• stack2 contains the value 20
• because assignment copies the complete state
– Unless we define the assignment operator to have a
different meaning
– See later.stack2stack2 stack1
Slide # 159COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
stk[1..n]
stkIndex
stk[1..n]
stkIndex=
all fields copied
C/C++
Separating interface & implementation
• Break code into stack.h, stack.cpp and main.cpp.
• Both cpp files #include "stack.h"• Both cpp files #include "stack.h"
• stack.h is:
#define STK_MAX 100class Stack {
int stk[STK_MAX]; // Use an array to store the stacked dataint stkIndex; // Index of the first free position in the stack
public: // Stuff before this is private, after it is publicStack(); // The constructor
Slide # 160COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
Stack(); // The constructorvoid push(int i); // Method to push i into the stackint pop(); // Method to return the result of popping the top item
};
C/C++
Separating interface & impl. (cont'd)
• stack.cpp (the implementation of Stack) is:
#include "stack.h"#include "stack.h"
#include <assert.h>
Stack::Stack() { // This is the constructor
stkIndex = 0; // All it does is make sure the index is zero
}
void Stack::push(int i) { // Implementation of the push method
assert(stkIndex < STK_MAX);
stk[stkIndex++] = i;
Slide # 161COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
stk[stkIndex++] = i;
}
int Stack::pop() { // Implementation of the pop method
assert(stkIndex > 0);
return stk[--stkIndex];
}
The notation Stack::thing means “thing
in the Stack class’s namespace”.
C/C++
15. Dynamic memory in C++
• Allocating heap space within a constructor• Allocating heap space within a constructor
• Deallocating space with the destructor
• Problems with assignment
Slide # 162COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Stack, take 2
• Suppose we want client class to specify maximum stack
space to allocate?space to allocate?
• Raises two issues:
1. How does client specify that maximum size?
Ans: Through a constructor parameter
2. How does Stack define a variable-sized array?
Ans: By allocating space for the stack dynamically (i.e. on the heap)
• But 2 raises another issue
Slide # 163COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• But 2 raises another issue
1. How does the dynamically allocated space get freed again?
Ans: By freeing it in the class’s destructor.
C/C++
Stack, take 2 (cont'd)
• So: stack.h becomes• So: stack.h becomesclass Stack {
int *stk; // A pointer to the dynamically-allocated stack space
int max; // No. of integers of allocated stack space
int stkIndex; // Index of the first free position in the stack
public: // Stuff before this is private, after it is public
Stack(int stkMax); // Constructor allowing user-specified maximum space
~Stack(); // The destructor – called when Stack object is freed
Slide # 164COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
~Stack(); // The destructor – called when Stack object is freed
void push(int i); // Method to push i into the stack
int pop(); // Method to return the result of popping the top item
};
C/C++
Stack, take 2 (cont'd)
• The new bits of stack.cpp are:
Stack::CStack(int stkMax) { // The constructor -- allocate "stkMax" ints of stack
stk = new int[stkMax]; // Allocate the space
max = stkMax; // Define the other instance variables ...
stkIndex = 0; // ... in the usual way.
}
Stack::~Stack() { // This is the destructor - called when the object is deleted
Slide # 165COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
delete [] stk; // Free the memory we allocated with 'new'
}
UDOO: what changes are necessary to push and pop?
C/C++
Notes on Stack, mark 2
• Syntax to invoke this new constructor is:
– Stack myStack(50);– Stack myStack(50);
OR (equivalent but more long-winded)
– Stack myStack = CStack(50);
• In C++ we allocate/deallocate memory with new/delete.
– Much nicer than malloc/free
• Don't use them again!
Slide # 166COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– When deleting arrays, must use form delete [] p
• DON'T OMIT THE "[ ]"
– It will compile but crash or leak memory!!
– If new fails we get an exception thrown – see later.
C/C++
Notes on Stack, mark 2 (cont'd)
• There is now no parameterless constructor
– Compiler will not generate one now (like Java)
– Some things will not work without one e.g. Stack anotherStack;
• So you could define a parameterless constructor as well.
– Stack::Stack() { …}
• Parameterless constructor is “invoked” by Stack anotherStack;
– NOT by Stack anotherStack!!
Slide # 167COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Latter declares a function anotherStack that returns a Stack!
C/C++
Notes on Stack, mark 2 (cont'd0)
• C++ (like Java) allows overloaded functions and constructors
– But note that you can’t have one of the overloaded constructors “call” another – But note that you can’t have one of the overloaded constructors “call” another
one of them to initialise *this, as you can in Java
• The following compiles fine but doesn’t work!
CThing::CThing() { … } // Parameterless constructor
CThing::CThing(int blah) { // Constructor with params
CThing(); // Attempt to invoke parameterless constructor
… etc …
Slide # 168COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
… etc …
}
Creates a new object then discards it!
Doesn’t initialise the fields of *this as you probably expected!
C/C++
Be careful assigning objects!
• With our new Stack class, assignment is perilous!
• What would stk2 contain after the following?
Stack stk1(10), stk2(20);
stk1.push(5);
stk2 = stk1;
stk1.pop();
stk1.push(7);
Slide # 169COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Be careful assigning objects (cont'd)
• Immediately before stk2 = stk1 we have:
int *stk;int max; 10int stkIndex; 1
int *stk;
510-int array
20-int array
stk1
stk2
Slide # 170COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
int *stk;int max; 20int stkIndex; 0
stack space
heap space
C/C++
Be careful assigning objects (cont'd)
• Immediately after stk2 = stk1 we have:
int *stk;int max; 10int stkIndex; 1
int *stk;
510-int array
20-int array
stk1
stk2
shared!
Slide # 171COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
int *stk;int max; 10int stkIndex; 1
stack space
heap space
lost (leaked)!
not shared!
C/C++
Solutions to those problems
• Either:
– Don’t ever use assignment on objects that contain – Don’t ever use assignment on objects that contain
dynamically-allocated data
• This really isn’t a solution at all.
• You’re just setting a huge trap for yourself and others.
• Or
– Implement the class properly!
• Implement a copy constructor and an assignment operator (see
Slide # 172COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Implement a copy constructor and an assignment operator (see
later) that either:
– duplicate the associated heap space (“deep copy”), or
– implement controlled sharing of heap space, with reference counting
so that heap space can be freed on the last destructor call
C/C++
Interlude: OO in Ctypedef struct stack Stack;
struct stack {
int data[MAX_SIZE];int main(int argc, char* argv[ ]) {
int i = 0;int stkIndex;
};
void init (Stack* this) {
this->stkIndex = 0;
}
void push(Stack* this, int n) {
this->data[this->stkIndex++] = n;
int i = 0;
Stack stack;
init (&stack);
for (i = 1; i < argc; i++) {
push(&stack, atoi(argv[i]));
}
for (i = 1; i < argc; i++) {
printf("%d ", pop(&stack));
Slide # 173COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
this->data[this->stkIndex++] = n;
}
int pop(Stack* this) {
return this->data[--this->stkIndex];
}
printf("%d ", pop(&stack));
}
}
C/C++
From C to C++typedef struct stack Stack;
struct stack {
int data[MAX_SIZE];int main(int argc, char* argv[ ]) {
int i = 0;
class Stack
int stkIndex;
};
void init (Stack* this) {
this->stkIndex = 0;
}
void push(Stack* this, int n) {
this->data[this->stkIndex++] = n;
int i = 0;
Stack stack;
init (&stack);
for (i = 1; i < argc; i++) {
push(&stack, atoi(argv[i]));
}
for (i = 1; i < argc; i++) {
printf("%d ", pop(&stack));
Become constructor + methods;
this parameter is implicit.
stack.push(
Slide # 174COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
this->data[this->stkIndex++] = n;
}
int pop(Stack* this) {
return this->data[--this->stkIndex];
}
printf("%d ", pop(&stack));
}
}
stack.pop()
C/C++
16. Copy constructors
• Initialisation of objects
• Copy constructors
• structs
• Reference variables
Slide # 175COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Initializers
Consider the code
int i = 10 ;
Isn’t this the same as
int i ;
i = 10 ; ?
Slide # 176COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Answer: No!
int i = 10 ; int i ; Declarationint i = 10 ; int i ;
i = 10;
Declaration
Declaration
Assignment
Initializer
Slide # 177COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
With objects, it matters!
Stack stk; // Initialise fields with parameterless constructor
stk = anotherCStackObj; // Redefine all fields by assigning
// ... them from anotherCStackObj// ... them from anotherCStackObj
versus
Stack stk = anotherCStackObj;
// Copy constructor initializes all fields by copying
// them from “anotherCStackObj”.
Slide # 178COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
So second version does less work!
C/C++
Specifying field initialisers
• Rather than using assignments in constructor to set field
values, can use special initialiser syntax.values, can use special initialiser syntax.
struct Point {
int x, y;
Point(int x0, int y0) : x(x0), y(y0) { }
}
Field names
Initialiser values
In C++, a struct is just a
class in which the default
attribute access is public.
No need for clumsy C
"tag" syntax.
Slide # 179COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Sometimes must do this, e.g. when field is of a class type with
no default constructor or when it’s a reference (see later)
Initialiser values
C/C++
Defining your own copy constructor
• Default copy constructor just copies all object fields.
• But we can define our own, e.g.
class Stack {class Stack {
int stkIndex;
int stk[MAX_STACK_ELEMENTS];
public:
Stack(const Stack& other) {
stkIndex = other.stkIndex;
for (int i = 0; i < stkIndex; i++)
stk[i] = other.stk[i];
Slide # 180COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
stk[i] = other.stk[i];
}
.
.
}
• Don’t worry about the meaning of “const Stack&” for now
copy constructor (equiv. to default in this case)
C/C++
A problem with object parameters
Why doesn't the following function work?
// Function to push the value 1 onto the// Function to push the value 1 onto the
// stack given as a parameter. [Doesn't work!]
void push1(Stack stk) {
stk.push(1);
}
where caller does:
Slide # 181COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
Stack myStack;
.
.
push1(myStack); // Try (unsuccessfully) to push 1
C/C++
Answer
• Parameter stk is a Stack object local to push1
• It is constructed using a copy constructor that copies fields
from the actual parameter.
• Pushing 1 onto it has no effect on the actual parameter
• stk is discarded when push1 returns
Slide # 182COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Fix #1: pass a pointer as parameter
// Function to push the value 1 onto the
// stack that it is given as a parameter.
void push1(Stack *stk) {void push1(Stack *stk) {
stk->push(1);
}
Caller must then do:
Stack myStack;
Slide # 183COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
.
.
push1(&myStack); // push 1 onto myStack.
C/C++
Fix #2: use a reference parameter
// Function to push the value 1 onto the
// stack that it is given as a parameter.
void push1(Stack& stk) {
stk.push(1);
}
Caller can now do as before:
Stack myStack;
Means that parameter stk
is a reference to an object
of type Stack.
Automatically dereferenced
Slide # 184COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
Stack myStack;
.
.
push1(myStack); // push 1 onto myStack.
C/C++
More on references
• Non-parameter variables can be references, too
int n = 1;int n = 1;int& nRef = n; // This is a reference variablenRef = 5;printf("%d\n", n); // Prints '5'.
• A reference is an alias for the variable that it references
– The association is made only by initialisation, NOT assignment
• Any use of the reference actually uses the referenced variable
• References are just pointers in disguise
Slide # 185COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• References are just pointers in disguise
– like all non-primitive variables in Java
C/C++
Use of references (style guideline)
• Use references only for formal parameters
• Use reference parameters when forced to e.g.• Use reference parameters when forced to e.g.
– Copy constructors
– Operator overloading
• Don’t use reference parameters when passing scalar types
• Use reference parameters for passing objects as parameters:
– If efficiency is an issue (saves copying all fields of the object), or
– You want side effects and the user of the function/method will expect
Slide # 186COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– You want side effects and the user of the function/method will expect
them
• e.g. like the push2 function
• Otherwise, if you want side effects, require user to pass an
explicit pointer
C/C++
17. Derived classes
• Declaring subclasses
• const objects• const objects
Slide # 187COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Declaring a derived class ("subclass")
• Given a base class Person:
class Person {
char *name; // The only field is person's namechar *name; // The only field is person's name
public:
Person(char *name) { // Constructor
this->name = malloc(strlen(name)+1);
strcpy(this->name, name); // The only time I allow strcpy in 208!
}
~Person() { // Destructor
delete[] name;
}
Slide # 188COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
}
void print(char *prefix) { // Prints prefix followed by name
printf("%s%s\n", prefix, name);
}
};
C/C++
Derived classes (cont'd)
• Can subclass to Student:
class Student : public Person { // Student is a sub-class of Personclass Student : public Person { // Student is a sub-class of Person
public:
int id; // Extra field: student ID
Student(const char *name, int id) : Person(name) { // Constructor
this->id = id;
}
// Print prefix followed by name (ID)
Parameter to base-class constructor
Slide # 189COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
// Print prefix followed by name (ID)
void print(const char *prefix) const {
printf("%s%s (%d)\n", prefix, name, id);
}
};
C/C++
Example use
int main(void) {
Person someone("Fred");
Student stud("Chung", 123456);Student stud("Chung", 123456);
someone.print("someone is ");
stud.print("stud is ");
printf("\n");
Person *ppers = &someone;
Student *pstud = &stud;
ppers->print("ppers is ");
pstud->print("pstud is ");
Slide # 190COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
pstud->print("pstud is ");
ppers = pstud;
ppers->print("After assignment, ppers is ");
}
C/C++
Output from example
someone is Fred
stud is Chung (123456)
ppers is Fred
pstud is Chung (123456)
After assignment, ppers is Chung
NB: DOESN'T say “ppers is Chung (123456)”
Slide # 191COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
To get automatic selection of the right method when usingpointers, must declare print methods as virtual, i.e.
virtual void print(char *prefix) { .... etc
C/C++
const methods
• The print method was declared const
– void print(const char *prefix) const { ...– void print(const char *prefix) const { ...
• This means it doesn't modify the state of the object
• Hence can be called if you have a const pointer to the object,
e.g.const Student* pStud = ...
pStud->print("Student is "); // This is valid only if print is const
• The position of the const qualifier is important!
Slide # 192COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• The position of the const qualifier is important!const char* getName() { ... } // Returns a const pointer
char* getName() const {...} // Declares a constmethod
const char* getName() const {...} // Does both
C/C++
18. C++ Libraries
• Much smaller set than Java's.
– Strings
• string, cctype, cwtype, cstring, cwchar, cstdlib• string, cctype, cwtype, cstring, cwchar, cstdlib
– Input/output
• iostream, iosfwd, ios, streambuf, istream, ostream, iomanip, sstream,
cstdlib, fstream, cstdio, cwchar
– Containers and iterators
• vector, list, deque, queue, stack, map, set, bitset, iterator
– Algorithms
Slide # 193COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• algorithm, cstdlib
– General Utilities
• utility, functional, memory, ctime
We look briefly only at the italicised blue ones!
C/C++
C++ Library classes (cont’d)
– Diagnostics
• exception, stdexcept, cassert, cerrno• exception, stdexcept, cassert, cerrno
– Localisation
• locale, clocale
– Language support
• limits, climits, cfloat, new, typeinfo, cstddef, cstdarg, csetjmp,
cstdlib, ctime, csignal
– Numerics
Slide # 194COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Numerics
• complex, valarray, numeric, cmath, cstdlib
C/C++
More-extensive libraries
• Some improvements to the standard are proposed in
Technical Report #1, aka "TR1".Technical Report #1, aka "TR1".
– See http://en.wikipedia.org/wiki/Technical_Report_1
• Adds regular expressions, smart pointers (heap pointers with
garbage collection capabilities), hash tables, random number
generators, better functional-programming capabilities (but still
hideous)
• A much bigger defacto-standard library is boost
Slide # 195COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• A much bigger defacto-standard library is boost
– See www.boost.org
– All the above plus imaging, networking, graph algorithms,
linear algebra, maths, more containers, ....
C/C++
demo.cpp (string & istream)
// Program to demonstrate simple uses of the string// class and an outstream rather than printf.
#include <string>#include <string>#include <iostream>
using namespace std; // NB: version in lab doesn't use this. Prefixes all names with std::
void printMe(const string s) {cout << s << endl;
}
int main(int argc, char *argv[ ]){
string person = "Fingers McSnortle";
Slide # 196COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
string person = "Fingers McSnortle";cout << "The value of person is " << person << '\n';string anotherString = "person = " + person;cout << anotherString << endl;cout << "Or using a concatenation operator: " + person << endl;cout << "The length of 'person' is " << person.length() << endl;
C/C++
demo.cpp
(cont’d)
// Now do some string processing on the first argument (if supplied).if (argc == 2) {
string name(argv[1]); // The name argumentcout << "Processing name '" << name << "'\n";size_t posOfSpace = name.find(" ");
string firstName, lastName;if (posOfSpace == string::npos) { // Not foundif (posOfSpace == string::npos) { // Not found
firstName = "";lastName = name;
}else {
firstName = name.substr(0, posOfSpace); // Second param is *length*lastName = name.substr(posOfSpace+1);
}cout << "First name: " + firstName + "\n";cout << "Last name: " + lastName + "\n";cout << "Full name, surname first: " << lastName << ", " << firstName << std::endl;
}
Slide # 197COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
}
// Mixing strings and char* variables
string candidate; // An empty stringcandidate = "Barak"; // This works. [Surprised?]printMe("Engelbert"); // And this. [You should be.]candidate += " Obama"; // This too.
}
C/C++
Points to note
• Documentation accessible in VS by clicking include file name
– Guided tour – DEMO.– Guided tour – DEMO.
• string class gives us a Java-like string capability
– No memory leak issues unless you create pointers to strings with new
(in which case you’d better use delete too!)
– One of constructors takes C-style string as parameter
• Which also allows things like s = “blah”, where s a string, because of “on
the fly” new object construction
– Disabled with keyword explicit in constructor declaration
Slide # 198COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Disabled with keyword explicit in constructor declaration
C/C++
Points to note (cont’d)
– Overloaded ‘+’ operator does concatenation
– find method equivalent to indexOf
• returns value std::string::npos if not found (a symbolic -1)• returns value std::string::npos if not found (a symbolic -1)
• I/O done with iostreams
– std::cin is standard input stream, std::cout is standard output stream
– Overloaded “<<“ for output, “>>” for input
– Special entities called iomanipulators can be used for manipulating the
stream (e.g. flush to flush it, endl for newline + flush).
– Expressions like stream << dataItem evaluate to a (new) output
Slide # 199COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Expressions like stream << dataItem evaluate to a (new) output
stream, to which further items can be output.
#include <string>#include <iostream>using namespace std;int main(int argc, char *argv[ ]) {
if (argc != 3) {cerr << "Usage: " << argv[0] << " fromString toString" << endl;return EXIT_FAILURE;
}
replace.cpp(buggy)
string from(argv[1]); // String to be replacedstring to(argv[2]); // String to replace it withsize_t fromLength = from.length();size_t toLength = to.length();string line;getline(cin, line); // Read a line (sets fail if gets nothing)while (!cin.fail()) {
size_t pos = line.find(from); // Position of fromString in lineif (pos != string::npos) { // If "from" found, if (pos != string::npos) { // If "from" found,
line.replace(pos, fromLength, to); // Replace it with the "to" string}cout << line << endl;getline(cin, line);
}return EXIT_SUCCESS;
}COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Points to note• cerr is standard error stream
• cin >> n is equiv. of scanf(“%d”, &n) and similarly for other standard typesstandard types
• Can read whole lines with getline– Sets fail flag if error occurs, checked with cin.fail()
• replace method modifies the string in place– C++ strings are mutable
• Can modify program to take input from a nominated file by use of ifstream class (in <fstream>)– Subclass of istream
Slide # 201COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Subclass of istream
– Constructor takes filename as param (opens file)
– Check fail flag to see if open succeeded
• Switching between cin and ifstream requires care!
C/C++
Lecture #16 intro
• A plug for the on-line surveys [plug, plug ...]
• Assignment:• Assignment:
– At least one person has finished
• ~ 6 hours, so half the size of assignment 1?
– You MUST use ISO Standard C++ library functions ONLY (STL)
• Avoid the .NET/Visual Studio "Standard Library" functions
• "Missing manifest" error in lab is another version of the
"missing DLL" error.
Slide # 202COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
"missing DLL" error.
• Lab 14: problem with sort. Please download another copy.
C/C++
pointlist.cpp#include <utility> // The pair class is in here#include <vector>#include <iostream>#include <string>#include <string>
using namespace std;
typedef pair<double, double> Point2d; // A quick and dirty Point representation!typedef vector<Point2d> PointList; // A vector (aka ArrayList) of Point2d'stypedef PointList::iterator Iter; // An iterator over a PointListtypedef PointList::const_iterator ConstIter; // This iterator doesn't allow list modification
void printAll(const PointList& list) {
Slide # 203COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
// Prints the size of the list then all the elements in it, one per line.cout << "List contains " << list.size() << " points" << endl;for (size_t i = 0; i < list.size(); i++) {
cout << "Element " << i << " is (" << list[i].first << "," << list[i].second << ")" << endl;
}}
C/C++
pointlist.cpp (cont’d)void printAllWithIterator(const PointList& list) {
// Prints the list in the form "[(1,3),(2,4),(7,11)]".char* separator = ""; // Char to print before each item in listcout << '[';for (ConstIter it = list.begin(); it != list.end(); ++it) {for (ConstIter it = list.begin(); it != list.end(); ++it) {
cout << prefixChar << "(" << it->first << ',' << it->second << ")";separator = ","; // Separates items with comma
}cout << ']' << endl;
}
Iter findPoint(const Point2d p, PointList& list) {// Return an iterator that references the first point in list that equals p, or list.end()// if no such element. [Better to use find algorithm though – see later.]
Slide # 204COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
// if no such element. [Better to use find algorithm though – see later.]// Iterator isn't const (allowing found item to be modified) so list param can't be constIter it = list.begin();while (it != list.end() && *it != p) {
++it;}return it;
}
pointlist.cpp (cont’d)int main() {Point2d p(1,2);cout << "p = (" << p.first << "," << p.second << ")" << endl;PointList points; // Equiv to Java ArrayList<Point3d> points.printAll(points);printAllWithIterator(points);points.push_back(p); // push_back is an "append" operatorpoints.push_back(Point2d(2,3));points.push_back(Point2d(2,3));points.push_back(Point2d(3,4));points.push_back(Point2d(4,5));printAll(points);printAllWithIterator(points);Iter reqdPointIter = findPoint(Point2d(2,3), points);if (reqdPointIter == points.end()) {
cout << "Reqd point not found." << endl;} else {
points.erase(reqdPointIter);points.erase(reqdPointIter);}printAll(points);printAllWithIterator(points);points.erase(points.begin() + 2); // Delete the item with index [2]printAll(points);printAllWithIterator(points);
}
COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
Points to note
• <utility> defines a pair class
• <vector> defines a vector class• <vector> defines a vector class
– C++’s ArrayList class
• pair class takes types of two components as template
parameters– pair<string, double> someone("Fingers McSnortle", 27.4);
– cout << "(" << someone.first << "," << someone.second << ")";
• pair is a struct i.e., a class with all fields/methods public
Slide # 206COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• pair is a struct i.e., a class with all fields/methods public
– Fields are first and second
• Use typedefs to give new names to such types– typdef pair<string, double> PersonAndAge;
• DEMO: guided tour of vector class.
C/C++
Points to note (cont’d)
• Vector assignment involves deep copying (expensive)
• iterators are essential for use of C++ containers
– Effectively pointers to elements
– Stepped forwards/backwards with ++/-- operators
• For each type vector<T> there is a type vector<T>::iterator
– Like pointer, dereferenced with “*”, e.g. *it
– It’s a subclass called random access iterator
• Allows arithmetic like *(it + 3)
– Can be written as it[3]
Slide # 207COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Can be written as it[3]
• Allows difference computation, e.g. it1 – it2
– Index difference between two items
• There’s also a vector<T>::const_iterator, which doesn’t allow
modification of the referenced collection
C/C++
Points to note (cont’d)
• For all container classes, can iterate over all elements with: for (ContainerType::iterator it = container.begin(); it != container.end()) {
.... do something with element *it ........ do something with element *it ....
}
– Only with random access iterators can you write it < container.end()
• Arithmetic and relational operators not defined for other iterator types
• Can load data from an array into a container with code like:– double data[ ] = {1.5, 2.7, 3.9, 4.6};
– std::vector<double> vecData(&data[0], &data[4]);
Slide # 208COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Possible because there is a constructor that takes two iterators as
parameters and because pointers are accepted as iterators
Number of elements in array
More generally: sizeof(data)/sizeof(double)
C/C++
<algorithm>
• A collection of algorithms like find, max_element, sort.
e.g.e.g.– Iter reqdPointIter = find(points.begin(), points.end(), Point2d(7, 11));
– Point2d furthest = *max_element(points.begin(), points.end(), &furtherOut);
double radiusSquared(Point2d& p) {return p.first*p.first + p.second*p.second;
}
Slide # 209COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
}
bool furtherOut(Point2d& p1, Point2d& p2) {// True iff p2 is further from the origin than p1return radiusSquared(p1) < radiusSquared(p2);
}
C/C++
#include <iostream>#include <string>#include <map> // A “map” is an ordered associative store
mapdemo.cpp
using namespace std;
typedef map<string, int> PhoneBook;typedef PhoneBook::iterator Iter;
int main() {PhoneBook phoneNums; // A map from name (string) to phone number (int)phoneNums["Richard L"] = 7859; // Prettier than using ‘insert’ ☺phoneNums["Brent"] = 7868;
Slide # 210COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
phoneNums["Brent"] = 7868;phoneNums["Mukundan"] = 7770;...phoneNums["Wal"] = 8225;phoneNums["Richard P"] = 7869;
C/C++
cout << "Richard L's number: " << phoneNums["Richard L"] << endl;
Iter curr = phoneNums.find("Richard L"); // Use find if you want an iteratorif (curr != phoneNums.end()) { // ... or if key may not be there
mapdemo.cpp (cont’d)
if (curr != phoneNums.end()) { // ... or if key may not be thereIter prev = curr;Iter next = curr; ++next;--prev;cout << "Previous (in alphabetical order) is " << prev->first << endl;cout << "Next (in alphabetical order) is " << next->first << endl;
}
// Now iterate over all names, in alphabetical order.
Slide # 211COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
cout << endl << endl << "Departmental Phone Numbers" << endl;for (Iter it = phoneNums.begin(); it != phoneNums.end(); ++it) {
cout << it->first << ": " << it->second << endl;}
}
C/C++
19. C++ potpourri
• Exceptions• Exceptions
• Operator overloading
• Templates
Slide # 212COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
Exceptions#include <stdexcept>#include <string>using namespace std;class Stack {public:
class Overflow : public runtime_error { // Exception thrown on stack overflowpublic:
Overflow(const string& message) : runtime_error(message) {}};
Embedded classes
};class Underflow : public runtime_error { // Exception thrown on stack underflowpublic:
Underflow(const string& message) : runtime_error(message) {}};void push(int i) { // Method to push i into the stack
if (stkIndex >= max) {throw Overflow("Stack overflow in 'push' method");
}stk[stkIndex++] = i;
}
Embedded classes
Meth
ods th
rowing ex
ceptions
}int pop() { // Method to return a value popped from the stack
if (stkIndex <= 0) {throw Underflow("Stack underflow in 'pop' method");
}return stk[--stkIndex];
}// Fields, constructors and other methods as before.
}
Meth
ods th
rowing ex
ceptions
C/C++
Notes on exceptions• The class exception is a class in the std namespace.
– Declared in <exception>
• The class runtime_exception is a subclass of exception• The class runtime_exception is a subclass of exception
– Declared in <stdexcept>
• Stack::Overflow is a subclass of runtime_exception
• No need to declare that methods may throw exceptions
– So weaker than Java
• Caller catches exceptions as in Java, e.g.
Slide # 214COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
• Caller catches exceptions as in Java, e.g.
try { ... stuff using stack ...} catch (Stack::Overflow& e) {
printf(“%Exception: %s\n”, e.what());abort();
}
C/C++
auto_ptr
class Thing void f() {
Thing* pThing = new Thing();
Throwing exceptions can lead to memory leaks, e.g. ....
{
public:
Thing() {
cout << "constructing thing" << endl;
}
~Thing() {
cout << "destroying thing" << endl;
Thing* pThing = new Thing();
throw runtime_error("Down we go");
delete pThing; // Never happens!!
}
void main() {
try {
f();
Slide # 215COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
}
};
}
catch (exception e) {
cout << e.what() << endl;
}
}
C/C++
Solution
class Thing void f() {
auto_ptr<Thing> pThing(new Thing());
Use a "smart pointer", e.g. auto_ptr (in <memory>)
{
public:
Thing() {
cout << "constructing thing" << endl;
}
~Thing() {
cout << "destroying thing" << endl;
auto_ptr<Thing> pThing(new Thing());
throw runtime_error("Down we go");
// delete pThing; // Don't need this now!
}
void main() {
try {
f();
Slide # 216COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
}
};
}
catch (exception e) {
cout << e.what() << endl;
}
}
C/C++
Operator overloading
• We can write our own versions of all the standard operators
– + - * / % ^ & | ~ = < > += -= /= *= %= |= <<
>> >>= <<= == != <= >= && ++ -- , ->* ->
() [] new delete new[] delete[]
• Some operate on lvalues (i.e., variables rather than
expressions), e.g. =, <<, += etc.
– Usually implemented as member functions
• Some operate on expressions (e.g. + - *)
Slide # 217COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Usually implemented as global functions
• Advantage: get implicit type conversion on operands
C/C++
Assignment operator overload
Stack& Stack::operator=(const Stack& other) {
delete[ ] stk; // Discard our current "stk" arraydelete[ ] stk; // Discard our current "stk" array
stk = new int[other.max]; // Allocate space for a new one
for (int i = 0; i < other.stkIndex; i++) { // Copy contents of stack across
stk[i] = other.stk[i]; // (or could use memcpy - see lab)
}
max = other.max; // Copy other instance variables
stkIndex = other.stkIndex;
return *this;
Slide # 218COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
}
This is a reference to the current object
C/C++
Global function operator overload
Stack operator+(const Stack& stk1, const Stack& stk2) {
// An operator that returns a new stack containing all the objects of
// stk1 then all the objects of stk2 (!)// stk1 then all the objects of stk2 (!)
Stack result;
for (int i = 0; i < stk1.stkIndex; i++) {
result.push(stk1.stk[i]);
}
for (int i = 0; i < stk2.stkIndex; i++) {
result.push(stk2.stk[i]);
}
return result; // Should have both copy instructor and assignment operator so ...
This is a decidedly
questionable use of the '+'
operator, but at least it uses
classes you're familiar with.
Slide # 219COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
return result; // Should have both copy instructor and assignment operator so ...
// ... caller can copy the returned value into its own local variable
}
• But how can this operator function access the private members
of stk1 and stk2 (e.g. stkIndex)?
C/C++
How to make friends
– Answer (a): by being a friend of the Stack class!• Stack has to explicitly declare its friends, e.g. • Stack has to explicitly declare its friends, e.g.
class Stack {
friend Stack operator+(const Stack& stk1, const Stack& stk2);
int stkIndex;
int *stk;
.
.
etc
}
– Answer (b): by declaring getter methods for any fields
Slide # 220COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
– Answer (b): by declaring getter methods for any fields
that such operators might need.
Style note: don't use friends. Instead, declare getter methods
for any fields that non-member functions need to access
C/C++
templates
template <typename T>
class Stack {
Allow us to have type parameters for classes (like Java 5).
class Stack {
T *stk; // A pointer to the dynamically-allocated stack space
int max; // No. of items of allocated stack space
int stkIndex; // Index of the first free position in the stack
public:
CStack(int stkMax) { // The constructor -- allocate "stkMax" T’s of stack
stk = new T[stkMax]; // Allocate the space
if (stk == NULL) { ... } // Either throw an exception or realloc
max = stkMax; // Define the other instance variables ...
stkIndex = 0; // ... in the usual way.
Slide # 221COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
stkIndex = 0; // ... in the usual way.
}
T pop() { ... etc ... }
void push(T item) { ... etc ... }
}
C/C++
using a template
Stack<int> intStack(100); Stack<char*> stringStack(100);
Again, just like Java 5:
Stack<int> intStack(100);
for (int i = 0; i < 10; i++) {
intStack.push(i);
}
while (!intStack.isEmpty()) {
cout << intStack.pop() << endl;
}
Stack<char*> stringStack(100);
for (int i = 0; i < argc; i++) {
stringStack.push(argv[i]);
while (! stringStack.isEmpty()) {
cout << stringStack.pop() << endl;
}
OR
Slide # 222COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
C/C++
templates (cont'd)
template <typename T>T sum(T data[ ], size_t n) {
T total = 0;
Can also have templated functions, e.g.
This sum function can be used with any
data type that supports += and T total = 0;while (n > 0) {
total += data[--n];}return total;
}
#include <iostream>
int main() {
data type that supports += and
initialisation with a zero.
Templated-function calls don't need an explicit type param
though you can use one if you like, e.g. sum<int>(idata,5)
Slide # 223COSC 208 C & C++ Programming. ©Richard Lobb, 2010.
int main() {int idata[ ] = {1,2,3,4,5};std::cout << "Sum of integers = " << sum(idata, 5) << std::endl;
double ddata[ ] = {123.1, 17.5, -19.9, 11.0};std::cout << "Sum of doubles = " << sum(ddata, 4) << std::endl;
}
C/C++
That’s all, folks!
Slide # 224COSC 208 C & C++ Programming. ©Richard Lobb, 2010.