 Using functions  Writing functions  Basics  Prototypes  Parameters  Return types  Functions and memory  Pointer parameters.

Slides:



Advertisements
Similar presentations
C Structures and Memory Allocation There is no class in C, but we may still want non- homogenous structures –So, we use the struct construct struct for.
Advertisements

Kernighan/Ritchie: Kelley/Pohl:
Lecture 2 Introduction to C Programming
Introduction to C Programming
 2000 Prentice Hall, Inc. All rights reserved. Chapter 2 - Introduction to C Programming Outline 2.1Introduction 2.2A Simple C Program: Printing a Line.
Introduction to C Programming
ספטמבר 04Copyright Meir Kalech1 C programming Language Chapter 3: Functions.
 2007 Pearson Education, Inc. All rights reserved Introduction to C Programming.
Chapter 6. 2 Objectives You should be able to describe: Function and Parameter Declarations Returning a Single Value Pass by Reference Variable Scope.
1 CSC 1401 S1 Computer Programming I Hamid Harroud School of Science and Engineering, Akhawayn University
1 Chapter 8 Functions, Pointers, and Storage Classes  Pointer  Pointers to void  Call-by-Reference  Basic Scope Rules  Storage Classes  Default Initialization.
1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation –The new operator –The delete operator –Dynamic.
Introduction to C Programming
1 Procedural Concept The main program coordinates calls to procedures and hands over appropriate data as parameters.
Introduction To C++ Programming 1.0 Basic C++ Program Structure 2.0 Program Control 3.0 Array And Structures 4.0 Function 5.0 Pointer 6.0 Secure Programming.
Chapter 3: Introduction to C Programming Language C development environment A simple program example Characters and tokens Structure of a C program –comment.
Functions in C. Function Terminology Identifier scope Function declaration, definition, and use Parameters and arguments Parameter order, number, and.
1 Chapter 9 Scope, Lifetime, and More on Functions.
18-2 Understand “Scope” of an Identifier Know the Storage Classes of variables and functions Related Chapter: ABC 5.10, 5.11.
MAHENDRAN CHAPTER 6. Session Objectives Explain Type of Functions Discuss category of Functions Declaration & Prototypes Explain User Defined Functions.
© The McGraw-Hill Companies, 2006 Chapter 4 Implementing methods.
C Programming Tutorial – Part I CS Introduction to Operating Systems.
CSC 2400 Computer Systems I Lecture 5 Pointers and Arrays.
Project 1 Due Date: September 25 th Quiz 4 is due September 28 th Quiz 5 is due October2th 1.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. Chapter 2 Chapter 2 - Introduction to C Programming.
1 Functions Chapter 7 2 Hope you can function! What is R2D2 doing here? What is his function? Who is Nibble? Can he function? IS he a function? Who is.
CPS120: Introduction to Computer Science Decision Making in Programs.
Structure of a C program Preprocessor directive (header file) Program statement } Preprocessor directive Global variable declaration Comments Local variable.
Fundamentals of C and C++ Programming. EEL 3801 – Lotzi Bölöni Sub-Topics  Basic Program Structure  Variables - Types and Declarations  Basic Program.
CPS120: Introduction to Computer Science Functions.
Functions Top-down design Breaking a complex problem into smaller parts that we can understand is a common practice. The process of subdividing a problem.
Object-Oriented Programming in C++
CPS120: Introduction to Computer Science Lecture 14 Functions.
19&20-2 Know how to declare pointer variables. Understand the & (address) and *(indirection) operators. Dynamic Memory Allocation Related Chapter: ABC.
C Functions Three major differences between C and Java functions: –Functions are stand-alone entities, not part of objects they can be defined in a file.
Structure Programming Lecture 8 Chapter 5&6 - Function – part I 12 December 2015.
CSCI 171 Presentation 6 Functions and Variable Scope.
CSC141 Introduction to Computer Programming Teacher: AHMED MUMTAZ MUSTEHSAN Lecture - 6.
 Integers and Characters  Character Strings  Input and Output.
