Transcript eel3801

Fundamentals of C and C++
Programming
Simple data structures
Pointers
Simple Data Structures
Arrays
Structures
Unions
Simple Data Structures
It would be limiting to have to express all
data as variables.
It would be desirable to be able to group
data into sets of related data.
This can be done two main ways:
–arrays (all data of the same type)
–structures (data may be of different types).
EEL 3801 – Lotzi Bölöni
Type Definitions
Special data types designed by the
programmer can be defined through the
typedef keyword.
For example, if we want to define a data
type that is to be defined only once and
then used thereafter:
typedef unsigned long int Myvar
EEL 3801 – Lotzi Bölöni
Type Definitions
So, Myvar can now be used to indicate an
unsigned long int wherever used.
Myvar n;
is the same as:
unsigned long int n;
But it can be used for far more. (later)
EEL 3801 – Lotzi Bölöni
Arrays
Left-most symbol indicates the name of the
array. This is common for all its elements.
Individual data identified by distance from
first one in array.
Within square brackets is the cell number
(how many cells away from the first one).
Individual cells can be used as regular
variables.
EEL 3801 – Lotzi Bölöni
Arrays
For array c:
c[0]
c[1]
-45
6
c[2]
c[3]
c[4]
c[5]
0
72
1543
-89
c[6]
c[7]
c[8]
0
62
-3
EEL 3801 – Lotzi Bölöni
Declaring Arrays
The declaration allows the compiler to set
aside sufficient contiguous memory for
the size of array
The type of data to be stored must be
identified so that sufficient space is
allocated.
Arrays allocated statically - remain the
same size throughout program execution.
EEL 3801 – Lotzi Bölöni
Declaring Arrays
int c[12];
float a[100];
char b[15];
Can be automatic or external.
Size typically done through a macro.
#define SIZE 10
EEL 3801 – Lotzi Bölöni
Initializing Arrays
Not automatically initialized. Can be
initialized during declaration or within the
program in a loop.
int n[10] = {32,27,64,18,95,14,90,70,60};
If more elements than initialized, others = 0.
If less elements than initialized - error.
int n[] = {32,27,64,18,95,14,90,70,60,37};
EEL 3801 – Lotzi Bölöni
Passing Arrays to Functions
Arrays passed by reference - actual variable
address passed. The called function can
modify the original array’s values.
Pass name without brackets.
Include the size of the array as a passed
value.
Function header and prototype must indicate
that an array is being passed.
EEL 3801 – Lotzi Bölöni
Passing Arrays to Functions
#define SIZE 5
void function1(int [],int);
void function2(int);
main()
{
int a[] = {0, 1, 2, 3, 4};
function1(a,SIZE);
function2(a[3]);
}
EEL 3801 – Lotzi Bölöni
Multi-dimension Arrays
Arrays can have an arbitrary number of
dimensions.
Indicated by multiple bracket pairs.
int a[5][10];
int b[10][12][20];
Can be called in same way as vector arrays.
First bracket is the row script
Second is the column script.
EEL 3801 – Lotzi Bölöni
Initializing Multi-dim. Arrays
 Initialization by row in braces.
 First brace equates to first row, 2nd to
2nd,.
int c[2][2] = {{1,2} {3,4}};
 Initializes
b[0][0]=1, b[0][1]=2,
b[1][0]=3, and b[1][1]=4.
 But what if int c[2][2] = {{1} {3,4}};
 Initializes b[0][0]=1, b[0][1]=0 ,
