MMGameslogo  MMGames
TwitterSharebutton  FacebookSharebutton   
learn through sufferingC Language
learn through sufferingC Language

The Peculiar Relationship Between Arrays and Pointers

Array-like usage
"In the previous section, we explained that to pass an array to a function, you were passing the address of the array's first element."
By the way, the following program is based on the previous one, but uses arguments of pointer type.
"Do you see anything unnatural or out of place in this program?"

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]; /* Pointer variablesなのに? */
    }

    return average / 10;
}

The most obviously unnatural part here is the data[i] in the line I pointed out in the comments.
"Because this variable data is a pointer variable, not an array."
Despite this, what does it mean to be able to specify element numbers using []?

このことは、3節 でも簡単にDescriptionしています。
The brackets, [], serve as an operator that specifies the index of an array element.
It simply involves adding to the address given by the array name.
"This essentially means that any value representing an address will do, not just array elements."

To elaborate, when writing array names within a formula, the brackets, regardless of whether they are present or not,
Array names are treated as the address (pointer value) of the first element of the array.
"And when you append [] to the array name, it adds the value of the index to the address."
As a result, it is being treated as an element of the numbered sequence that has been summed.

Declarations vs. Formulas
arrayを宣言するHourには、<>で要素数を指定し、
arrayの要素を使うHourは、<>で番号を指定するのですが、
実は、この2つもまったく別のsymbolis.

宣言Hourの<>は要素数を指定するという意味を持ちますが、
数式の中で使用する<>は、addressに足し算する演算子is.

C languageでは、似た使い方には同じsymbolを使いたがる傾向があり、
Therefore, it appears that there are many instances where the same symbol is assigned to different meanings.

From this, we can see that pointer variables can be used like arrays if there is available memory.
The following program demonstrates the use of pointer variables like an array.

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; /* Pointer variablesにarrayのaddressをAssignment */

    for (i = 0; i < 10; i++)
    {
        average += data[i]; /* arrayみたいに使える */
    }
    
    printf("%d\n", average / 10);
    return 0;
}


Execution results
49

Normally, I have absolutely no need to deal with something this complicated.
You'll need it eventually when you start using dynamic memory allocation.

Arrays and pointers are entirely different things.
It seems many people confuse arrays and pointers.
arrayとは、多数のvariableを順番つけでまとめて扱う方法であり、
A pointer is a way to create a shortcut to a variable.

それなのに、似たような使い方ができるのはarrayの設計と関係あります。
In C, arrays are implemented using pointers.
Therefore, with pointer variables, you can achieve the same things as with arrays.

そのため、Pointerとarrayは混同しやすいのですが、
arrayはあくまでも多数のvariableの先頭を示す固定されたvariableであり、
Pointer variablesは、好きなvariableのaddressをAssignmentして、
It's a variable that can use the preferred memory space.

Pointer-specific notation
"In the previous section, we explained that if you assign the address of an array to a pointer variable, you can use it in the same way."
Being usable in the same way means that it allows specifying element numbers using the [] operator.

However, the truth is that pointer variables have their own way of being written.
This is written in a style called pointer arithmetic, and it looks like this:

Pointer arithmetic
*(Pointer variables + 要素番号)

The asterisk (*) at the beginning is an operator used to switch a pointer variable to normal variable mode.
“Pretending to be clever, I added the element number to the address value of the pointer variable,”
by switching to normal variable mode with that summed address value,
This is a method of accessing memory a specified number of bytes ahead of the starting address.

キーワード
【Pointer arithmetic】

"A way to access array elements by performing addition and subtraction on pointer variables."
In the past, this method was widely used because it was faster.


The following program is an example of rewriting the previous program in this style.

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; /* Pointer variablesにarrayのaddressをAssignment */

    for (i = 0; i < 10; i++)
    {
        average += *(data + i); /* Pointer arithmetic */
    }
    
    printf("%d\n", average / 10);

    return 0;
}


We are accessing the array using pointer arithmetic without using [].
Of course, the results will be exactly the same as before.
Furthermore, there's also a way to write it that takes advantage of the ability of pointer variables to have their values changed.
Generally, when people talk about pointer arithmetic, they often refer to something like this.

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++)
    {
        /* ここに注目 */
        average += *data;
    }

    printf("%d\n", average / 10);

    return 0;
}


