You are on page 1of 34

COMP2006

C++ Programming
Lecture 2
Dr Chao Chen

1
Development Environment Comments
• You can use any development environment you want
• You can use Linux or Mac if you prefer
– As long as you are happy to install and support the environment
yourself – e.g. something you are familiar with?
– For the coursework I’ll give you some Linux and Mac information
which should get you started
– I use a library which has Linux and Mac support too so the code
should ‘just compile’ (unless something changed from last year)
• Windows virtual desktop should work for you and avoid
installing Visual Studio yourself
• You can install visual studio yourself
https://azureforeducation.microsoft.com/devtools

2
This lecture
• Data types
– C/C++ similarities and differences

• Pointers
– Address of
– Dereferencing
• Arrays
• C-type Strings

3
Data types

4
bool type (C++ only, not C)
• bool : true/false
• Similar to java’s boolean type
• Boolean expressions (e.g. many conditions)
have results of type ‘bool’ in C++
– But type int in C – a subtle difference
• IMPORTANT: bool and int can be converted
implicitly / automatically to each other
– i.e. C++ is backward compatible with C
– true defined to be 1 when converted to int
– false defined to be 0 when converted to int
– 0 is defined to be false
– non-zero is defined to be true 5
ints and bools
• In both C and C++ any integer types can be used in
conditions (i.e. char, short, long, int)
– In C++ the value is silently converted to a C++ bool type
• When using integer types:
– true is equivalent to non-zero (or 1), false is equivalent to zero
• Example:
int x = 6;
while ( x )
{
printf( "X is %d\n", x );
x -= 2;
}
• In Java this would be an error : “x not boolean”
• In C/C++ this is valid ( it means ‘while( x != 0 )’ ) 6
Sizes of types…
• The size of types (in bits/bytes) can vary in C/C++
– For different compilers/operating systems
– In Java, sizes are standardised, across O/Ss
• Some guarantees are given:
– A minimum size (bits): char 8, short 16, long 32
– Relative sizes: char ≤ short ≤ int ≤ long
• An int changes size more than other types!
– Used for speed (not portability), but VERY popular! (fast)
– Uses the most efficient size for the platform
– 16 bit operating systems usually use 16 bit int
– 32 bit operating systems usually use 32 bit int
– 64 bit operating systems usually use 64 bit int
• sizeof() operator exists to tell us the size (in chars)
7
Basic Data Types - Summary
Type Minimum Minimum range of values
size (bits) (Depends upon the size on your platform)
char 8 -128 to 127 (or 0-255 : implementation defined)
(WARNING: Java ‘byte’. Java char is 16 bit!)
short 16 -32768 to 32767
long 32 -2147483648 to 2147483647

float Often 32 Single precision (implementation defined)


e.g. 23 bit mantissa, 8 bit exponent
double Often 64 Double precision (implementation defined)
e.g. 52 bit mantissa, 11 bit exponent
long double ≥ double Extended precision, implementation defined
int ≥ short varies

8
signed/unsigned values
• Signed/unsigned variants of integer types
– Unlike in Java where they are fixed
– Examples:
signed char sc; unsigned short us;
signed long sl; unsigned int ui;
– Default is signed (except for char)
• If neither ‘signed’ nor ‘unsigned’ is stated
• Default for char is compiler-dependent
– Note: Using ‘signed char’ or ‘unsigned char’
removes the ambiguity of the range for char
9
wchar_t type
• wchar_t : wide character
– Like a Java ‘char’
• ASCII limited to values 0 to 127 (7 bits)
– Not enough characters for some languages
• wchar_t is designed to be big enough to
hold a character of the : “largest character
set supported by the implementation’s
locale”
(Bjarne Stroustrup, The C++ Programming Language)
• Use L'a' or L"hello" for wide character/string literals
10
The void type

• The void type is used to mean:


– No return value
• e.g. void foo( int a );
– No parameters, optional (Not Java)
• e.g. int bar(void);
– Undefined pointer type: void*
• Cast it to the correct type to use it
• You cannot create a variable of type ‘void’
• Some (older) compilers may not accept void
– But they should do if they are C89/C90/C99
const – more later on this
• More on const later, but for the moment…
• ‘const’ means constant/unchangeable
– ‘final’ serves this purpose in Java
– e.g. const int k = 6;
k = 6; // Error!

