C language learned by suffering
C language learned by suffering
Passing information by argument
Arguments of pointer type
In Chapter 11, I explained how to use and create your own functions.
In this section, we explained how to return information from a function by using the return value.
While using return values to return information is arguably the easiest way to do this, the
This method can always return only one piece of information.
This is inconvenient when more than one piece of information needs to be returned.
In such cases, information can be returned using arguments of type pointer.
Pointer-type arguments are nothing special.
The argument type is simply a pointer type, no different from ordinary arguments.
In C, when passing information to a function, a copy of the value of the original variable is always passed.
Such a method is called value passing and is characterized by the fact that the value of the original variable remains unchanged.
There is no difference in the principle that a copy of the value is passed even if it is a pointer type argument.
The reason we still use the pointer type is that the pointer type can receive addresses.
If you specify the address of a variable that already exists when you call the function
If the called function assigns the received address to the pointer variable
The pointer variable can then be switched to normal variable mode and the information to be returned can be assigned.
The returned information will be stored in the variable specified by the caller.
The following program is an example of actually using pointer type arguments to return information.
The result of executing this program might look like this
Note that this is the result on LSIC-86, so the address is 2 bytes.
In this program, the address of the variable value is passed when calling the function.
It is only the address value itself (0F68 in this case) that is passed to the func function.
Since the func function assigns that address value to a pointer variable
Naturally, the address passed to the func function and the address received are the same.
If an address value is assigned to a pointer variable, the
You can switch to normal variable mode and read and write that memory at will.
As a result, the contents of the calling variable can be rewritten from the called function.
All functions that have been called with & are similarly structured.
This is the most popular use of pointers in the C language.
In this section, we explained how to return information from a function by using the return value.
While using return values to return information is arguably the easiest way to do this, the
This method can always return only one piece of information.
This is inconvenient when more than one piece of information needs to be returned.
In such cases, information can be returned using arguments of type pointer.
Pointer-type arguments are nothing special.
The argument type is simply a pointer type, no different from ordinary arguments.
In C, when passing information to a function, a copy of the value of the original variable is always passed.
Such a method is called value passing and is characterized by the fact that the value of the original variable remains unchanged.
There is no difference in the principle that a copy of the value is passed even if it is a pointer type argument.
The reason we still use the pointer type is that the pointer type can receive addresses.
If you specify the address of a variable that already exists when you call the function
If the called function assigns the received address to the pointer variable
The pointer variable can then be switched to normal variable mode and the information to be returned can be assigned.
The returned information will be stored in the variable specified by the caller.
The following program is an example of actually using pointer type arguments to return information.
source code
#include <stdio.h>
void func(int* pvalue); /* prototype declaration */
int main(void)
{
int value = 10;
printf("&value = %p\n", &value);
func(&value); /* pass address */
printf("value = %d\n", value);
return 0;
}
void func(int* pvalue)
{
printf("pvalue = %p\n", pvalue);
*pvalue = 100; /* switch to normal variable mode and assign */
return;
}
The result of executing this program might look like this
Note that this is the result on LSIC-86, so the address is 2 bytes.
Execution Result
&value = 0F68
pvalue = 0F68
value = 100
pvalue = 0F68
value = 100
In this program, the address of the variable value is passed when calling the function.
It is only the address value itself (0F68 in this case) that is passed to the func function.
Since the func function assigns that address value to a pointer variable
Naturally, the address passed to the func function and the address received are the same.
If an address value is assigned to a pointer variable, the
You can switch to normal variable mode and read and write that memory at will.
As a result, the contents of the calling variable can be rewritten from the called function.
All functions that have been called with & are similarly structured.
This is the most popular use of pointers in the C language.
Array type arguments
Arrays can also be used as arguments, although we have not dealt with this so far.
However, arrays have many different properties than regular arguments, making them more difficult to handle.
For now, let us try to create a function with array-type arguments in the same way as before.
The argument is an array of type int with 10 elements, and a function is created to find the average of the values assigned to the array.
Implemented in the same way as before, it would be as follows
The result of executing this program is as follows
Within the function, the values of array element numbers 0 through 9 are added to the variable and
Finally, the result is divided by 10 to obtain the average value.
However, arrays have many different properties than regular arguments, making them more difficult to handle.
For now, let us try to create a function with array-type arguments in the same way as before.
The argument is an array of type int with 10 elements, and a function is created to find the average of the values assigned to the array.
Implemented in the same way as before, it would be as follows
source code
#include <stdio.h>
int getaverage(int data[10]);
int main(void)
{
int average, array[10] = { 15, 78, 98, 15, 98, 85, 17, 35, 42, 15 }
average = getaverage(array);
printf("%d\n", average);
return 0;
}
int getaverage(int data[10])
{
int i, average = 0;
for (i = 0; i < 10; i++) {
average += data[i];
}
return average / 10;
}
The result of executing this program is as follows
Execution Result
49
Within the function, the values of array element numbers 0 through 9 are added to the variable and
Finally, the result is divided by 10 to obtain the average value.
Thus, at first glance, it appears that arrays can also be passed as arguments.
Strange Properties of Array Type Arguments
In the previous section, we described how to use arrays as arguments.
This function has an odd property that was not possible with the previous arguments.
First, the number of array elements is ignored.
The following program is an example of intentionally passing an array with 5 elements.
The result of executing this program might look like this
An array with only 5 elements can be passed, even though the argument type is 10 elements.
As a result, the function side is forced to process 10 elements, resulting in a strange result.
An even stranger phenomenon is that changing the value of an array in a function also changes the caller.
The following program is an example of trying to change the value of an array within a function.
The result of executing this program is as follows
With the previous arguments, changing the value of an argument in the called function would not change the value of the
The value of the caller's argument never changed, but the
In arrays, for some reason, changes made by the caller affect the caller.
Such a thing should not be possible with value passing.
This function has an odd property that was not possible with the previous arguments.
First, the number of array elements is ignored.
The following program is an example of intentionally passing an array with 5 elements.
source code
#include <stdio.h>
int getaverage(int data[10]);
int main(void)
{
int average, array[5] = { 15, 98, 98, 17, 42 }; /* number of elements is 5 */
average = getaverage(array);
printf("%d\n", average);
return 0;
}
int getaverage(int data[10])
{
int i, average = 0;
for (i = 0; i < 10; i++) {
average += data[i];
}
return average / 10;
}
The result of executing this program might look like this
Execution Result
202380394
An array with only 5 elements can be passed, even though the argument type is 10 elements.
As a result, the function side is forced to process 10 elements, resulting in a strange result.
An even stranger phenomenon is that changing the value of an array in a function also changes the caller.
The following program is an example of trying to change the value of an array within a function.
source code
#include <stdio.h>
int getaverage(int data[10]);
int main(void)
{
int average, array[10] = { 15, 78, 98, 15, 98, 85, 17, 35, 42, 15 };
printf("array[3] = %d\n", array[3]);
average = getaverage(array);
printf("array[3] = %d\n", array[3]);
printf("%d\n", average);
return 0;
}
int getaverage(int data[10])
{
int i, average = 0;
for (i = 0; i < 10; i++) {
average += data[i];
}
data[3] = 111; /* change the value of the argument array */
return average / 10;
}
The result of executing this program is as follows
Execution Result
array[3] = 15
array[3] = 111
49
array[3] = 111
49
With the previous arguments, changing the value of an argument in the called function would not change the value of the
The value of the caller's argument never changed, but the
In arrays, for some reason, changes made by the caller affect the caller.
Such a thing should not be possible with value passing.
I'm giving you the address.
In the previous section, we discussed the strange properties of array-type arguments.
That phenomenon would not be possible if arrays were passed by value.
So, conversely, the array itself is not passed by value.
However, we have succeeded in actually passing the array to the function to calculate the average value.
In other words, there is no doubt that the array is being passed in some form.
To verify this point, let us conduct a little experiment.
First, we saw in the previous section that the number of elements is ignored in arguments of array types.
What if the number of elements is not specified?
In other words, change the function as follows.
When rewritten and executed in this manner, it works without any problems.
Moreover, if you do not specify the number of elements in the prototype declaration, but instead use
Even when the number of elements is added in the actual function declaration, no error occurs.
This shows that the number of elements is completely ignored.
But how do you pass an array value if you ignore the number of elements?
Normally, when passing an array, you would copy the value by the number of elements.
However, as long as the number of elements is ignored, such a method cannot be used.
Here, I would like to conduct another experiment.
In the previous section, when you changed the value of the array in the called function, it changed to the caller, but
This phenomenon is very similar to the use of pointer-type arguments.
In other words, it may be that you are passing an address instead of an array.
As a test, I changed the function as follows.
Amazingly, this still worked without any problems.
Now we know the cause of all the strange phenomena that had just occurred.
In other words, we were not passing an array, but the address of the beginning of the array.
If you just pass the top address of the array, the number of elements does not matter at all.
Also, since the array in the called function will point to the same memory area as the caller
It stands to reason that if the value of the array is changed in the called function, the caller will also be changed.
To summarize this, first, the following three are temporary argument declarations with the same meaning.
However, these three have the same meaning only in the case of function pseudo-argument declarations.
And in the function, data is a variable of pointer type in both cases.
And the caller and the caller will use exactly the same array of memory space.
That phenomenon would not be possible if arrays were passed by value.
So, conversely, the array itself is not passed by value.
However, we have succeeded in actually passing the array to the function to calculate the average value.
In other words, there is no doubt that the array is being passed in some form.
To verify this point, let us conduct a little experiment.
First, we saw in the previous section that the number of elements is ignored in arguments of array types.
What if the number of elements is not specified?
In other words, change the function as follows.
source code
int getaverage(int data[])
When rewritten and executed in this manner, it works without any problems.
Moreover, if you do not specify the number of elements in the prototype declaration, but instead use
Even when the number of elements is added in the actual function declaration, no error occurs.
This shows that the number of elements is completely ignored.
But how do you pass an array value if you ignore the number of elements?
Normally, when passing an array, you would copy the value by the number of elements.
However, as long as the number of elements is ignored, such a method cannot be used.
Here, I would like to conduct another experiment.
In the previous section, when you changed the value of the array in the called function, it changed to the caller, but
This phenomenon is very similar to the use of pointer-type arguments.
In other words, it may be that you are passing an address instead of an array.
As a test, I changed the function as follows.
Source code
int getaverage(int *data);
Amazingly, this still worked without any problems.
Now we know the cause of all the strange phenomena that had just occurred.
In other words, we were not passing an array, but the address of the beginning of the array.
If you just pass the top address of the array, the number of elements does not matter at all.
Also, since the array in the called function will point to the same memory area as the caller
It stands to reason that if the value of the array is changed in the called function, the caller will also be changed.
To summarize this, first, the following three are temporary argument declarations with the same meaning.
However, these three have the same meaning only in the case of function pseudo-argument declarations.
Source code
int getaverage(int data[10]);
int getaverage(int data[]);
int getaverage(int* data);
And in the function, data is a variable of pointer type in both cases.
And the caller and the caller will use exactly the same array of memory space.
Which one to use
Some of you may be wondering which one to use when all three mean the same thing.
The author recommends using the second form, which omits the number of elements.
This is because the third declaration is confusing with an ordinary pointer type.
With the second declaration, it is explicitly clear that you are receiving an array.
The first declaration looks childish to those familiar with the C language.
The author recommends using the second form, which omits the number of elements.
This is because the third declaration is confusing with an ordinary pointer type.
With the second declaration, it is explicitly clear that you are receiving an array.
The first declaration looks childish to those familiar with the C language.
About this Site
The C language (bitter C), which is learned by suffering, is
This is the definitive C language introductory site.
It systematically explains the basic functions of the C language and
It is as complete as or more complete than any book on the market.