PARAMETER PASSING

CONTENTS:

Parameters can be classified into three groups or modes. They can be used to:

  1. Pass information to a sub-program.
  2. Return information from a sub-program.
  3. Pass information to a sub-program where it is updated and then returned.

Ada identifies these as the in, out and in out parameter modes (note that in Ada, by default, a parameter is an in parameter). There are many mechanisms whereby the above can be implemented, these include:

  1. Call by value.
  2. Call by constant value.
  3. Call by reference.
  4. Call by reference value.
  5. Call by result.
  6. Call by copy-restore or value-result.

Alongside the above we can also identify two kinds of parameter association:

  1. Named parameter association.
  2. Positional parameter association.

There area also a number of further considerations:




CALL BY VALUE

Call by value is the most common and is used by languages such as C, Pascal, Modula-2 and Algol-60. Here the formal parameter acts as a local variable which is initialised with the value of the actual parameter (which may be a variable, a constant or an expression) and may then be changed. However, any changes made to the formal parameter will not effect the value of the actual parameter.

C Example:

#include <stdio.h>

void doit(int, int, int);

void main(void)
{
int value1, value2, value3;

scanf("%d %d %d",&value1,&value1,&value3);

printf("Before doit:   value1=%d, value2=%d, value3=%d\n",value1,value2,value3);

doit(value1,value2,value3);

printf("Afrer doit:    value1=%d, value2=%d, value3=%d\n",value1,vlaue2,value3);
}

void doit(int num_a, int num_b, int num_c)
{
printf("Start of doit: num_a=%d, num_b=%d, num_c=%d\n",num_a,num_b,num_c);

num_a = num_b*100; num_b = num_b+num_c;

printf("End of doit:   num_a=%d, num_b=%d, num_c=%d\n",num_a,num_b,num_c);
}
CALL BY VALUE



CALL BY CONSTANT VALUE

In languages such as Ada (also Algol-68) the formal parameter is a local constant rather than a local constant and thus can not be changed. The latter mechanism is thus referred to as call by constant value.

Ada Example:

with CS_IO; use CS_IO;

procedure IN_MODE_EXAMPLE is
        VALUE_1, VALUE_2: float;

        procedure MEAN_VALUE (NUM_1, NUM_2: in float) is
        begin
                put_line("MEAN VALUE FUNCTION");
                put_line("===================");
                put("The mean is ");
                put((NUM_1+NUM_2)/2.0);
                new_line;
        end MEAN_VALUE;

begin
        get(VALUE_1);get(VALUE_2);
        MEAN_VALUE(VALUE_1, VALUE_2);
end IN_MODE_EXAMPLE;
CALL BY CONSTABT VALUE



CALL BY REFERENCE

The disadvantage of call by value (and call by constant value) is that a copy is always made of the actual parameter to obtain the formal parameter. The need to make a copy can be avoided using the call be reference mechanism. In call by reference the address of the actual parameter is passed, thus everything that happens to the formal parameter actually happens to the actual parameters. This is used by languages such as, Pascal, Modula-2 and Algol-68.

Pascal Example:

program PASSING (input, output);
        var VALUE_1, VALUE_2: real;

        procedure MEAN_VALUE (NUM_1: real; var NUM_2: real);
        begin
                NUM_2 := (NUM_1+NUM_2)/2;
        end;

begin
        readln(VALUE_1, VALUE_2);
        write('VALUE_1 = '); write(VALUE_1);
        write(', VALUE_2 = '); write(VALUE_2); writeln;
        MEAN_VALUE(VALUE_1, VALUE_2);
        write('MEAN VALUE_2 = '); write(VALUE_2); writeln;
end.
CALL



CALL BY REFERENCE VALUE

In the C programming language the effect of call be reference can be achieved by passing a reference as a value. Knowledge of this reference can then be used to alter the value held in it. This mechanism thus only simulates call by reference and should (more accurately) be referred to as call be reference value.


C Example:

#include <stdio.h>

void meanValue(float *, float);

void main(void)
{
float value_1, value_2;

scanf("%d %s\n",&value_1,&value_2):

meanValue(&value_1, value_2);

printf("Mean value_1 = %f\n",value_1);
}

void meanValue(float *num_1, float mum_2)
{
printf("num_1 = %f, num_2 = %f\n",*num_1,num_2);
*num_1 = (*num_1+num_2)/2.0;
}

Remember that the operator & is interpreted as "the address of ...". And the operator * when followed by a pointer is interpreted as "the variable pointed at by ...".

CALL BY REFERENCE VALUE

Call by reference value is used in C to pass arrays. This has the efficiency advantage that we do not have make a copy of the array; of course when doing this we must appreciate that we are working with the actual data item. An example where we pass a string to a function is given below. Remember that, in C, when we use an array name on its own it acts as a "pointer" to the start of the array!

#include <stdio.h>

void toUpper(char *);

/* ------ MAIN ------ */

void main(void) {
    char myString[32];
	
    printf("Input a string of no more than 32 lower case characters\n");
    scanf("%s",myString);
	
    printf("Echo myString = %s\n",myString);
	
    /* Convert to Upper Casae */
	
    toUpper(myString);
	
    /* Output result */
	
    printf("Upper case = %s\n",myString);
    }