• Important: use const char * instead of char*


– Pointers can specify that they cannot be used to
change the thing they point at – a ‘constant char’ *
– You should not change string literals, so use const
const char* p = "Hello";
12
auto
• The auto type is really useful
– Allows you to be lazy (don’t bother about type)
– Very useful later as we will see
• New to C++11
– older compilers will not support it
• Can only be used for initialised variables
– Compiler will work out the type at compile
time from the type of the initialisation value
• E.g. auto str = "Hello World";
• The type is still fixed!!! (Not like Python!) 13
Other types
• Some platforms (notably Microsoft Windows) have
platform specific types. E.g.:
– WORD = 16 bit value
– DWORD = 32 bit value
– __int8, __int16, __int32, __int64 (double _ _ at start)
– Many other platform specific data types
• Using these has advantages (portability across versions
of that platform) and disadvantages (may need to do
some #defines to port to other platforms)
• You can also create your own types:
– typedef <oldtype> <newname>
– E.g. typedef unsigned int DWORD32
– Or typedef float FLOAT
14
Pointers

15
Variables

#include <cstdio>

int main(int argc, char* argv[])


{
int i = 4;
const char* s = "String";
printf("%d %s\n", i, s);
return 0;
}
16
Variables: size and location
Every variable has:
A name In your program only (not at runtime!)
A type In program, determines layout in memory
A size Number of bytes it takes up at runtime ( sizeof )
An address Location in memory at runtime ( & )
A value The number(s) actually stored at runtime

• We can ask for the address of a variable


– Use the & operator in C/C++
• We can ask for the size (in chars) – compile time
– Use the sizeof() operator (on variable or type)
• We can ask for the value (runtime)
– Just use the variable name 17
Pointers
• * is used to denote a pointer
– i.e. a variable which will hold the address of some other variable
• Examples:
char* a pointer to a char
int* a pointer to an int
void* a generic pointer, address of some data of unknown type
(or a ‘generic’ address)
char** a pointer to a char*
long*** a pointer to a long**

• Remember two things about pointers:


1. The value of the pointer is an address in memory
2. The type of the pointer says what type of data the
program should expect to find at the address
• Type and value are completely different things!
18
The concept of a pointer

Conceptually:
Value of variable
‘pointer’ is the
pointer variable
address of variable
<&variable> 345639 ‘variable’

pointer points to/at the variable

• You can think of pointers whichever way


is easier for you
1. As an address in memory and a type/format
2. As a way of pointing to some other data,
and a record of what type of data you think
the thing pointed at is 19
Pointer example
short s = 965;
short* ps1 = &s;
short* ps2 = ps1;
• Q: What goes into the red circled parts?

Conceptually: Actually: (example addresses)


ps1 s Address Name Value
3000 s
5232 ps1
ps2 6044 ps2

20
Pointer example
short s = 965;
short* ps1 = &s;
short* ps2 = ps1;
• Q: What goes into the red circled parts?

Conceptually: Actually: (example addresses)


ps1 s Address Name Value
965 3000 s 965
5232 ps1
ps2 6044 ps2

21
Pointer example
short s = 965;
short* ps1 = &s;
short* ps2 = ps1;
• Q: What goes into the red circled parts?

Conceptually: Actually: (example addresses)


ps1 s Address Name Value
3000 965 3000 s 965
5232 ps1 3000
ps2 6044 ps2

22
Pointer example
short s = 965;
short* ps1 = &s;
short* ps2 = ps1;
• So, assigning one pointer to another means:
– It points at the same object
– It has the same address stored in it (i.e. the same value)

Conceptually: Actually: (example addresses)


ps1 s Address Name Value
3000 965 3000 s 965
5232 ps1 3000
ps2 6044 ps2 3000
3000
23
Dereferencing operator : *
• The * operator is used to access the ‘thing’ that a
pointer points at
• For example: define a char and char*
char c1 = 'h';
char* pc = &c1; // pc is a pointer to c1
• Ask for the value of the thing pc points at
char c3 = *pc; // *pc is thing pointed at
• Thinking in terms of pointers holding addresses…
– pc is a char*, so it is the address of a char
– *pc is the char pointed at, i.e. value of c1!
– So, *pc is (now) another name for c1 24
Dereferencing example
short s1 = 965;
short* ps1 = &s1;
short* ps2 = ps1;
short s2 = *ps2;
• What goes into the red circled parts?
– Hint: What is *ps2?

Conceptually: Actually: (example addresses)


ps1 s1 Address Name Value
3000 965 3000 s1 965
5232 ps1 3000
ps2 s2 6044 ps2 3000
3000 6134 s2
25
Dereferencing example
short s1 = 965;
short* ps1 = &s1;
short* ps2 = ps1;
short s2 = *ps2;
• So, we can access (use) the value of s1 without using its
variable name

Conceptually: Actually: (example addresses)


ps1 s1 Address Name Value
3000 965 3000 s1 965
5232 ps1 3000
ps2 s2 6044 ps2 3000
3000 965 6134 s2 965
26
Dereferencing example
short s1 = 965;
short* ps1 = &s1;
short* ps2 = ps1;
short s2 = *ps2;
*ps1 = 4; Q: What does this do?

Conceptually: Actually: (example addresses)


ps1 s1 Address Name Value
3000 965 3000 s1 965
5232 ps1 3000
ps2 s2 6044 ps2 3000
3000 965 6134 s2 965
27
Dereferencing example
• ‘*ps1 = 4’ changes the value pointed at by ps1
• We can change the thing pointed at without
knowing what variable the address actually refers
to (just ‘change the value at this address’)
• The value of s1 changed without us mentioning s1
Conceptually: Actually: (example addresses)
ps1 s1 Address Name Value
3000 4 3000 s1 4
5232 ps1 3000
ps2 s2 6044 ps2 3000
3000 965 6134 s2 965
28
Uninitialised Pointers
• In C and C++, variables are NOT initialised
unless you give them an initial value
• Unless you initialise them, the value of a
pointer is undefined
– Always initialise all variables, including pointers
– You can use NULL (or nullptr in c++)
• Dereferencing an unitialised pointer has
undefined results
– Could crash your program (likely)
– Could crash your computer (less likely)
– Could wipe your hard drive? (unlikely) 29
Passing pointers as
parameters

30
Parameters can be pointers
First parameter Second parameter
is an int is a pointer

int myfunction( int i, char* str )


{ You could alter
str[1] = ‘h’; the char or string
return i+1; that it points at
}

• Each parameter has a single type, so may be one ‘thing’


• A copy of the ‘thing’ is stored in the memory for the parameter
– i.e. the function gets its own copy! Of variable (incl pointer), literal, …
• To alter something that is external to a function from within a function,
you need to refer to the thing itself, not a copy of it:
– Easy way is to pass a pointer to it
– A copy of a pointer will point to the same thing
– i.e. It will copy the address rather than the thing pointed at
– Thus you can change the thing at that address 31
Example: pointer parameter
void AlterCopy( int icopy )
{
icopy = 2;
}

void AlterValue( int* picopy )


{
*picopy = 3;
}

int main( int argc, char* argv[] )


{
int i = 1;
printf( "Initial value of i is %d\n", i );
AlterCopy( i );
printf( "After AlterCopy, value of i is %d\n", i );
AlterValue( &i );
printf( "After AlterValue, value of i is %d\n", i );
return 0;
} 33
Other things…
• Return values
– Return values work similarly
– Returning a pointer will copy the address
– Returning a value will copy the value
• Passing or returning objects (more later!)
– A copy of the object is created
– Unless you pass/return a pointer
– Java object references work like pointers
• We will see references later – work like
pointers but look like normal variables
– Ignore these for the moment 34
Next Lecture
• Arrays and layout in memory
• Pointer Arithmetic
• String functions and simple
implementations

35

You might also like