b[1][0]=3, and b[1][1]=4.
EEL 3801 – Lotzi Bölöni
Arrays and Strings
Strings are in reality arrays of characters
Each element contains one character.
Each cell is one byte in size.
More about strings and string operations
later.
EEL 3801 – Lotzi Bölöni
Structures
A collection of related, but dissimilar
variables under one name.
Provides great flexibility that an array does
not.
Used to define records to be stored in files.
Also used to form dynamic data types such
as linked lists, linked stacks and linked
queues.
EEL 3801 – Lotzi Bölöni
Structure Definitions
Declared as follows:
struct planet {
char *name;
int nummoons;
double dist_from_sun;
float dist_from_earth;
};
This creates a definition of the structure.
planet is the structure tag.
EEL 3801 – Lotzi Bölöni
Structures Components
The variables are called members.
They can be accessed individually using:
–The structure member operator (also called the
dot operator).
–The structure pointer operator (also called the
arrow operator).
See Figure 10.2, page 400 of textbook.
EEL 3801 – Lotzi Bölöni
Structure Operators
The dot operator accesses the contents of
the member using the member name and
the structure variable name.
planet.nummoons
directly accesses the contents of the
member nummoons
Can be used as a regular integer variable.
EEL 3801 – Lotzi Bölöni
Structure Operators
The arrow operator accesses the contents of
the member using a pointer to the structure
variable and the member name.
planet_ptr->nummoons
directly points to the contents of the member
nummoons
equal to (*planet_ptr).nummoons
EEL 3801 – Lotzi Bölöni
Structure Variables
The struct keyword defines a “model” of
the desired structure.
It is not a real variable per se.
A real variable is created by creating an
instance of the structure model.
Also referred to as “instantiating”.
EEL 3801 – Lotzi Bölöni
Structure Variables
To make instances of the definition:
–Instance name(s) can be added after the
definition.
–Can be defined as a data type to be instantiated
separately.
–The struct keyword can be used along with
the tag to instantiate.
See examples next.
EEL 3801 – Lotzi Bölöni
Structure Variables
Instances added after the definition:
struct planet {
char *name;
int nummoons;
double dist_from_sun;
float dist_from_earth;
} earth, mars, solar[9], *ptr;
solar[9] is an array of 9 structures of type
planet. ptr is a pointer to a planet type.
EEL 3801 – Lotzi Bölöni
Structure Variables
The tag is optional. The following code is
equivalent to the one in the last slide:
struct {
char *name;
int nummoons;
double dist_from_sun;
float dist_from_earth;
} earth, mars, solar[9], *ptr;
Only way to instantiate is in the definition.
EEL 3801 – Lotzi Bölöni
Structure Variables
Defined as a datatype:
typedef struct planet Planet;
Planet earth, mars;
Planet *ptr;
Planet solar[9];
This assumes that the structure definition
is as before.
EEL 3801 – Lotzi Bölöni
Structure Variables
 Can also be done directly in the
definition:
typedef struct planet
{
char *name;
int nummoons;
double dist_from_sun;
float dist_from_earth;
} Planet;
 The planet tag is not necessary in