Review 1 List Data Structure List operations List Implementation Array Linked List.
Functions Illustration of: Pass by value, reference Scope Allocation Reference: See your CS115/215 textbook.
POINTERS. // Chapter 3 - Program 1 - POINTERS.CPP #include int main() { int *pt_int; float *pt_float; int pig = 7, dog = 27; float x = , y = 32.14;
L what are predefined functions? l what is? n function name n argument(s) n return value n function call n function invocation n nested function call l.
Functions Math library functions Function definition Function invocation Argument passing Scope of an variable Programming 1 DCT 1033.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. 1 Chapter 2 - Introduction to C Programming Outline.
 2007 Pearson Education, Inc. All rights reserved. A Simple C Program 1 /* ************************************************* *** Program: hello_world.
CMPSC 16 Problem Solving with Computers I Spring 2014 Instructor: Lucas Bang Lecture 11: Pointers.
Programming Fundamentals Enumerations and Functions.
A FIRST BOOK OF C++ CHAPTER 8 ARRAYS AND POINTERS.
1 Chapter 8 Scope, Lifetime, and More on Functions CS185/09 - Introduction to Programming Caldwell College.
1 Lecture 2 - Introduction to C Programming Outline 2.1Introduction 2.2A Simple C Program: Printing a Line of Text 2.3Another Simple C Program: Adding.
Chapter 9: Value-Returning Functions
User-Written Functions
Lesson #6 Modular Programming and Functions.
Chapter 2 - Introduction to C Programming
Lesson #6 Modular Programming and Functions.
Functions and Structured Programming
Chapter 2 - Introduction to C Programming
Programmazione I a.a. 2017/2018.
Lecture 6 C++ Programming
User-Defined Functions
Lesson #6 Modular Programming and Functions.
Functions Inputs Output
Object Oriented Programming COP3330 / CGS5409
Chapter 2 - Introduction to C Programming
Pointers, Dynamic Data, and Reference Types
Lesson #6 Modular Programming and Functions.
In C Programming Language
Predefined Functions Revisited
Pointers, Dynamic Data, and Reference Types
Presentation transcript:

 Using functions  Writing functions  Basics  Prototypes  Parameters  Return types  Functions and memory  Pointer parameters

 Using library functions  Writing functions  Parameter lists  Return types

 Library functions are often used in C  For example, the math.h library contains mathematical functions ▪ Such as sqrt and pow  When a function is called in a program the function code is executed  And the return value of the function (if any) replaces the function call (or invocation)

// Prints the area of a circle #include "stdio.h" #include "math.h" // Define Pi #define PI ; // Main program – next slide! int main(){ //... }

int main(){ float radius; float area; // Get keyboard input printf("Please enter the radius: "); scanf("%f", &radius); // Calculate area area = PI * pow(radius, 2); printf("The area of the circle is %.2f", area); return 0; }

area = PI * pow(radius, 2); function name arguments to the function the function executes, and it is replaced by the result that it returns

 Function calls in statements have precedence over most other operations  Such as arithmetic or comparisons  A function is executed and its result returned before other operations are performed

 Many functions need input  Data passed to a function are referred to as arguments  The number and type of arguments must match what is expected by the function  Failing to give appropriate arguments results in a compilation error

area = PI * pow("fred", 2); error: incompatible type for argument 1 of ‘pow’

 When a function is called, program execution switches to the function  Each line of code in the function is executed in turn until ▪ The last line is reached, or ▪ A return statement is processed  Execution then returns to the line of code where the function was called from  The function call is replaced by the return value

 As well as using functions, we can write our own functions  This is very useful as it increases the modularity of programs  Functions can be written and tested in isolation  It is good programming style to write many small functions

int mySquare(int x) { int sq = x * x; return sq; } function body return type parameter list function name function header return statement

 Functions have two parts  A header (or declaration) ▪ Return type of the function ▪ Function name ▪ Function parameter list  A body (or definition) ▪ The executable statements or implementation of the function ▪ The value in the return statement (if any) must be the same type as the function's return type

 Function's names are identifiers, so must follow identifier rules  Only contain a to z, A to Z, _, 0-9  Must start with a to z, A to Z  By convention function names should  Start with a lower case letter ▪ They can be distinguished from variables by their parameter lists (brackets)  Have meaningful names

 Not all functions need to return a value  For example a function to print instructions  Functions that return nothing should be given a return type of void  A function that returns nothing (void) cannot be used in an assignment statement  Void functions are often used for output

 Every function must have a parameter list  The parameter list consists of ()s which follow the function name  Parameter lists contain function input  A parameter list can be empty, but the brackets are still required when the function is defined  Whenever a function is called (used) it must be followed by brackets  Again, even if they are empty

#include "stdio.h" void hi(){ printf("hello world"); } int main (){ hi(); return 0; }

 A function that is written in a.c file can be used in that file  Just like a library function  The function must be declared before it is used, either by  Defining the function, or  Writing a forward declaration, and defining it later ▪ Also referred to as a function prototype

#include "stdio.h" #include "math.h" const float PI = ; int main() { float r = 3; printf("radius %.2f, volume = %.2f", r, sphere_volume(r)); return 0; } double sphere_volume(double radius) { return PI * pow(radius, 3) * 4.0/3; } error: conflicting types for ‘sphere_volume’ that's kind of an odd error message to get when the function hasn't been defined, here is an earlier warning the compiler processes the file one line at a time starting from the top, so when it reaches sphere_volume it doesn't recognize the name warning: format ‘%f’ expects argument of type ‘double’, but argument 3 has type ‘int’

#include "stdio.h" #include "math.h" const float PI = ; // Function Prototypes double sphere_volume(double radius); int main() { float r = 3; printf("radius %.2f, volume = %.2f", r, sphere_volume(r)); return 0; } double sphere_volume(double radius) { return PI * pow(radius, 3) * 4.0/3; } fix by inserting a function prototype before main (or by moving the function definition) it is usually preferable to use function prototypes rather than defining all of the functions above main

 The compiler compiles a program one line at a time  Starting at the top of the file  If the compiler encounters an undefined identifier it will be unable to continue  Functions can be declared before being used and defined later on in the file  A function prototype consists of the function header (followed by a semi-colon)

 Many functions require data to perform operations on (i.e. input)  Such data can be given to functions in a number of ways  The function can obtain the data itself ▪ By getting input from the user  Data can be provided via global variables ▪ Which are visible throughout the file  Values can be passed to parameters

 A global variable is a variable that is declared outside any function  Including the main function  Variables declared inside a function are referred to as local variables  Global variables can be used by any function  In the same file (and possibly other files)  Avoid global variables ▪ With a few exceptions, such as constants

 They make programs harder to understand  Functions that rely on global variables cannot be considered in isolation  They make programs harder to modify  It is relatively straightforward to change a function that is self-contained  They make programs less portable  If functions depend on global variables they cannot easily be used by other files

 Parameter lists are the preferred method of data input to a function  Parameters are special variables that can be passed values from calling code  A function's parameters are given the value of variables passed to a function ▪ Variables passed to functions are called arguments

void print_int_division(int dividend, int divisor) { int quotient = dividend / divisor; int remainder = dividend % divisor; printf("%d/%d = %d remainder %d\n", dividend, divisor, quotient, remainder); } //... main function scanf("%d", &x); //... scanf("%d", &y); //... print_int_division(x, y); //prints result of x/y //... main function scanf("%d", &x); //... scanf("%d", &y); //... print_int_division(x, y); //prints result of x/y formal parameters arguments

 Parameters and arguments are different variables  They refer to different main memory locations  Parameters are given the values of arguments  They may even have the same name but still refer to different variables  It is also possible to pass a function the address of a variable  As we've seen with scanf – more on this later

 Many functions return values  The function performs a calculation  And sends the result back to calling code ▪ e.g. sqrt, pow  Values are returned by a return statement  The type of the value in a return statement must match the return type of the function

int mySquare(int x) { int sq = x * x; return sq; } As soon as any return statement is reached the function execution ends and the value is returned to the calling code

 Whenever we want to perform an action or a calculation we should write a function  Functions organize other programming constructs  Functions often need input (arguments) and often return values  The return type of a function specifies the type of information that it returns  Note that a function with a return type of void returns nothing

 A function that specifies a return type must contain a return statement  Or an error results  The compiler may not check that all paths within a function contain a return value  Such as nested if statements, or  If, else if,..., else statements  Some compilers may give warnings about this, but others may not

 Is it possible to return from a function that does not return a value (i.e. is void)?  Yes!  Just use return with no value  This allows us to return from any function before reaching the end of the function  For example, in a branch of an if statement

 Functions should perform one task  In particular, functions that calculate values should not be responsible for output ▪ Such values should be returned not printed  Functions should be self contained  Input should be passed via parameters  Results should be returned using a return statement

 A function prototype should consist of the function header  Return type, name, parameter types ▪ e.g. int foo(int, int); ▪ The parameter names do not have to be specified, but may be if desired  Older C compilers did not require parameters in function prototypes  This applies to the Visual Studio C compiler

 Recall that two variables cannot have the same name  More accurately, two variables can have the same name as long as they have different scope  The scope of a variable is the block in which it is declared  So variables with different scope may have different names

void f(){ int x = 99; printf("%d\n", x); } int main() { int x = 1; if (x == 1){ int x = 2; printf("%d\n", x); } printf("%d\n", x); f(); printf("\n\n"); return 0; } x's scope

 The scope of any variable declared inside a function is local to that function  This includes a function's parameters ▪ So a parameter of a function may not have the same name as a variable declared inside that function ▪ Unless the variable has a more limited scope  Functions cannot be defined inside functions  The scope of two different functions therefore does not overlap

 The example shown previously had two variables called x in the main function  One variable declared in if (if-x) and one declared in main (main-x)  The scope of main-x encompassed the entire main function and overlapped with if-x  In such cases only the variable with the least scope is visible

 Let's expand our memory model to cover functions  Which includes the main function  It's not going to be very different from our original model  Main memory is a long sequence of binary digits  Variables are allocated in sequence  A system table allows us to find variables ▪ But we are not going to go into much detail about it

data22313 address data223TheDude\013 address Let’s look at an example of memory allocation in a main function int x = 223; char name[10]; int y = 13; This function, defined in string.h copies the second argument into the first argument variabletypeaddress xint2048 namechar*2052 yint2062 This area of memory is referred to as the call stack, and it is used for memory associated with function calls symbol table (also in main memory) strcpy(name, “The Dude”); next free byte

variabletypeaddress xint2048 namechar*2052 yint2062 variabletypeaddress xint2048 namechar*2052 yint2062 aint2066 bint2070 data223TheDude\013 address data223TheDude\ address Now add some function calls to a function called sum2 int x = 223; char name[10]; int y = 13; During the call to sum2 memory is allocated (in sequence) to the parameters of sum2 (and its other variables if it had any) strcpy(name, “The Dude”); x = sum2(x, y); int sum2(int a, int b) { return a + b; } int sum2(int a, int b) { return a + b; } sum2’s memory next free byte

data223TheDude\ address data236TheDude\ address Now add some function calls to a function called sum2 int x = 223; char name[10]; int y = 13; After the call to sum2, x has changed and the next free byte is 2066, since the memory allocated to sum2 is no longer needed strcpy(name, “The Dude”); x = sum2(x, y); variabletypeaddress xint2048 namechar*2052 yint2062 int sum2(int a, int b) { return a + b; } int sum2(int a, int b) { return a + b; } next free byte

variabletypeaddress xint2048 namechar*2052 yint2062 variabletypeaddress xint2048 namechar*2052 yint2062 aint2066 bint2070 data236TheDude\ address data236TheDude\ address Now add some function calls to a function called sum2 int x = 223; char name[10]; int y = 13; Note that the two calls to sum2 reuse the same eight bytes of the stack since they happen one after the other strcpy(name, “The Dude”); x = sum2(x, y); int sum2(int a, int b) { return a + b; } int sum2(int a, int b) { return a + b; } y = sum2(x, x) + sum2(y, y);

data236TheDude\ address Now add some function calls to a function called sum2 int x = 223; char name[10]; int y = 13; Note that the two calls to sum2 reuse the same eight bytes of the stack since they happen one after the other strcpy(name, “The Dude”); x = sum2(x, y); variabletypeaddress xint2048 namechar*2052 yint2062 int sum2(int a, int b) { return a + b; } int sum2(int a, int b) { return a + b; } y = sum2(x, x) + sum2(y, y);

variabletypeaddress xint2048 namechar*2052 yint2062 variabletypeaddress xint2048 namechar*2052 yint2062 aint2066 bint2070 data236TheDude\ address data236TheDude\013 address Now add some function calls to a function called sum2 int x = 223; char name[10]; int y = 13; Note that the two calls to sum2 reuse the same eight bytes of the stack since they happen one after the other strcpy(name, “The Dude”); x = sum2(x, y); int sum2(int a, int b) { return a + b; } int sum2(int a, int b) { return a + b; } y = sum2(x, x) + sum2(y, y);

data236TheDude\013 address data236TheDude\ address Now add some function calls to a function called sum2 int x = 223; char name[10]; int y = 13; Note that the two calls to sum2 reuse the same eight bytes of the stack since they happen one after the other strcpy(name, “The Dude”); x = sum2(x, y); variabletypeaddress xint2048 namechar*2052 yint2062 int sum2(int a, int b) { return a + b; } int sum2(int a, int b) { return a + b; } y = sum2(x, x) + sum2(y, y);

 The area of main memory used for function calls is called the call stack  A stack is a simple data structure where items are inserted and removed at the same end  Usually referred to as the top of the stack  A stack is a LIFO (Last In First Out) structure  The call stack behaves like a stack  Since the last function to be called  Is the first function to be removed (de-allocated)

 The process for allocating main memory on the stack is simple  Always allocate memory in sequence  A few things have to be recorded  The address of the next free byte  The starting address for each function’s memory  The line number of each function call in the calling function

 Their is one disadvantage of using stack memory  The size of a variable cannot change  The value of variables can change but more space cannot be allocated to an existing variable  Since it would overwrite the next variable on the stack  It might be useful to change the size of array variables...

Introduction to Pointers

 We have mostly used pass-by-value to give information to functions  The data passed to a function is copied into the function’s parameters  This requires time to make a copy of the passed value ▪ Trivial if we are passing an integer ▪ Less trivial if we are passing a 100MB image

 Let's say we want to write a function to swap the values in two variables  Here is a first attempt void swap(int x, int y) { int temp = x; x = y; y = temp; } void swap(int x, int y) { int temp = x; x = y; y = temp; } Does this work?

void swap(int x, int y) { int temp = x; x = y; y = temp; } void swap(int x, int y) { int temp = x; x = y; y = temp; } // Calling code (in main) int a = 23; int b = 37; swap(a, b); // Calling code (in main) int a = 23; int b = 37; swap(a, b); 23 a 37 b x and y are parameters of the swap function so have their own space in main memory 23 x 37 y

void swap(int x, int y) { int temp = x; x = y; y = temp; } void swap(int x, int y) { int temp = x; x = y; y = temp; } // Calling code (in main) int a = 23; int b = 37; swap(a, b); // Calling code (in main) int a = 23; int b = 37; swap(a, b); 23 tempabxy 2337

swap has completed its execution so its memory is released 37 x 23 y temp note that neither a nor b's values have changed, so the swap function achieved nothing! void swap(int x, int y) { int temp = x; x = y; y = temp; } void swap(int x, int y) { int temp = x; x = y; y = temp; } // Calling code (in main) int a = 23; int b = 37; swap(a, b); // Calling code (in main) int a = 23; int b = 37; swap(a, b); ab 2337

 Remember that scanf accepts the address of a variable as an argument  And that the value of the variable is changed once scanf has finished its execution  This is often referred to as pass by reference  We can specify an address using &  A function definition also needs to specify that it expects an address ▪ Note that the address of a float is not the same as a float

void swap(int* x, int* y) { int temp = *x; *x = *y; *y = temp; } void swap(int* x, int* y) { int temp = *x; *x = *y; *y = temp; } // Calling code int a = 23; int b = 37; swap(&a, &b); // Calling code int a = 23; int b = 37; swap(&a, &b); 23 a 37 b the x and y parameters contain the addresses of a and b, not their values x y

x y temp a b void swap(int* x, int* y) { int temp = *x; *x = *y; *y = temp; } void swap(int* x, int* y) { int temp = *x; *x = *y; *y = temp; } // Calling code int a = 23; int b = 37; swap(&a, &b); // Calling code int a = 23; int b = 37; swap(&a, &b);

37 23 a b x y temp swap has completed its execution so its memory is released Because swap's parameters are passed addresses a and b have changed void swap(int* x, int* y) { int temp = *x; *x = *y; *y = temp; } void swap(int* x, int* y) { int temp = *x; *x = *y; *y = temp; } // Calling code int a = 23; int b = 37; swap(&a, &b); // Calling code int a = 23; int b = 37; swap(&a, &b);

 The * is used to mean a number of different things, dependent on the context  Multiplication  Declaration of a pointer variable, when used after a type name ▪ int * p; declares a pointer called p that will store the address of an int  Dereferencing of a pointer to access the variable that it points to ▪ *p = 7; assigns 7 to the int that p points to

 A pointer is a special type of variable  That stores an address rather than a value  They are called pointers as they can be considered to point to a variable  It is necessary to record the type of data that a pointer variable points to  So that the appropriate operations can be performed on the value it points to

 Pointers store addresses  Addresses are always the same size on the same system  So why do we have to say what type of data is going to be pointed to?  To reserve enough space for the data and  To ensure that the appropriate operations are used with the data

 Pointer variable are identified by an * that follows the type in the declaration  int * p;  This declares a variable called p that will point to (or refer to) an integer  Note that the type of a pointer is not the same as the type it points to  p is a pointer to an int, and not an int

PPreviously I declared a pointer like this  i i nt * p ; ▪T▪The spaces are not necessary YYou can do this  i i nt *p ; OOr this  i i nt* p ; OOr even this  i i nt*p ; But this is kind of ugly!

 The operation shown below is unsafe  int x = 12;  int *p = x;  Remember that the type of p is an address (to an int), and not an int  Addresses are actually whole numbers but assigning arbitrary numbers to them is a bad idea  Since a programmer is unlikely to know what is stored at a particular memory address This is not a good thing to do and will result in a compiler warning or error

 Pointers can be assigned the address of an existing variable  Using the address operator, &  In this way it is possible to make a pointer refer to a variable

int x = 23; int* p = &x; p contains the address of x & is the address of operator

 Pointers can be used to access variables  But only after they have been assigned the address of a variable  To change the value of a variable a pointer points to the pointer has to be dereferenced  Using the * operator which can be thought of meaning the variable pointed to

int x = 5; int *p = &x; /*assign p the address of x*/ /*Use p to assign 23 to x*/ *p = 9; /*dereferences p*/ printf("value in x = %x\n", x); printf("address of x = %x\n", &x); printf("value in p = %x\n", p); printf("address of p = %x\n", &p); printf("value in *p = %x\n\n", *p);

int x = 12; int y = 77; int *p1 = &x; //assign p1 the address of x int *p2 = &y; //assign p2 the address of y p1 p x x y y

int x = 12; int y = 77; int *p1 = &x; //assign p1 the address of x int *p2 = &y; //assign p2 the address of y p1 = p2; //assigns the address in p2 to p1 p1 p x x y y

12 77 int x = 12; int y = 77; int *p1 = &x; //assign p1 the address of x int *p2 = &y; //assign p2 the address of y *p1 = *p2; p1 p2 77 x x y y

 In practice we don't often use pointers like the preceding examples  Pointers can be used to allow functions to change the value of their arguments  They are also key to managing memory for objects that change size during run-time  Such objects are allocated space in another area of main memory – in dynamic memory