Microsoft PowerPoint – 10_Function_header_PtrFunctions.pptx
1
CS 2211
System Programming
Part Nine (a): Header Files
1
FILES main.c
#include
int main(int argc, char *argv[])
{
int x,y,d,r;
float rT;
x=9;
y=2;
if (denominator < 1)
return(-1);
d=numerator/denominator;
r=numerator%denominator;
rT = ( (float)numerator/ (float)denominator);
printf("%d/%d = %d with %d remainder\n",x,y,d,r);
printf("%d/%d = %f ",x,rT);
}
FILES main.c
#include
int main(int argc, char *argv[])
{
int x,y,d,r;
float rT;
x=9;
y=2;
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
}
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
FILES main.c
#include
int main(int argc, char *argv[])
{
int x,y,d,r;
float rT;
x=9;
y=2;
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
}
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
goal:
break this down into a
main program
and all other functions in
separate files
1 2
3 4
2
FILES main.c
#include
int main(int argc, char *argv[])
{
int x,y,d,r;
float rT;
x=9;
y=2;
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
}
functions.c
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
FILES main.c
#include
int main(int argc, char *argv[])
{
int x,y,d,r;
float rT;
x=9;
y=2;
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
}
functions.c
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
error:
code will compile and run
but !
the answer will be incorrect.
preprocessor does not ‘know’ the return
type of the function division
so
it assigns the default of type int
running this code will return a value of
4.0000000
for rT (based on integer not floating point)
FILES main.c
#include
int main(int argc, char *argv[])
{
int x,y,d,r;
float rT;
x=9;
y=2;
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
}
functions.c
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
error:
code will compile and run
but !
the answer will be incorrect.
preprocessor does not ‘know’ the return
type of the function division
so
it assigns the default of type int
running this code will return a value of
4.0000000
for rT (based on integer not floating point)
must ‘prototype’ the function so the
preprocessor knows what to expect as a
return type
FILES main.c
#include
float division(int , int , int* , int*);
int main(int argc, char *argv[])
{
int x,y,d,r;
float rT;
x=9;
y=2;
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
}
functions.cfloat division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
warning:
the prototype MUST end with a semicolon
5 6
7 8
3
FILES main.c
#include
float division(int , int , int* , int*);
int main(int argc, char *argv[])
{
int x,y,d,r;
float rT;
x=9;
y=2;
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
}
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
functions.c
the list of prototype can get very large and
confusing.
solution:
create a header file
and in this file place
prototypes
macro definitions (#define)
data type definitions
variable definitions
FILES main.c
#include
#include “prog1.h”
int main(int argc, char *argv[])
{
int x,y,d,r;
// float rT; // make this a global variable
x=9;
y=2;
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
}
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
functions.c
#ifndef PROG1_H_INCLUDED
#define PROG1_H_INCLUDED
float rT;
float division(int , int , int* , int*);
#endif // PROG1_H_INCLUDED
prog1.h
FILES main.c
#include
#include “prog1.h”
int main(int argc, char *argv[])
{
int d,r;
// float rT; // make this a global variable
NUMB x, y;
x=9;
y=2;
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
}
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
functions.c
#ifndef PROG1_H_INCLUDED
#define PROG1_H_INCLUDED
#define NUMB int
float rT;
float division(int , int , int* , int*);
#endif // PROG1_H_INCLUDED
prog1.h
FILES main.c
#include
#include “mainHeader.h”
int main() {
NUMB x, y, d, r;
x=9;
y=2;
printf(“address of d: %p\n”,&d);
printf(“address of r: %p\n”,&r);
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
printf(“rT=%f\n”,rT);
}
functions.hfloat division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
9 10
11 12
4
functions.h
#include
#include “mainHeader.h”
int main() {
NUMB x, y, d, r;
x=9;
y=2;
printf(“address of d: %p\n”,&d);
printf(“address of r: %p\n”,&r);
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
printf(“rT=%f\n”,rT);
}
FILES main.c
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
#ifndef dH
#define dH
#define NUMB int
float rT;
float division(int , int , int* , int*);
#endif // dH
definitionsHeader.h
functions.h
#include
#include “mainHeader.h”
int main() {
NUMB x, y, d, r;
x=9;
y=2;
printf(“address of d: %p\n”,&d);
printf(“address of r: %p\n”,&r);
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
printf(“rT=%f\n”,rT);
}
FILES main.c
float division(int numerator, int denominator,
int *dividend, int *remainder)
{
printf(“address stored in dividend: %u\n”,dividend);
printf(“address stored in remainder: %u\n”,remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
#ifndef dH
#define dH
#define NUMB int
float rT;
float division(int , int , int* , int*);
#endif // dH
definitionsHeader.h
#ifndef mH
#define mH
#include "definitionsHeader.h"
#include "functions.h"
#endif // mH
mainHeader.h
functions.h
FILES
main.c
#ifndef dH
#define dH
#define NUMB int
float rT;
float division(int , int , int* , int*);
#endif // dH
definitionsHeader.h
#ifndef mH
#define mH
#include "definitionsHeader.h"
#include "functions.h"
#endif // mH
mainHeader.h
float division(int numerator, int denominator, int *dividend, int *remainder) {
printf("address stored in dividend: %u\n",dividend);
printf("address stored in remainder: %u\n",remainder);
if (denominator < 1)
return(-1);
*dividend=numerator/denominator;
*remainder=numerator%denominator;
return( (float)numerator/ (float)denominator);
}
functions.h
#include
#include “mainHeader.h”
int main() {
NUMB x, y, d, r;
x=9;
y=2;
printf(“address of d: %p\n”,&d);
printf(“address of r: %p\n”,&r);
rT = division(x,y,&d,&r);
printf(“%d/%d = %d with %d remainder\n”,x,y,d,r);
printf(“x=%d\n”,x);
printf(“rT=%f\n”,rT);
}
16
LAYERS of a
C PROGRAM
header files containing C code
compiled
13 14
15 16
5
17
COMPILING a C PROGRAM
code (xx.c) files
containing C code
object
code
18
Header Files in C
END OF SECTION
19
CS 2211
System Programming
Part Nine (b): Pointers to Functions
20
17 18
19 20
6
Data Structures: A Pseudocode
Approach with C
21
Data Structures: A Pseudocode
Approach with C
22
void* larger (void* dataPtr1, void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if ((*ptrToCF) (dataPtr1, dataPtr2) > 0)
return dataPtr1;
else
return dataPtr2;
} // larger
#include
#include
#include “Ch1A.h” // Header file
int compare (void* ptr1, void* ptr2);
int main (void)
{
int i = 7 ;
int j = 8 ;
int lrg;
lrg = (*(int*) larger (&i, &j, compare_I));
printf (“Larger value is: %d\n”, lrg);
return 0;
} // main
int compare_I (void* ptr1, void* ptr2)
{
if (*(int*)ptr1 >= *(int*)ptr2)
return 1;
else
return -1;
} // compare
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2) > 0)
return dataPtr1;
else
return dataPtr2;
} // larger
header file (Ch1A.h)
Label Address Value
399
…
…
…
…
…
…
…
…
compare_I 5004 – 5125 102552
…
21 22
23 24
7
#include
#include
#include “Ch1A.h” // Header file
int compare (void* ptr1, void* ptr2);
int main (void)
{
int i = 7 ;
int j = 8 ;
int lrg;
lrg = (*(int*) larger (&i, &j, compare_I));
printf (“Larger value is: %d\n”, lrg);
return 0;
} // main
int compare_I (void* ptr1, void* ptr2)
{
if (*(int*)ptr1 >= *(int*)ptr2)
return 1;
else
return -1;
} // compare
header file (Ch1A.h)
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
…
…
…
…
…
compare_I 5004 – 5125 102552
…
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2) > 0)
return dataPtr1;
else
return dataPtr2;
} // larger
#include
#include
#include “Ch1A.h” // Header file
int compare (void* ptr1, void* ptr2);
int main (void)
{
int i = 7 ;
int j = 8 ;
int lrg;
lrg = (*(int*) larger (&i, &j, compare_I));
printf (“Larger value is: %d\n”, lrg);
return 0;
} // main
int compare_I (void* ptr1, void* ptr2)
{
if (*(int*)ptr1 >= *(int*)ptr2)
return 1;
else
return -1;
} // compare
header file (Ch1A.h)
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
…
…
…
…
…
compare_I 5004 – 5125 102552
…
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2) > 0)
return dataPtr1;
else
return dataPtr2;
} // larger
#include
#include
#include “Ch1A.h” // Header file
int compare (void* ptr1, void* ptr2);
int main (void)
{
int i = 7 ;
int j = 8 ;
int lrg;
lrg = (*(int*) larger (&i, &j, compare_I));
printf (“Larger value is: %d\n”, lrg);
return 0;
} // main
int compare_I (void* ptr1, void* ptr2)
{
if (*(int*)ptr1 >= *(int*)ptr2)
return 1;
else
return -1;
} // compare
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2) > 0)
return dataPtr1;
else
return dataPtr2;
} // larger
header file (Ch1A.h)
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
…
…
…
…
…
compare_I 5004 – 5125 102552
…
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2)
> 0)
return dataPtr1;
else
return dataPtr2;
} // larger
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
dataPtr1 484 – 487 400
dataPtr2 488 – 491 404
ptrToCF 492 – 495 5004
…
…
compare_I 5004 – 5125 102552
…
25 26
27 28
8
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2)
> 0)
return dataPtr1;
else
return dataPtr2;
} // larger
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
dataPtr1 484 – 487 400
dataPtr2 488 – 491 404
ptrToCF 492 – 495 5004
…
…
compare_I 5004 – 5125 102552
…
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2)
> 0)
return dataPtr1;
else
return dataPtr2;
} // larger
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
dataPtr1 484 – 487 400
dataPtr2 488 – 491 404
ptrToCF 492 – 495 5004
ptr1 624 -627 400
ptr2 628 – 631 404
compare_I 5004 – 5125 102552
…int compare_I (void* ptr1, void* ptr2)
{
if (*(int*)ptr1 >= *(int*)ptr2)
return 1;
else
return -1;
} // compare
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2)
> 0)
return dataPtr1;
else
return dataPtr2;
} // larger
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
dataPtr1 484 – 487 400
dataPtr2 488 – 491 404
ptrToCF 492 – 495 5004
ptr1 624 -627 400
ptr2 628 – 631 404
compare_I 5004 – 5125 102552
…int compare_I (void* ptr1, void* ptr2)
{
if (*(int*)ptr1 >= *(int*)ptr2)
return 1;
else
return -1;
} // compare
if ( 7 >= 8)
int compare_I (void* ptr1, void* ptr2)
{
if (*(int*)ptr1 >= *(int*)ptr2)
return 1;
else
return -1;
} // compare
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2)
> 0)
return dataPtr1;
else
return dataPtr2;
} // larger
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
dataPtr1 484 – 487 400
dataPtr2 488 – 491 404
ptrToCF 492 – 495 5004
ptr1 624 -627 400
ptr2 628 – 631 404
compare_I 5004 – 5125 102552
…
if ( 7 >= 8)
29 30
31 32
9
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2)
> 0)
return dataPtr1;
else
return dataPtr2;
} // larger
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
dataPtr1 484 – 487 400
dataPtr2 488 – 491 404
ptrToCF 492 – 495 5004
…
…
compare_I 5004 – 5125 102552
…
if ( -1 > 0 )
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2)
> 0)
return dataPtr1;
else
return dataPtr2;
} // larger
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411
dataPtr1 484 – 487 400
dataPtr2 488 – 491 404
ptrToCF 492 – 495 5004
…
…
compare_I 5004 – 5125 102552
…
if ( -1 > 0 )
#include
#include
#include “Ch1A.h” // Header file
int compare (void* ptr1, void* ptr2);
int main (void)
{
int i = 7 ;
int j = 8 ;
int lrg;
lrg = (*(int*) larger (&i, &j, compare_I));
printf (“Larger value is: %d\n”, lrg);
return 0;
} // main
int compare_I (void* ptr1, void* ptr2)
{
if (*(int*)ptr1 >= *(int*)ptr2)
return 1;
else
return -1;
} // compare
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2) > 0)
return dataPtr1;
else
return dataPtr2;
} // larger
header file (Ch1A.h)
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411 8
…
…
…
…
…
compare_I 5004 – 5125 102552
… lrg = *(int*) address 404
#include
#include
#include “Ch1A.h” // Header file
int compare (void* ptr1, void* ptr2);
int main (void)
{
int i = 7 ;
int j = 8 ;
int lrg;
lrg = (*(int*) larger (&i, &j, compare_I));
printf (“Larger value is: %d\n”, lrg);
return 0;
} // main
int compare_I (void* ptr1, void* ptr2)
{
if (*(int*)ptr1 >= *(int*)ptr2)
return 1;
else
return -1;
} // compare
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2) > 0)
return dataPtr1;
else
return dataPtr2;
} // larger
header file (Ch1A.h)
Label Address Value
399
i 400 – 403 7
j 404 – 407 8
lrg 408 – 411 8
…
…
…
…
…
compare_I 5004 – 5125 102552
…
Larger value is: 8
33 34
35 36
10
#include
#include
#include “Ch1A.h” // Header file
int compare (void* ptr1, void* ptr2);
int main (void)
{
float f1 = 73.4;
float f2 = 81.7;
float lrg;
lrg = (*(float*) larger(&f1,&f2, compare_F));
printf (“Larger value is: %d\n”, lrg);
return 0;
} // main
int compare_F (void* ptr1, void* ptr2)
{
if (*(float*)ptr1 >= *(float*)ptr2)
return 1;
else
return -1;
} // compare
void* larger (void* dataPtr1,
void* dataPtr2,
int (*ptrToCF)(void*, void*))
{
if
((*ptrToCF) (dataPtr1, dataPtr2) > 0)
return dataPtr1;
else
return dataPtr2;
} // larger
header file (Ch1A.h)
Label Address Value
399
…
…
…
…
…
…
…
…
…
…
…
changes required to make this compare two floating
point values (notice func. larger does NOT change.
– passing func. pointer makes larger generic
38
Pointers to Functions in C
END OF SECTION
37 38
39