In the previous section, we explained three types of pointers.
Let's declare some pointer variables here to get a feel for how they work.
So, with that said, I'd like to show you an example of declaring a pointer variable now.
As it turns out, this is quite a tricky matter.
Let's start by showing two examples of declaring pointer variables of type int.
Source code
int *p;
int* p;
This is how you declare a pointer variable, as shown in many introductory texts.
These two are ways to declare a variable of pointer type to an int named p.
One way to write it appears to be *p, where * is a symbol indicating a pointer type.
In fact, we are declaring a variable 'p' that stores the address of an integer variable.
"In that case, the second declaration with the asterisk in the type name also seems more readable, doesn't it?"
Declaring more than one variable can cause subsequent ones to differ from the apparent type name.
In the following example, the second p2 will become a regular int variable.
Source code
int *p1, p2;
"It's a very troublesome issue because both ways of writing are extremely unclear."
For now, let's stick to the first writing style.
"That means you can declare a pointer variable by putting an asterisk (*) before the variable name."
Even with a * attached, the variable name remains p.
Assign an address.
As explained in the previous section, a pointer variable is a variable that holds an address.
Let's move on to assigning addresses to the pointer variable right away.
"Okay, assigning an address is fine, but what address are you assigning?"
In theory, if the number falls within the range of memory the computer has.
For example, a computer with 4GB of memory can handle any number within the range of 0 to 4 billion.
"You can use them in that way for extremely simple computers like calculators, or for older gaming consoles like the Nintendo Famicom."
However, the computers you are likely using to learn C are probably modern ones.
Computers can be equipped with operating systems (OS) such as Windows, macOS, and Linux.
"This is managed by a mechanism called virtual memory, which prevents you from arbitrarily using memory."
Therefore, arbitrary address numbers will not be addresses managed by the OS.
Using pointer variables with arbitrary address assignments will likely be flagged as abnormal behavior by the OS and result in a crash.
Pointer variables must be assigned addresses managed by the operating system.
Actually, there is a simple and reliable way to assign properly managed address numbers.
The method is simple: declare another variable and assign the address of the original to it.
Declared variables can be used without issue because they are created in a memory area managed by the OS.
The following program demonstrates assigning a variable's address to a pointer variable p.
Source code
int main(void)
{
int *p;
int i;
p = &i;
return 0;
}
First, you can declare a variable as a pointer by placing an asterisk (*) before its name.
Please understand that an 'i' without a '*' prefix before its name indicates a regular variable.
In this example, we're using the & operator to obtain the address of variable i and assigning it to the pointer variable p.
In other words, at this point, the pointer variable p contains the address of i.
Therefore, the address of i and the content of the pointer variable p should naturally be the same.
The following program is an example of using the printf function to display and verify addresses.
Source code
#include <stdio.h>
int main(void)
{
int *p;
int i;
p = &i;
printf("p = %p\n", p);
printf("&i = %p\n", &i);
return 0;
}
The output of this program may be as follows.
Execution results
p = 0012FF80 &i = 0012FF80
They are perfectly aligned.
It's almost inevitable, considering pointer variables are variables themselves.
"Because you're assigning &i to p and then immediately displaying that value."
However, be mindful of the type here.
The type of pointer variable p is a pointer to int.
The type of variable i is int, but the address obtained using the & operator is of pointer type.
Therefore, &i can be substituted for p, and both can be displayed using the %p specifier.
Null pointer
Pointer variables also have garbage values assigned immediately after declaration. その値が使用可能なaddressなのかはまったくわからないので、 Using that address by mistake will definitely cause a bug.
You need to differentiate whether an address has been assigned to prevent this. そこで、C languageには、Null pointerが用意されています。 NULL というsymbolをPointer variablesにAssignmentしておけば、 "This indicates that the address is unassigned, meaning it's not yet in a usable state." int *p = NULL; このようにすれば、if文で p == NULL であるか比較すれば、 You can tell whether p has an address assigned to it.
Is a null pointer zero?
int *p = 0; "Nevertheless, it will be assigned a null pointer." これはC languageの文法として決まっていることであり、 NULL is not the same as zero.NULL is NULL. NULL は 正しいaddressがAssignmentされていないことを示すための識別用の値であり、 It is clearly distinguished from the number 0, which is used for calculation. もっとも、ほとんどのCompilerでは NULL は 0 になってると思いますが・・・
Mode switch
As explained in the previous section, pointer variables have two modes.
It is in both normal variable mode and pointer variable mode.
If you're using a pointer variable without any specific designation, it's in pointer variable mode.
To switch to normal variable mode, prefix the variable with an asterisk (*).
Pointer variables marked with an asterisk behave exactly like regular variables.
The following program demonstrates an example of switching pointer variables to standard variable mode.
Source code
#include <stdio.h>
int main(void)
{
int *p;
int i;
p = &i;
*p = 10; /* normalvariableモードに切り替えたPointer variablesにAssignment */
printf("*p = %d\n", *p);
printf("i = %d\n", i);
return 0;
}
The results of this program's execution are as follows:
Execution results
*p = 10 i = 10
In this program, the pointer variable p is dereferenced by adding a * to it, switching it to normal variable mode.
p is a pointer variable p that has switched to normal variable mode.
"As long as it's *p, you can treat it exactly like a regular variable."
Pointer variables switched to normal variable mode function just like regular variables.
The memory used at that time is the address assigned in pointer variable mode.In other words,
The most basic usage of pointer variables
Pointer variablesモードのHourに読み書きしたいメモリのaddressをAssignmentして、 "Subsequently, switch to normal variable mode to manipulate that memory."
This is the most basic way to use a pointer variable.
Instead of directly specifying which memory address to overwrite,
Assign the memory address you want to rewrite, switch the mode, and rewrite it.
It's something of a tiered structure with two levels, so it might not be immediately obvious.
In the previous program, on line 5, the address of variable i was assigned to the pointer variable p.
In line 6, p is switched to normal variable mode, and 10 is assigned to the address stored in p.
At this time, the address that p stored is, in other words, the address of variable i.
As a result, the value of variable i will be overwritten to 10.
If I could explain this more specifically, at that time, variable i and the *p in normal variable mode,
"It means they are using the exact same memory space."
It's not to say that when you assign 10 to *p*, *i* automatically switches to 10 as well.
These two are pointing to the same memory location.
Strange symbols*
The asterisk symbol actually has three different meanings, which can be a source of confusion. Let's clarify three distinctions here.
1つ目は、乗算演算子is.It's what we call multiplication. "Use symbols in equations like kai = 5 * 8."
2つ目は、間接参照演算子is.Convert pointer variables to regular variable mode. "In the formulas, use the symbols like *p." Pointer variablesモードのHourのPointer variablesでは掛け算が出来ないため、 Even though they use the same symbol as the multiplication operator, they are distinguishable.
3つ目は、Pointer variablesを宣言するHourに使用するsymbolis. It's only used at declaration and is used like `int *p`. ここがややこしいのですが、normalvariableモードに切り替える間接参照演算子*と、 宣言のHourに使用する*のsymbolは、何の関係もないまったく別のsymbolis. It's just a coincidence that they happen to use the same characters.
I think it would be clearer to use different characters for all three of these. 同じ文字を割り当てているのはC languageの欠陥の1つis. でも、いまさら直しようがありませんから、 Please make sure you all understand that these three are symbols with different meanings.
namely, a shortcut
We have now explained all the functionalities of pointer variables.
In fact, pointers have no functions beyond what has been explained so far.
When in pointer variable mode, assign a memory address.
That's the full functionality of pointers: switching to normal variable mode and then manipulating that memory.
Given what we've covered so far, it's natural that questions will arise.
Ultimately, what practical purpose do pointers serve?
As stated in the preceding section, to assign the variable's address in pointer variable mode,
What's the point of switching to normal variable mode to do something like that?
This is exactly as I suspected, and it's useless in this way.
It's generally much easier and less prone to errors to manipulate variables directly.
The true use of pointers is to use them as shortcuts.
It's just like those shortcuts on your Windows desktop.
A shortcut is a file that points to a file located elsewhere.
Opening the shortcut will open the file it points to.
Despite this, a shortcut is not the file it points to.
You can create shortcuts wherever you like.
Creating or deleting multiple instances will have no effect on the pointed-to file.
This is precisely what a pointer does.
"If you store the address of an existing variable in a pointer variable,"
Wherever the pointer variable is usable, it may be in a place where the original variable is not.
If you switch a pointer variable to a regular variable mode, you can use it just like the original variable.
That's exactly how it can act as a shortcut.
Foreign language pointers
It is commonly said that pointers are a feature only of the C and C++ languages. "You're right, in the sense that it involves manipulating a specific memory address."
しかし、Pointerの本当の使い方はショートカットとして使うことであり、 From that perspective, **most practical languages have pointers.** Javaの参照はまさしくそんな機能で、しかも頻繁に使われますし、 Similarly, one could say the same about statements like SET in Visual Basic.
そもそも、Pointerがないのでは、連結リストやtree構造などの、 We can't implement complex data structures, and object-oriented programming is also difficult. その意味では、仕組みが不明なJavaやVisualBasicのPointerより、 I find C pointers, with their clear mechanism, easier to understand.
The biggest difference between referencing in other languages and C pointers is whether it's automatic or manual. 他の言語の参照は、ほとんどautomaticでショートカットとして機能するようになっていますが、 C language pointers are entirely manual and must be fully understood and used by the programmer.
そのかわり、上級者がC languageのPointerを使いこなすと、Pointerだけで、 "Almost any control structure, any data structure, can become an unrealistically powerful feature." In fact, most of C's features are based on pointers.
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.