It's certainly the simplest way to return information using a return value, but...
This method can only return one piece of information at a time.
It's inconvenient when you want to return more than one piece of information.
In such cases, you can return information using a pointer argument.
Pointer arguments aren't really anything special.
Simply, the type of the argument being a pointer doesn't make it any different from a regular argument.
In C, when passing information to a function, you always pass a copy of the original variable's value.
This method is called pass by value, and it is characterized by the fact that the original variable's value does not change.
"Even with pointer arguments, the principle of passing a copy of the value remains the same."
"That's why we still use pointer types - because they can receive addresses."
If you specify the address of an existing variable when calling a function,
If the received address is assigned to a pointer variable within the called function,
"Then, switch the pointer variable to a normal variable mode, and you can assign the returned information."
The returned information will be stored in the variable specified by the caller.
The following program demonstrates an example of using a pointer argument to return information.
The output of this program may be as follows.
Please note that this is based on results from LSIC-86, so the address is 2 bytes.
Execution results
&value = 0F68 pvalue = 0F68 value = 100
This program passes the address of the variable `value` when calling the function.
The `func` function receives the address value itself (0F68 in this case).
Since the address value of the func function is being assigned to a pointer variable,
Of course, the address passed to the func function and the address received are the same.
"When a pointer variable is assigned an address value,"
"Since you can switch to normal variable mode and freely read and write to that memory,"
As a result, the called function can modify the contents of the variable in the calling context.
The functions that were previously called with & all operate using the same mechanism.
This is one of the most common ways to use pointers in C.
Array arguments
We haven't supported this before, but it can now accept arrays as arguments.
However, arrays have many properties that differ from regular arguments, making them more difficult to work with.
Let's start by creating a function with an array-typed argument, just like we've been doing.
"Create a function that takes an integer array of size 10 as input and calculates the average of the values assigned to the array."
If we implement it the way we always have, it will look like this.
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 output of this program is as follows:
Execution results
49
Within the function, the values of array elements from index 0 to 9 are added to a variable.
Finally, the result is divided by 10 to calculate the average.
In this way, it appears that arrays can also be passed as arguments.
The Peculiar Nature of Array Arguments
In the previous section, we explained how to use arrays as arguments.
This function has a peculiar property that was not possible with previous arguments.
First, the size of the array element is disregarded.
The following program demonstrates an example of deliberately passing an array with a size of 5.
Source code
#include <stdio.h>
int getaverage(int data[10]);
int main(void)
{
int average, array[5] = { 15, 98, 98, 17, 42 }; /* 要素数が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 output of this program might be as follows.
Execution results
202380394
"Although the argument's type has 10 elements, you can pass an array with only 5 elements."
As a result, the function forcefully processed 10 elements, leading to incorrect results.
As an even stranger phenomenon, modifying the value of an array within the function changes it for the caller as well.
The following program demonstrates an example of modifying array values 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; /* argumentのarrayの値を変更 */
return average / 10;
}
The output of this program is as follows:
Execution results
array[3] = 15 array[3] = 111 49
"With the arguments as they are now, modifying the value of an argument within the called function..."
The caller's argument value has not changed.
In arrays, for some reason, changes made at the callee are affecting the caller.
This simply shouldn't happen with pass-by-value.
I'm giving you the address.
In the preceding section, we described the peculiar properties of array-typed arguments.
Such a phenomenon would be impossible if the array were passed by value.
In other words, the array itself is not being passed by value.
However, I am actually successful in passing an array to the function and calculating the average.
In other words, it's undeniable that an array is being passed.
Let's do a little experiment to verify this point.
"First, we saw in the previous section that the size of the array is ignored when using array type arguments."
"Then, what would happen if we didn't specify the number of elements?"
"So, you're going to modify the function like this."
Source code
int getaverage(int data[])
It works perfectly fine even when rewritten and executed like this.
And furthermore, without specifying the number of elements in the prototype declaration.
Even in actual function declarations with the number of elements specified, no errors occur.
This further demonstrates that the number of elements is being completely disregarded.
"But how are the array values being passed without considering the number of elements?"
Normally, when passing an array, it involves copying the values as many times as there are elements.
However, since it ignores the number of elements, such a method cannot be used.
Here, I'd like to conduct another experiment.
In the previous section, when the value of an array was changed in a called function, the change propagated back to the calling function.
This phenomenon is quite similar to what happens when using pointer arguments.
It's possible that we're passing an address, not the array itself.
I tried modifying the function like this.
Source code
int getaverage(int *data);
Surprisingly, it worked flawlessly anyway.
Now, the cause of all the strange phenomena we've been experiencing is clear.
"Essentially, I wasn't passing the array itself, but rather the address of the beginning of the array."
If you only pass the address of the beginning of the array, the number of elements doesn't matter at all.
Also, arrays in called functions will refer to the same memory space as the calling function.
It's natural for the calling function to be modified when the value of an array is changed within the called function.
To summarize this, the following three are equivalent function declarations.
However, this only holds true for function parameter declarations.
Source code
int getaverage(int data[10]);
int getaverage(int data[]);
int getaverage(int* data);
And within the function, all of the `data` are pointer-type variables.
"Consequently, the caller and callee will end up using the exact same memory region for the array."
Which one?
この3つが同じ意味だと、どれを使って良いのか迷う人もいるかもしれませんが、 筆者としては、2番目のように要素数を省略した形を使うことを勧めます。 Because the third declaration is confusing due to its similarity to a regular pointer type. "The second declaration makes it explicit that an array is being received." The first declaration might seem naive to those familiar with C.
About This Site
Learning C language through suffering (Kushi C) is
This is the definitive introduction to the C language.
It systematically explains the basic functions of the C language.
The quality is equal to or higher than commercially available books.