Title: Fundamentals of C and C Programming Simple data structures Pointers
1Fundamentals of C and C ProgrammingSimple
data structuresPointers
2Simple Data Structures
3Simple 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).
4Type 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
5Type 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)
6Arrays
- 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.
7Arrays
For array c
-45
c0
6
c1
0
c2
72
c3
1543
c4
-89
c5
0
c6
62
c7
-3
c8
8Declaring 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.
9Declaring Arrays
- int c12
- float a100
- char b15
- Can be automatic or external.
- Size typically done through a macro.
- define SIZE 10
10Initializing Arrays
- Not automatically initialized. Can be
initialized during declaration or within the
program in a loop. - int n10 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
11Passing Arrays to Functions
- Arrays passed by reference - actual variable
address passed. The called function can modify
the original arrays 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.
12Passing 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(a3)
-
13Multi-dimension Arrays
- Arrays can have an arbitrary number of
dimensions. - Indicated by multiple bracket pairs.
- int a510
- int b101220
- Can be called in same way as vector arrays.
- First bracket is the row script
- Second is the column script.
14Initializing Multi-dim. Arrays
- Initialization by row in braces.
- First brace equates to first row, 2nd to 2nd,.
- int c22 1,2 3,4
- Initializes b001, b012, b103, and
b114. - But what if int c22 1 3,4
- Initializes b001, b010 , b103,
and b114.
15Arrays 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.
16Structures
- 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.
17Structure 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.
18Structures 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.
19Structure 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.
20Structure Operators
- The arrow operator accesses the contents of the
member using a pointer to the structure variable
and the member name. - planet_ptr-gtnummoons
- directly points to the contents of the member
nummoons - equal to (planet_ptr).nummoons
21Structure 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.
22Structure 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.
23Structure Variables
- Instances added after the definition
- struct planet
- char name
- int nummoons
- double dist_from_sun
- float dist_from_earth
- earth, mars, solar9, ptr
- solar9 is an array of 9 structures of type
planet. ptr is a pointer to a planet type.
24Structure 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, solar9, ptr
- Only way to instantiate is in the definition.
25Structure Variables
- Defined as a datatype
- typedef struct planet Planet
- Planet earth, mars
- Planet ptr
- Planet solar9
- This assumes that the structure definition is as
before.
26Structure 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.
27Structure 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
28Initializing Structure Members
- Like in arrays.
- Use values inside braces.
- Only when variable being instantiated.
- struct planet earth earth,1,1.0e6,0
- If less values than members, then only the first
few are initialized. Others 0. - Must be constant values or expressions.
29Structures 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.
30Structures
- Arrays can be assigned to a structure member.
- There can be arrays of structures.
- Structure members can be other structures.
- Structure members can be self-referencing
structures - pointers that point to similar
structures as itself.
31Unions
- 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.
32Unions
- 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.
33Enumeration 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.
34Enumeration Example
- include ltstdio.hgt
- enum months JAN1, FEB, MAR, APR, MAY, JUN, JUL,
AUG, SEP, ACT, NOV, DEC - main()
-
- enum months month
- char monthName , January,..
- for(monthJANmonthltDECmonth)
- printf(.monthNamemonth
35Pointers
36Pointer 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.
37Pointer 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
38Declaration 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.
39Pointer 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 ltstdio.hgt
- Pointers assigned a value of 0 actually have the
value 0 and not an address.
40Address-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).
41Indirection 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!!!.
42Pointer 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)
-
43Call by Reference with Pointers
- By passing a variables 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.
44Call 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
-
45Call by Value - Example
- Original value 5
- New value 5
- The call to function value_funct did not change
the original variable number in main().
46Call 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)
-
47Call 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()
48Functions 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.
49The 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
50Pointer 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.
51Pointer 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)
52Pointer 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
53Pointer 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
54Pointer 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.
55Pointer 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.
56Pointer 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)
57Pointer Arithmetic
- int yptr 3000
- yptr 2
- In reality, yptr 3008, because 248 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.
58Pointer 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.
59Pointer Arithmetic
- Subtraction works the same way.
- int x
- x v1ptr - v2ptr
- where v1ptr3008 and v2ptr3000
- gt x 2 if int is 4 bytes.
60Pointers 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 (a0). - This is why when an array is passed to a
function, its address is passed and it
constitutes call by reference.
61Pointers and Arrays
- a3 can be also referenced as (a3).
- The 3 is called the offset to the pointer.
- Parenthesis needed because precedence of is
higher than that of . - Would be a03 otherwise.
- a3 could be written as a3.
- See Fig. 7.20, page 284 in textbook.
62Pointers 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.
63Pointers 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).
64Arrays of Pointers
- Arrays may contain nearly any type of variable.
- This includes pointers.
- Could be used to store a set of strings.
- char suit4 hearts, diamonds, spades,
clubs - The char says that the elements of the array
are pointers to char.
65Arrays of Pointers
H e a r t s \0
Suit0
D i a m o n d s \0
Suit1
C l u b s \0
Suit2
S p a d e s \0
Suit3
66Pointers 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
67Pointers 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
68Example 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.
69Example 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)
- . . .
-
70Example 1 - continued
- void sort(int arr, const int size, int
(compare_func) (int, int)) -
- if ((compare_func)(arri, arri1))
- do something
-
- int ascending(const int a, const int b)
-
- return b lt a
-
71Example 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, arri
and arri1. - compare_func returns 1 if true,0 if false.
72Example 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.
73Example 2 - continued
- void function1(int)
- void function2(int)
- void function3(int)
- main()
-
- void (f3)(int) function1, function2,
function3 -
- f is an array of 3 pointers to functions that
take an int as an argument and return void
74Example 2 - continued
- Such functions can be called as follows
- (fchoice) (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.
75Double 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.
76Double Pointers
ptr
int
77Double Pointers
- Deferencing a double pointer results in an
address. - Derefencing it again results in the value of the
ultimate variable - var (dbl_ptr)
78Memory Allocation
79Static 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.
80Static 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
81Dynamic 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
82Dynamic 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.
83Dynamic 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.
84Dynamic 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)
85Dynamic 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.
86Dynamic 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
87Dynamic 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.
88Dynamic 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.
89Dynamic Memory Allocation
- In C, it is somewhat easier
- the new operator takes as an argument the data
type name - new ltdata type namegt - returns a pointer of the correct type to a block
of memory of the correct size (does not need
sizeof(datatype) ). - delete ltpointer namegt de-allocates the memory
block and returns it to heap.
90Dynamic 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.
91Example
- typedef struct name_tag
- int blah
- float blah_blah
- Typename
- Typename ptr
- ptr (Typename ) malloc(sizeof(Typename))
- ptr-gtblah 2
- .
- .
- free(ptr)
92Example
- typedef struct name_tag
- int blah
- float blah_blah
- Typename
- Typename ptr
- ptr (Typename ) calloc(20,sizeof(Typename))
- ptr12-gtblah 10
- free(ptr)
93Example
- typedef struct name_tag
- int blah
- float blah_blah
- Typename
- Typename ptr
- ptr new Typename
- ptr-gtblah 23
- .
- .
- delete ptr
94Example
- typedef struct name_tag
- int blah
- float blah_blah
- Typename
- Typename ptr
- ptr new Typename20
- ptr15-gtblah 19
- .
- delete ptr