This program has quite a few complicated parts, so an explanation is needed.
First, at the start of the for loop, the pointer variable data is assigned the address of the array.
And, as an update, "data++" is specified, but...
This means, as with variables previously, it's an operation that increments the address within data by one.
"(Specifically, increment it by the size of the type pointed to by that pointer variable.)"
And the loop continues until the pointer variable has the same value as the tenth element (counting from zero).

By incrementing the value of the pointer variable itself to access...
It's a method of accessing each element of the array sequentially.

This is a way of writing in C that was commonly used because it was fast (at the time).
Because when using arrays with standard indexing [], you need to perform addition every time you access an element.
However, with pointer arithmetic, the addition can be performed only once per loop iteration.
Legacy pointer arithmetic
The previous section explained pointer arithmetic for accessing array elements using pointer variables.
But I'd like to ask you all.Do you think that way of writing is clear?
At least, to me, it doesn't seem clear.

"First, these two options mean exactly the same thing, but it's clear which one is easier to understand."

Source code
data[5]
*(data + 5)

Moreover, pointer arithmetic using the increment operator (++) is even worse.
I don't think there's a humanity that would find the bottom one easier to understand.

Source code
for (i = 0; i < 10; i++)
{
    average += data[i];
}

for (data = array; data != &array[10]; data++)
{
    average += *data;
}


Furthermore, while it was written that pointer arithmetic using ++ is fast, that's actually a thing of the past.

Compilers have seen dramatic performance improvements recently.
And modern compilers, if they encounter a loop accessing something like within brackets [].
"It will be compiled, replacing it with a write that looks like pointer arithmetic, such as incrementing with ++."

Back when C was first created, there weren't any compilers like that.
Many compilers do that much these days.

In embedded systems
Most compilers for personal computers perform adequate optimization.
さらに、パソコン用のCPUは内部のキャッシュの仕組みが複雑かつ高性能であり、
There's a mechanism that allows the CPU to optimize loops for speed.
Therefore, with modern computers, either writing style will ultimately result in the same speed.

However, this isn't always the case with embedded systems (low-performance computers built into appliances and other devices).
CompilerによるOptimizationは十minuteには機能しないことも多いですし、
Because the CPU's architecture is relatively simple, the way programs are written tends to directly impact performance.
In such cases, pointer arithmetic remains useful even today.

"In the past, incrementing pointer arithmetic was frequently used, and many people still use it today as a remnant of that practice."
As the author, I recommend using clear [ ] to access arrays.
Let's forget about the address.
So far, we've covered almost everything about the functionality of pointer variables.
Emphasizing that pointer variables are variables that store addresses,
We have explained the various phenomena associated with it.

However, when actually creating a program,
Forget everything you know about pointer variables being variables that store addresses.

Because the real use of pointer variables is to use them as shortcuts to variables.
Never manipulate addresses.
In other words, a pointer variable storing an address is a mechanism, not a usage.
"That's because once you know how to use it, it doesn't matter how the internal workings are structured."
It's like being able to use a computer even without knowing how it works.

Many people stumble with pointer variables because they only focus on remembering addresses.
You can easily use pointer variables even if you don't know the underlying mechanisms.
Set shortcuts by prefixing variables with an ampersand (&), and use the asterisk (*) to return to normal variable mode.
As long as you follow these instructions, it doesn't matter about the address or anything like that.

However, C can occasionally produce very perplexing bugs.
In this case, the root cause is often a misuse of pointer variables.
When debugging, remember that pointer variables are variables that store addresses,
I suppose I need to check if an incorrect address has been assigned somewhere.


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.

Part 0: Program Overview
  1. What is a program?
Chapter 3: Displaying on the Screen
  1. String Display
  2. newline character
  3. Practice Problem 3
Chapter 4: Displaying and Calculating Numbers
  1. Display of numbers
  2. Basic calculations
  3. Numeric types
  4. Practice Problem 4
Chapter 6: Input from the Keyboard
  1. input function
  2. The fear of input
  3. Practice Problem 6
Chapter 9: Repeating a Fixed Number of Times
  1. Iterative sentence
  2. How Loops Work
  3. Practice Problem 9
Chapter 10: Repeating Without Knowing the Number of Times
  1. Unspecified loop
  2. Input validation
  3. Practice Problem 10
Chapter 13: Handling Multiple Variables at Once
  1. Handling multiple variables collectively.
  2. Arrays
  3. Practice Problem 13
Chapter 19: Dynamic Arrays
  1. Create arrays freely.
  2. Practice Problem 19