/* ------ TO UPPER CASE ------ */

void toUpper(char *text) {
    int index=0;
   
    while (text[index] != '\0') {
   	text[index] = text[index]-32;
	index++;
	}
    }



CALL BY RESULT

Call by result is used in Ada to implement out mode parameter passing. The formal parameter acts as an uninitialised local variable which is given a value during execution of the procedure. The value of the formal parameter is then assigned to the actual parameter on returning from the routine.


Ada Example:

with CS_IO; use CS_IO;

procedure OUT_MODE_EXAMPLE is
        VALUE_1, VALUE_2: float;
        MEAN: float;

        procedure MEAN_VALUE (NUM_1, NUM_2: in float; NUM_3: out float) is
        begin
                NUM_3:= (NUM_1+NUM_2)/2.0;
        end MEAN_VALUE;

begin
        MEAN_VALUE(VALUE_1, VALUE_2, MEAN);
        put("The mean is ");
        put(MEAN);new_line;
        new_line;
end OUT_MODE_EXAMPLE;
CALL



CALL BY COPY RESTORE (VALUE RESULT)

Call by copy restore (also known as call by value result) is an amalgamation of call by value and call by result. The formal parameter acts as a local variable which is initialised to the value of the actual parameter. Within the routine, changes to the formal parameter only affect the local copy. On returning from the routine the final value of the formal parameter is assigned to the actual parameter. Call by copy restore is supported by Ada to achieve "in-out" parameter operation. It has the same disadvantages as those associated with call by value.


Ada Example:

with CS_IO; use CS_IO;

procedure IN_OUT_MODE_EXAMPLE is
        VALUE_1, VALUE_2: float;

        procedure MEAN_VALUE (NUM_1: in out float; NUM_2: in float) is
        begin
                NUM_1:= (NUM_1+NUM_2)/2.0;
        end MEAN_VALUE;

begin
        get(VALUE_1);get(VALUE_2);
        put("BEFORE MEAN VALUE: VALUE_1 = ");
        put(VALUE_1);put(", VALUE_2 = ");put(VALUE_2);new_line;
        MEAN_VALUE(VALUE_1, VALUE_2);
        put("The mean is ");
        put(VALUE_1);new_line;
        put("AFTER MEAN VALUE: VALUE_1 = ");
        put(VALUE_1);put(", VALUE_2 = ");put(VALUE_2);new_line;
end IN_OUT_MODE_EXAMPLE;
CALL BY COPY RESTORE



POSITIONAL PARAMETER ASSOCIATION

The normal procedure when calling a routine is to list all the actual parameters in order separated by commas. This is called Positional Parameter Association (PPA). PPA means that any actual parameters supplied must agree with the formal parameters in number, order and type. Most imperative languages (Ada and C included) support PPA. Example

procedure POS_PARAM_ASSOC is
   ----------------------------------------------
   -- ADD_UP procedure
   procedure ADD_UP(X_VAL,Y_VAL,Z_VAL:INTEGER) is
   begin
      PUT(X_VAL+Y_VAL+Z_VAL);
      NEW_LINE;
   end ADD_UP;
    ----------------------------------------------
-- Top level
begin
   ADD_UP(2,4,6);
end POS_PARAM_ASSOC;    

The alternative is keyword or named parameter association (see below).



NAMED PARAMETER ASSOCIATION

Named parameter association (ada) example:

procedure NAMED_PARAM_ASSOC is
   ----------------------------------------------
   -- ADD_UP procedure
   procedure ADD_UP(X_VAL,Y_VAL,Z_VAL:INTEGER) is
   begin
      PUT(X_VAL+Y_VAL+Z_VAL);
      NEW_LINE;
   end ADD_UP;
   ----------------------------------------------
-- Top level
begin
   ADD_UP(X_VAL=>2, Y_VAL=>4, Z_VAL=>6);
   ADD_UP(Z_VAL=>6, X_VAL=>2, Y_VAL=>4);
   ADD_UP(2,        Z_VAL=>6, Y_VAL=>4);
end NAMED_PARAM_ASSOC;     



DEAFAULT PARAMETER VALUES

An Ada in parameters may be given a default value when the formal parameter is specified (sse example given right). However, in out parameters and out parameters may not have default values.

with CS_IO; use CS_IO;

procedure EXAMPLE is
   N1: float:= 4.2;
   N2: float:= 9.6;
   ---------------------------------------
   procedure MEAN_VALUE (X1: in out float;
      X2: in float := 6.4) is
   begin
      X1:= (X1+X2)/2.0;
   end MEAN_VALUE;
   ---------------------------------------
begin
   MEAN_VALUE(N1); put(N1); new_line;
   MEAN_VALUE(N1, N2); put(N1); new_line;
end EXAMPLE;      



PROCEDURES AS PARAMETERS

The above all assumes that we wish to pass data items. Some languages support passing of procedures (e.g. Pascal). Example: in numerical analysis, where methods for finding (say) roots of functions etc. can be written to be independent of any particular routine, it useful to be able to pass appropriate functions to solving routine.




Return to imperative home page.




Created and maintained by Frans Coenen. Last updated 03 July 2001