Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Hello everybody!
I have decided to write some additional notes on the above topic because when I looked
at your programs, I was quite surprised because most of your solutions used pointer
parameters. Well, if you looked at my solution, you would note that I only used pointer
parameters in the input function. In all the other functions, I did not use pointer
parameters. And the exercise (activity 6-1) also stated that you have to use pointer
parameters for the input function.
Before I answer this question, let me first discuss a little on functions in general.
The generic name for functions in C or in any other programming languages for that
matter is subprogram. This means that we can consider a function as a small program
within a big program. This way, it will be possible for us to decompose one big problem
into small problems and each small problem will have a small subprogram to take care
of it.
Now, a program as we all know, in order to be useful, must get input from the user and
must supply output to the user. Thus in order to make a program for a problem, we first
have to determine what the input is, then we have to determine what to do with the input
in order to get the output.
Since a function is a small program, as such, we should be able to supply input to the
function and the function should be able to supply the output to the user. Most of the
time, however, unless the function is supposed to do an actual input function, we try not
to put scanf inside. Instead, whatever the function needs as input, we pass it as
parameter. The output of the function on the other hand is returned to the user through
the return statement. This way, our function is a stand-alone function.
Since functions take input through parameters, it is important that you understand
parameters and parameter transmission very clearly.
There are actually two names that we use to refer to parameters. Parameters can be
formal parameters or actual parameters.
Example:
main(){
int x = 5, result;
result = factorial(x);
The n in factorial is called a formal parameter while the x in the function call in main() is
called an actual parameter.
C uses what we call transmission by value. This means that the value of the actual
parameter is transmitted to the formal parameter when the function is called.
Example 1:
feet 5
int feetToInches(int feet) {
int inches; inches 60
inches = feet * 12;
value is copied at
return inches;
the point of call
}
main() { f 5
int f=5, i=0;
i = feetToInches(f); i 0
}
In main(), there are two variables --> f and i, f has value 5 and i has value 0. When the
function feetToInches(f) is called, what happens is that the value of the actual
parameter f, which is 5, is passed to the formal parameter feet in the function. This
means the feet which is considered as local variable will have the value of 5.
Transmission by value therefore means, that the formal parameter is evaluated at the
point of call, then the value of the actual parameter is transmitted to the formal
parameter.
Example 2:
void changeMe(int x) {
x = x * 10;
}
main() {
int x = 5;
changeMe(x);
printf(“%d”,x);
}
Well, if you answered 50, you are wrong because the output of the program is 5?
WHY???
To illustrate:
void changeMe(int x) { x 50
x = x * 10;
}
main() {
int x = 5;
changeMe(x); x 5
printf(“%d”,x);
}
When changeMe() was called, the value 5 was copied to the formal parameter x.
Afterwards, formal parameter x was multiplied by 10, making it 50. However, note that
the actual parameter x in main() was not affected. This is the meaning of transmission
by value.
How then can we change the actual parameter? Is there a way by which we can actually
change the value of x in main()?
If you were able to follow the previous discussion, you should be convinced that simply
transmitting the value of a variable will not change the value of that variable. How then
can we change the value of the actual parameter like the x in changeMe()?
Example:
address
main() {
int a = 5; 0110 a 5
int p; /* p is a pointer to an integer */
p = &a; p 0110
*p = 10;
printf(“%d”,a);
}
In this example, the output is 10, not 5. The reason being that since p is holding the
address of a, saying *p = 10 actually means store 10 in the memory location pointed
to by p, which is actually the variable a, making the value of a 10.
This concept of pointer variables can be used in order to implement the cases where we
want to change the actual parameter. We can now change the previous program as
follows:
First, we have to remember that the if the formal parameter is a pointer parameter, we
have to pass the address of the actual parameter. Next, we have to use pointer
indirection *p for example, in order to access the variable pointed to by our parameter.
Normally, if the parameter will simply serve as input to the function, that is, the function
will simply use and not change (where the change is needed by the caller of the
function) then it is better to simply pass the value. Pointer parameters are quite
complicated so we should only use them whenever the function will
manipulate/change the parameter and the change is needed by the caller of the
function. And since the formal parameters are allocated separate space, most of
the time, if we are passing data structures already, we would normally want to
pass their address in order to save memory. And this is actually the strategy used
for arrays (as you will see later on). When we pass an array as parameter, it is
always the address that automatically gets transmitted.
So next time you need to implement a function with parameters, you have to ask
yourself first will the value serve as input only? in which pass the value, not the
address.
I hope that by now, you were able to understand why in my solution, it is only the the
input function that has pointer parameters. This is because, in the input function, I need
the input from the keyboard. For the others, the functions will simply use the value
transmitted to them.
I also know that you were able to make your program work even with the unnecessary
(sorry for the term) use of pointer parameters. However, in general, this will not work.
Remember that pointer parameters require the callers to transmit addresses of the
parameters.
For example:
Remember the primeNumber(n) function that checks whether n is prime? In this case,
we simply want to transmit a value as a parameter. If n is a pointer parameter like
primeNumber(int *n) aside from complicating the function, every time I call
primeNumber(int *n), I have to say primeNumber(&x), which is of course not a very
intuitive way of doing it. I also cannot call the function simply as primeNumber(13813),
in order to check if 13813 is a prime number. I have to store it in a variable first and pass
the address of that variable because the function accepts an address, not just an integer.
I hope that you get my point here. I just realized how difficult on-line learning is in cases
like this. It is better to illustrate concepts like this face to face.
Prepared by: