C language learned by suffering
C language learned by suffering
Strange relationship between arrays and pointers
Array-like usage
In the previous section, we explained that to pass an array to a function, the address of the first element of the array was passed.
By the way, the following program is the one from the previous section with pointer type arguments
Looking at this program, do you see anything unnatural?
The obvious unnatural part of this is data[i] in the line indicated by the comment.
Because this variable data is a pointer variable, not an array.
Nevertheless, how is it possible to specify an element number using []?
This is also briefly explained in section 3.
The role of [] is to be an operator that specifies the element number of an array, but
The mechanism is simply to add to the address of the array name.
In other words, it does not have to be an array, but any address value will do.
To elaborate, if you put an array name in a formula, with or without the [] symbol
The array name is treated as an address (pointer value) to the first element of the array.
Then, if the array name is appended with [], the number value is added to that address, and
As a result, they are treated as elements of the same number as the one that was added.
This shows that pointer variables can be used like arrays if available memory is available.
The following program is an example of using pointer variables like arrays.
Normally, there is no need for such a complication at all.
This will eventually become necessary when dynamic memory allocation is used.
By the way, the following program is the one from the previous section with pointer type arguments
Looking at this program, do you see anything unnatural?
source code
#include <stdio.h>
int getaverage(int *data);
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)
{
int i, average = 0;
for (i = 0; i < 10; i++)
{
average += data[i]; /* even though it is a pointer variable? */
}
return average / 10;
}
The obvious unnatural part of this is data[i] in the line indicated by the comment.
Because this variable data is a pointer variable, not an array.
Nevertheless, how is it possible to specify an element number using []?
This is also briefly explained in section 3.
The role of [] is to be an operator that specifies the element number of an array, but
The mechanism is simply to add to the address of the array name.
In other words, it does not have to be an array, but any address value will do.
To elaborate, if you put an array name in a formula, with or without the [] symbol
The array name is treated as an address (pointer value) to the first element of the array.
Then, if the array name is appended with [], the number value is added to that address, and
As a result, they are treated as elements of the same number as the one that was added.
Difference between declaration and formula
When you declare an array, you use <> to specify the number of elements, and
When you use an array element, you use <> to specify its number.
In fact, they are also two completely different symbols.
The <> in the declaration means to specify the number of elements, while the
The <> used in a formula is an operator that adds to an address.
In C, there is a tendency to want to use the same symbol for similar usages.
Therefore, there are many areas where the same symbol is assigned to different meanings.
When you use an array element, you use <> to specify its number.
In fact, they are also two completely different symbols.
The <> in the declaration means to specify the number of elements, while the
The <> used in a formula is an operator that adds to an address.
In C, there is a tendency to want to use the same symbol for similar usages.
Therefore, there are many areas where the same symbol is assigned to different meanings.
This shows that pointer variables can be used like arrays if available memory is available.
The following program is an example of using pointer variables like arrays.
Source Code
#include <stdio.h>
int main(void)
{
int *data;
int i, average = 0, array[10] = {15, 78, 98, 15, 98, 85, 17, 35, 42, 15}
data = array; /* assign array address to pointer variable */
for (i = 0; i < 10; i++)
{
average += data[i]; /* can be used like an array */
}
printf("%d\n", average / 10);
return 0;
}
Execution Result
49
Normally, there is no need for such a complication at all.
This will eventually become necessary when dynamic memory allocation is used.
Arrays and pointers are completely different
Many people seem to confuse arrays with pointers.
Arrays are a way of grouping many variables together in an ordered fashion, and
A pointer is a way to create a shortcut for a variable.
And yet, the similar usage has to do with the design of arrays.
This is because the C language uses pointers as a means to realize arrays.
Therefore, pointer variables can do the same thing as arrays.
So it is easy to confuse pointers with arrays.
An array is just a fixed variable that represents the beginning of many variables, and
A pointer variable can be assigned the address of any variable you like and
It is a variable that allows you to use any memory area you like.
Arrays are a way of grouping many variables together in an ordered fashion, and
A pointer is a way to create a shortcut for a variable.
And yet, the similar usage has to do with the design of arrays.
This is because the C language uses pointers as a means to realize arrays.
Therefore, pointer variables can do the same thing as arrays.
So it is easy to confuse pointers with arrays.
An array is just a fixed variable that represents the beginning of many variables, and
A pointer variable can be assigned the address of any variable you like and
It is a variable that allows you to use any memory area you like.
Pointer-only writing
In the previous section, we explained that assigning an array address to a pointer variable can be used in the same way.
The same usage means that the [] operator can be used to specify the element number.
But as a matter of fact, there is a way to write pointer variables for pointer variables.
This is called pointer arithmetic and is written as follows
The * at the beginning is an operator to switch pointer variables to normal variable mode.
brackets, the address value of the pointer variable is added by the element number, and
By switching the added address value to normal variable mode, the
This is a method of accessing memory that is advanced by a specified number from the first address.
The following program is an example of rewriting the previous program in this manner.
[], but instead uses pointer arithmetic to access arrays.
Of course, the execution result will be exactly the same as before.
In addition, the following is another way to write a pointer variable that takes advantage of the fact that it can change value.
Generally speaking, pointer arithmetic often refers to this type of operation.
This program is quite complicated and requires some explanation.
First, at the start of the for statement, the pointer variable data is assigned the address of the array.
Then, as an update, data++, is specified, but
The meaning of this is the same as for the previous variables: it is an operation to increase the address in DATA by one.
(More precisely, it is increased by the size of the type that the pointer variable points to.)
Then repeat until the pointer variable has the same value as the 10th element (counting from 0).
The method is to access each element of the array in turn.
This is a writing method that was often used in the C language because it was fast (at one time).
This is because if you normally use arrays in [], you need to add to the array every time you access it.
With pointer arithmetic, however, addition need only be done once each time in a loop.
The same usage means that the [] operator can be used to specify the element number.
But as a matter of fact, there is a way to write pointer variables for pointer variables.
This is called pointer arithmetic and is written as follows
pointer operation
*(pointer variable + element number)
The * at the beginning is an operator to switch pointer variables to normal variable mode.
brackets, the address value of the pointer variable is added by the element number, and
By switching the added address value to normal variable mode, the
This is a method of accessing memory that is advanced by a specified number from the first address.
Keyword
Pointer arithmetic]
A method of writing that uses array elements by adding or subtracting to or from a pointer variable.
In the past, this writing method was widely used because it was faster.
The following program is an example of rewriting the previous program in this manner.
source code
#include <stdio.h>
int main(void)
{
int *data;
int i, average = 0, array[10] = {15, 78, 98, 15, 98, 85, 17, 35, 42, 15}
data = array; /* assign array address to pointer variable */
for (i = 0; i < 10; i++)
{
average += *(data + i); /* pointer arithmetic */
}
printf("%d\n", average / 10);
return 0;
}
[], but instead uses pointer arithmetic to access arrays.
Of course, the execution result will be exactly the same as before.
In addition, the following is another way to write a pointer variable that takes advantage of the fact that it can change value.
Generally speaking, pointer arithmetic often refers to this type of operation.
source code
#include <stdio.h>
int main(void)
{
int *data;
int average = 0, array[10] = {15, 78, 98, 15, 98, 85, 17, 35, 42, 15};
for (data = array; data ! = &array[10]; data++)
{
/* Note here */
average += *data;
}
printf("%d\n", average / 10);
return 0;
}
This program is quite complicated and requires some explanation.
First, at the start of the for statement, the pointer variable data is assigned the address of the array.
Then, as an update, data++, is specified, but
The meaning of this is the same as for the previous variables: it is an operation to increase the address in DATA by one.
(More precisely, it is increased by the size of the type that the pointer variable points to.)
Then repeat until the pointer variable has the same value as the 10th element (counting from 0).
In other words, by accessing the pointer variable by increasing the value of the pointer variable itself
The method is to access each element of the array in turn.
This is a writing method that was often used in the C language because it was fast (at one time).
This is because if you normally use arrays in [], you need to add to the array every time you access it.
With pointer arithmetic, however, addition need only be done once each time in a loop.
bad old pointer arithmetic
In the previous section, we explained pointer arithmetic, a written method of accessing array elements with pointer variables.
But let me ask you this. Do you think that way of writing is easy to understand?
At least, it does not seem easy to understand to the author.
First, the following two mean exactly the same thing, but it is obvious which is easier to understand.
Also, the pointer operations, etc., for those increasing with ++ are even worse.
I don't think there is a human being who would look at the next two and think the lower one is easier to understand.
In addition, I wrote that pointer arithmetic is faster when increasing with ++, but in fact, this was a long time ago.
Today, compiler performance has improved dramatically.
And modern compilers, if they find a loop that looks like it's accessed by [].
Automatically, it is replaced and compiled in such a way that it is written like a pointer operation that is incremented by ++.
When C was first created, there were no such compilers.
Today, many compilers provide that level of ingenuity.
In the past, the ++ pointer operation was used quite a bit, and many people still use it today because of its legacy.
The author recommends using the easy-to-understand [] to access arrays.
But let me ask you this. Do you think that way of writing is easy to understand?
At least, it does not seem easy to understand to the author.
First, the following two mean exactly the same thing, but it is obvious which is easier to understand.
source code
data[5].
*(data + 5)
Also, the pointer operations, etc., for those increasing with ++ are even worse.
I don't think there is a human being who would look at the next two and think the lower one is easier to understand.
Source code
for (i = 0; i < 10; i++)
{
average += data[i];
}
for (data = array; data ! = &array[10]; data++)
{
average += *data;
}
In addition, I wrote that pointer arithmetic is faster when increasing with ++, but in fact, this was a long time ago.
Today, compiler performance has improved dramatically.
And modern compilers, if they find a loop that looks like it's accessed by [].
Automatically, it is replaced and compiled in such a way that it is written like a pointer operation that is incremented by ++.
When C was first created, there were no such compilers.
Today, many compilers provide that level of ingenuity.
Built-in
Most compilers for personal computers will perform the appropriate optimizations.
In addition, CPUs for personal computers have complex and high-performance internal cache mechanisms and
There are mechanisms that allow the CPU to optimize repetitive processes on its own to improve speed.
Therefore, in a modern personal computer, both writing methods end up being the same speed.
However, this is not necessarily true for embedded systems (low performance computers built into consumer electronics, etc.).
And compiler optimizations often don't work well enough.
The simplicity of the CPU mechanism makes it easy for the speed of a program to be directly reflected in the way it is written.
In such cases, pointer arithmetic is still useful today.
In addition, CPUs for personal computers have complex and high-performance internal cache mechanisms and
There are mechanisms that allow the CPU to optimize repetitive processes on its own to improve speed.
Therefore, in a modern personal computer, both writing methods end up being the same speed.
However, this is not necessarily true for embedded systems (low performance computers built into consumer electronics, etc.).
And compiler optimizations often don't work well enough.
The simplicity of the CPU mechanism makes it easy for the speed of a program to be directly reflected in the way it is written.
In such cases, pointer arithmetic is still useful today.
In the past, the ++ pointer operation was used quite a bit, and many people still use it today because of its legacy.
The author recommends using the easy-to-understand [] to access arrays.
Forget about the address.
So far, we have almost completely explained the function of the pointer variable, and
Emphasizing that pointer variables are variables that store addresses, the
We have explained various phenomena related to it.
However, when it comes time to actually program, the
Forget once and for all that a pointer variable is a variable that stores an address.
Because the real use of a pointer variable is to use it as a shortcut for a variable.
It is never about manipulating addresses.
In other words, pointer variables store addresses because they are only a mechanism, not a usage.
As long as you know how to use it, it does not matter how the internal processing works.
It is the same as being able to use a computer without knowing how it works at all.
Many people get stuck with pointer variables because they are only concerned with memorizing addresses.
Pointer variables are easy to use without knowing such internal mechanisms.
Set up a shortcut by appending & to the variable, and use it in normal variable mode by appending the * sign.
As long as you follow these steps, it doesn't matter what address you use.
However, there are sometimes very puzzling bugs in the C language.
In this case, the cause is mostly due to the wrong use of pointer variables.
When fixing bugs, remember that a pointer variable is a variable that stores an address, and
You will have to check to see if a wrong address has been assigned somewhere.
Emphasizing that pointer variables are variables that store addresses, the
We have explained various phenomena related to it.
However, when it comes time to actually program, the
Forget once and for all that a pointer variable is a variable that stores an address.
Because the real use of a pointer variable is to use it as a shortcut for a variable.
It is never about manipulating addresses.
In other words, pointer variables store addresses because they are only a mechanism, not a usage.
As long as you know how to use it, it does not matter how the internal processing works.
It is the same as being able to use a computer without knowing how it works at all.
Many people get stuck with pointer variables because they are only concerned with memorizing addresses.
Pointer variables are easy to use without knowing such internal mechanisms.
Set up a shortcut by appending & to the variable, and use it in normal variable mode by appending the * sign.
As long as you follow these steps, it doesn't matter what address you use.
However, there are sometimes very puzzling bugs in the C language.
In this case, the cause is mostly due to the wrong use of pointer variables.
When fixing bugs, remember that a pointer variable is a variable that stores an address, and
You will have to check to see if a wrong address has been assigned somewhere.
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.