this case.
EEL 3801 – Lotzi Bölöni
Structure Variables
The struct keyword can also be used to
instantiate.
struct planet {
char *name;
int nummoons;
double dist_from_sun;
float dist_from_earth;
};
struct planet earth;
EEL 3801 – Lotzi Bölöni
Initializing Structure Members
Like in arrays.
Use values inside braces.
Only when variable being instantiated.
struct planet earth = {earth,1,1.0e+6,0}
If less values than members, then only the
first few are initialized. Others = 0.
Must be constant values or expressions.
EEL 3801 – Lotzi Bölöni
Structures and Functions
Structures can be passed to functions as:
–Individual structure members.
–An entire structure variable.
–Pointer to a structure variable.
Passed by value if the individual structure
member or the entire structure is passed.
Passed by reference if a pointer to the
structure is passed.
EEL 3801 – Lotzi Bölöni
Structures
Arrays can be assigned to a structure
member.
There can be arrays of structures.
Structure members can be other
structures.
Structure members can be selfreferencing structures - pointers that point
to similar structures as itself.
EEL 3801 – Lotzi Bölöni
Unions
Same as structures, except members
share same storage space.
Saves space when some members are
never used at the same time.
Space for a member must be large enough
to accommodate the largest of the data
types to be stored in that member.
EEL 3801 – Lotzi Bölöni
Unions
Unions are declared and defined in a way
similar to structures.
The keyword union replaces the keyword
struct.
Not highly recommended except when
memory management is critical.
EEL 3801 – Lotzi Bölöni
Enumeration Constants
Allows a set of integer constants to be
represented by identifiers.
Symbolic constants whose value can be
set automatically.
Values start with 0 (unless otherwise
noted by programmer) and are
incremented by 1.
Uses the enum keyword for definition.
EEL 3801 – Lotzi Bölöni
Enumeration Example
#include <stdio.h>
enum months {JAN=1, FEB, MAR, APR, MAY,
JUN, JUL, AUG, SEP, ACT, NOV, DEC}
main()
{
enum months month;
char *monthName[] = {“”,
“January”,..};
for(month=JAN;month<=DEC;month++)
printf(……….monthName[month];
}
EEL 3801 – Lotzi Bölöni
Pointers
Pointer Variables
Conventional variables contain values.
Pointer variable contains memory address
of variable that contains values (or
pointers)
Allows call by reference.
Permits creation of dynamic data
structures.
Permits dynamic allocation of memory.
Difficult to understand and use.
EEL 3801 – Lotzi Bölöni
Pointer Variables
Conventional variable names directly
reference a value.
Pointer variables indirectly reference a
value
Referencing a value through a pointer
variable is called indirection.
Pointer variables = pointers
EEL 3801 – Lotzi Bölöni
Declaration of Pointer Variables
Pointers must be declared like regular
variables.
It must be stated which type of variable
they point to.
Declarations use * to indicate
“pointerhood”
int *ptr;
pointer ptr points to an integer variable.
EEL 3801 – Lotzi Bölöni
Pointer Variables
Pointers should be initialized.
The * does not distribute.
Can be set to NULL or to 0, but NULL is
preferred.
NULL is a symbolic constant defined in
<stdio.h>
Pointers assigned a value of 0 actually have
the value 0 and not an address.
EEL 3801 – Lotzi Bölöni
Address-of Pointer Operator
Address-of operator (&) is a unary
operator returning the address of its
operand.
The basic operator used to assign values
to pointers.
int y = 5;
int *ptr;
ptr = &y;
ptr points to y (contains its address).
EEL 3801 – Lotzi Bölöni
Indirection Pointer Operator
Indirection operator (*), or dereferencing
operator is also unary and returns the value
of the variable pointed at by the pointer.
In the previous example:
y = 5
*ptr = 5
Not to be confused with the declaration
operator - very confusing!!!.
EEL 3801 – Lotzi Bölöni
Pointer Example
main()
{
int
a;
int
*aptr;
a = 7;
aptr = &a;
printf(“The address of a =%d“,&a);
printf(“The value of aptr =%d“,
aptr);
printf(“The value of a = %d“,
*aptr);
}
EEL 3801 – Lotzi Bölöni
Call by Reference with Pointers
By passing a variable’s address to a
function, we give that function the ability
to modify the value of the original value.
This is a simulation of call by reference.
EEL 3801 – Lotzi Bölöni
Call by Value - Example
void value_funct1(int);
main()
{
int number = 5;
printf(“Original value =“, number);
value_funct(number);
printf(“New value =“, number);
}
void value_funct(int n);
{
n = n * n;
}
EEL 3801 – Lotzi Bölöni
Call by Value - Example
Original value = 5
New value = 5
The call to function value_funct did not
change the original variable number in
main().
EEL 3801 – Lotzi Bölöni
Call by Reference - Example
void value_funct2(int *);
main()
{
int number = 5;
printf(“Original value =“, number);
value_funct(&number);
printf(“New value =“, number);
}
void value_funct(int *nptr);
{
(*nptr) = (*nptr) * (*nptr);
}
EEL 3801 – Lotzi Bölöni
Call by Reference - Example
Original value = 5
New value = 25
The call to function value_funct
changed the original variable number in
main().
A similar effect can be obtained by
value_funct returning a value to main()
EEL 3801 – Lotzi Bölöni
Functions Returning Pointers
Functions can also return pointers to
variables.
int* function1(int, int);
is the prototype for a function that returns
a pointer to an integer variable.
Is easily done by simply returning the
value of a pointer variable - an address.
EEL 3801 – Lotzi Bölöni
The const and Pointer Passing
The const qualifier tells the compiler that
the variable following it is not to be
changed by any program statements.
Provides a measure of security when
passing addresses of variables whose
values are not to be modified (for
example, arrays).
When passing pointers, 4 possibilities
exist:
EEL 3801 – Lotzi Bölöni
Pointer Passing
Non-constant pointer to non-constant data
–Declaration does not include const in any way.
–Data can be modified through the pointer.
–Pointer can be modified to point to other data.
Highest level of data access to called
function.
This is what we have been doing up to
now.
EEL 3801 – Lotzi Bölöni
Pointer Passing
Non-constant pointer to constant data:
–Pointer can be modified to point to any data.
–Data that it points to cannot be modified
–May be used to protect the contents of a
passed array.
–Read as “a is a pointer to an integer constant”
void funct(const int *a)
EEL 3801 – Lotzi Bölöni
Pointer Passing
Constant pointer to non-constant data:
–Pointer always points to same memory
location.
–Data that it points to can be modified.
–Default value for a passed array.
–Pointer must be initialized when declared.
–Read “aptr is a constant pointer to an integer ”
int x;
int * const aptr = &x;
EEL 3801 – Lotzi Bölöni
Pointer Passing
Constant pointer to constant data:
–Pointer always points to same memory
location.
–Data that it points to cannot be modified.
–Read “aptr is a constant pointer to an integer
constant” - right to left
int x = 5;
const int* const aptr = &x;
EEL 3801 – Lotzi Bölöni
Pointer Arithmetic
Pointers are valid operands in
mathematical operations, assignment
expressions and comparison operations.
But not all operators are valid with
pointers.
Operators that are do not always work the
same way.
EEL 3801 – Lotzi Bölöni
Pointer Arithmetic
A pointer can be incremented (++).
A pointer can be decremented (--).
An integer may be added to, or subtracted
from a pointer (+, +=, -, -=).
One pointer may be subtracted from
another.
But this can be misleading.
EEL 3801 – Lotzi Bölöni
Pointer Arithmetic
When adding integers to pointers, the
value of the integer added is the number
of memory elements to be moved.
The actual answer depends on the type of
memory element being pointed to by the
pointer.
Assuming int = 4 bytes (32 bits):
EEL 3801 – Lotzi Bölöni
Pointer Arithmetic
int *yptr = 3000;
yptr += 2;
In reality, yptr = 3008, because 2*4=8 bytes.
In other words, the pointer moved two
integer data “spaces” away from its original
address.
Since an integer data space is 4 bytes, it
moved 8 bytes.
EEL 3801 – Lotzi Bölöni
Pointer Arithmetic
Since character variables are 1 byte in
size, the arithmetic will be normal for
pointers that point to characters.
The ++ and -- operators work the same
way.
They add one data space to the address.
int *ptr = 3000;
ptr++;
ptr = 3004, assuming integer takes 4
bytes.
EEL 3801 – Lotzi Bölöni
Pointer Arithmetic
Subtraction works the same way.
int x;
x = v1ptr - v2ptr;
where v1ptr=3008 and v2ptr=3000;
==> x = 2 if int is 4 bytes.
EEL 3801 – Lotzi Bölöni
Pointers and Arrays
The name of an array is in reality a pointer
to its first element.
Thus, for array a[] with, for instance, 10
elements, a = &(a[0]).
This is why when an array is passed to a
function, its address is passed and it
constitutes call by reference.
EEL 3801 – Lotzi Bölöni
Pointers and Arrays
a[3] can be also referenced as *(a+3).
The 3 is called the offset to the pointer.
Parenthesis needed because precedence
of * is higher than that of +.
Would be a[0]+3 otherwise.
a+3 could be written as &a[3].
See Fig. 7.20, page 284 in textbook.
EEL 3801 – Lotzi Bölöni
Pointers and Arrays
The array name itself can be used directly
in pointer arithmetic as seen before.
Pointer arithmetic is meaningless outside
of arrays.
You cannot assume that a variable of the
same type will be next to a variable in
memory.
EEL 3801 – Lotzi Bölöni
Pointers and Strings
Strings are really pointers to the first
element of a character array.
Array is one character longer than the
number of elements between the quotes.
The last element is “\0” (the character with
the ASCII code zero).
EEL 3801 – Lotzi Bölöni
Arrays of Pointers
Arrays may contain nearly any type of
variable.
This includes pointers.
Could be used to store a set of strings.
char *suit[4] = {“hearts”, “diamonds”, “spades”,
“clubs”};
The char * says that the elements of the
array are pointers to char.
EEL 3801 – Lotzi Bölöni
Arrays of Pointers
Suit[0]
H
e a
r
t
s
\0
Suit[1]
D
i
a
m o
n
d
Suit[2]
C
l
u
b
\0
Suit[3]
S
p a d e s \0
s
s
\0
EEL 3801 – Lotzi Bölöni
Pointers to Functions
Contains address of the function in
memory.
This is now addressing the code segment.
Can be
–passed to functions
–returned from functions
–stored in arrays
–assigned to other function pointers
EEL 3801 – Lotzi Bölöni
Pointers to Functions
Pointer contains the address of the first
instruction that pertains to that function.
Commonly used in menu-driven systems,
where the choice made can result in
calling different functions.
Two examples follow:
EEL 3801 – Lotzi Bölöni
Example 1
Writing a sorting program that orders an
array of integers either in ascending or
descending order.
main() asks the user whether ascending or
descending order, then calls the sorting
function with the array name, its size and
the appropriate function (ascending or
descending).
See Fig. 7-26, page 292 in textbook.
EEL 3801 – Lotzi Bölöni
Example 1 - continued
int ascending(int,int);
int descending(int,int);
void sort(int *, const int,
int (*)(int,int));
main()
{
. . .
sort(array,10,ascending); or
sort(array,10,descending);
. . .
}
EEL 3801 – Lotzi Bölöni
Example 1 - continued
void sort(int *arr, const int size, int
(*compare_func) (int, int));
{
if ((*compare_func)(arr[i], arr[i+1]))
do something;
}
int ascending(const int a, const int b)
{
return b < a;
}
EEL 3801 – Lotzi Bölöni
Example 1 - continued
main() calls sort() and passes to it the
array, its size, and the function to be used.
sort() receives the function and calls it
under a pointer variable compare_func,
with two arguments.
The arguments are elements of the array,
arr[i] and arr[i+1].
compare_func returns 1 if true,0 if false.
EEL 3801 – Lotzi Bölöni
Example 2
Functions are sometimes represented as an
array of pointers to functions.
The functions themselves are defined as
they would normally.
An array of pointers is declared that
contains the function names in its elements.
Functions can be called by dereferencing a
pointer to the appropriate cell.
EEL 3801 – Lotzi Bölöni
Example 2 - continued
void function1(int);
void function2(int);
void function3(int);
main()
{
void (*f[3])(int) = {function1,
function2, function3};
}
 “f is an array of 3 pointers to
functions that take an int as an
argument and return void”
EEL 3801 – Lotzi Bölöni
Example 2 - continued
Such functions can be called as follows:
(*f[choice]) (choice));
Can be interpreted as calling the contents of
the address located in the choice cell of
array f, with an argument equal to the value
of the integer variable choice.
The parenthesis enforce the desired
precedence.
EEL 3801 – Lotzi Bölöni
Double Pointers
Double pointers are commonly used when
a call by reference is desired, and the
variable to be modified is itself a pointer.
A double pointer is a pointer to a pointer
to a variable of a particular type.
Declared as
int **ptr
Read as a pointer to a pointer to an
integer.
EEL 3801 – Lotzi Bölöni
Double Pointers
ptr
int
EEL 3801 – Lotzi Bölöni
Double Pointers
Deferencing a double pointer results in an
address.
Derefencing it again results in the value of
the ultimate variable
var = *(*dbl_ptr);
EEL 3801 – Lotzi Bölöni
Memory Allocation
Static Memory Allocation
Variables declared at compile time (in the
source code) are called static variables.
It is necessary to know how many of these
variables will be necessary prior to
compilation.
They cannot be undeclared (other than by
functions exiting).
Easy to use but are not very flexible.
EEL 3801 – Lotzi Bölöni
Static Memory Allocation
Advantages:
–System does not run out of memory
–Easy to keep track of them
–Can be referenced directly by the variable name
–Limited to size of data segment in machine
Disadvantages
–Must know required amount at compile time
–Cannot be generated at run time
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
Addresses the disadvantages of static
memory.
–Only limited by the amount of memory in
machine, not by pre-determined size of array.
–Can be created and deleted at runtime.
–Can result in memory leaks.
–Harder to keep track of the variables
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
The C function call malloc() creates a
block of memory of the size and shape
designated by the call.
Its argument is the size of the desired block.
Returns a pointer of type void * which
points to the block of memory.
Returns a NULL pointer if memory not
sufficient.
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
Uses the sizeof() operator to determine
the size of the data type to be represented
by the newly allocated block of memory.
The call to malloc() should be cast so as
to force the pointer returned to be of the
proper type - but not necessary.
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
Good idea to always use the sizeof()
operator, even though technically, you can
simply place a number there. This
increases portability.
Memory block can be returned to the free
memory heap by using the
free()function
free(ptr);
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
Dynamically allocated memory can only be
“found” through its pointer.
Pointer must be cast to its correct data type.
Cannot be referenced any other way.
Typically used with structures and unions.
Thus, arrow operator becomes important in
dynamically allocated structures.
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
Arrays are static variables.
But can also be dynamically created.
Use the calloc() function call for arrays.
Requires two arguments:
–the number of elements in the array
–the size of each element in the array
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
calloc() also returns a pointer to the
first element of the array.
Can be scripted just like a regular array.
Must be deleted when no longer needed.
Cannot be extended at run time.
But its element size can be changed.
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
realloc() allows the modification of the
size of a memory block previously allocated
through malloc() or calloc().
Will keep data intact if size is larger.
Otherwise, it will become corrupted.
Requires two arguments:
–Name of pointer to block to be re-allocated.
–New size of the memory element.
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
In C++, it is somewhat easier:
–the new operator takes as an argument the data
type name - new <data type name>
–returns a pointer of the correct type to a block
of memory of the correct size (does not need
sizeof(datatype) ).
–delete <pointer name> de-allocates the
memory block and returns it to heap.
EEL 3801 – Lotzi Bölöni
Dynamic Memory Allocation
new also used to dynamically allocate arrays.
delete also used to de-allocate arrays, but
empty brackets are needed.
delete can only be used to delete memory
allocated with new.
Do not mix and match malloc(), free(),
new and delete.
EEL 3801 – Lotzi Bölöni
Example
typedef struct name_tag {
int blah;
float blah_blah;
} Typename;
Typename *ptr;
ptr = (Typename *)
malloc(sizeof(Typename));
ptr->blah = 2;
.
.
free(ptr);
EEL 3801 – Lotzi Bölöni
Example
typedef struct name_tag {
int blah;
float blah_blah;
} Typename;
Typename *ptr;
ptr = (Typename *)
calloc(20,sizeof(Typename));
ptr[12]->blah = 10;
free(ptr);
EEL 3801 – Lotzi Bölöni
Example
typedef struct name_tag {
int blah;
float blah_blah;
} Typename;
Typename *ptr;
ptr = new Typename;
ptr->blah = 23;
.
.
delete ptr;
EEL 3801 – Lotzi Bölöni
Example
typedef struct name_tag {
int blah;
float blah_blah;
} Typename;
Typename *ptr;
ptr = new Typename[20];
ptr[15]->blah = 19;
.
delete [] ptr;
EEL 3801 – Lotzi Bölöni