ポインタリンクについての最後の話:
ポインターの5番目の部分(const変更ポインター、マルチレベルポインター)---- 2021.2.22
ポインタ配列
ポインターに触れると、ポインター配列と配列ポインターの2つの概念に触れることがよくあります。今日は、最初にポインタ配列の概念と使用法について説明しましょう。配列ポインタについては、後の記事で説明します。
まず、ポインタ配列について話す前に、通常の配列、つまり整数配列の概念を紹介する必要があると思います。
整数配列:は配列であり、配列の各要素は整数です。
次に、整数配列の概念からポインタ配列を導入できます。
ポインタ配列:は配列であり、配列の各要素はポインタです。
では、どのような条件下でポインタ配列を提案しましたか?
次のコードに示すようなので、我々は3つの整数の変数を定義しa
、b
そしてc
。そして、割り当てた値に10
、20
そしてそれぞれ30
。その後、我々は、すなわち、その三つの変数のアドレスを保存するための3つのポインタを定義する必要があり*p1
、*p2
そして*p3
。
int main()
{
int a = 10;
int b = 20;
int c = 30;
int* p1 = &a;
int* p2 = &b;
int* p2 = &c;
}
これは正常に実行できますが、アドレスを保存する必要のあるパラメーターが多数あると想像するとどうなるでしょうか。この方法を使用するのは非常に簡単ですか、それから何人かの人々はこの問題を非常にうまく解決するポインタ配列の概念を提案しました。使い方を見てみましょう。
int main()
{
int a = 10;
int b = 20;
int c = 30;
//需求: 数组中的每一个元素都是指针(地址)
int* num[3] = {
&a,&b,&c };
printf("%d\n",sizeof(num));
for (int i = 0;i < sizeof(num) / sizeof(num[0]);i++)
{
printf("%d ", *num[i]);
}
}
以下のように分析します。
- 我々は3つの整数の変数を定義し
a
、b
そしてc
。そして、値を割り当て10
、20
そしてそれぞれ30
。この時点で、これら3つの整数変数のアドレスを格納するためのポインター配列を定義する必要があります。次にnum
、ポインター配列のデータ型を知る必要があります。たとえばa
、変数のデータ型は型であるため、int
以前の記事から、変数の&
データ型が最終的なデータ型に追加され、“ * ”
次に必要なポインター配列のデータ型が追加されることがわかります。 defineはint *
タイプです。 printf("%d\n",sizeof(num));
この文は、実際num
にはポインタ配列の配列型のバイトサイズを出力します。通常の結果は12
です。以前の記事で述べたように、データ型ポインタが何であっても、最終的なバイトサイズはすべて4
です。ポインタ配列には同じデータ型の変数が3つあるため、これは正常3 x 4 =12
であり、結果は次のようになります。
- したがって、ポインタの配列にいくつかの要素があることを最初に知る必要があるポインタの要素配列、要素
sizeof(num)
の合計サイズへのポインタのバイト配列、およびの配列の要素のデータ型を出力する場合ポインタが同じである場合、配列内の特定の要素を抽出するだけで済みます。ここでは、最初の要素を例として取り上げます。つまりsizeof(num[0])
、配列要素のサイズは、2つの式を除算することで取得できます。この例では、です3
。
次に、最後にポインタの内容を出力し“ * ”
ます。操作する必要があります。 - みんなに理解してもらうために、特別にみんなに見てもらえる絵を描きました。
したがって、この時点で、配列numの最初の要素のアドレスを格納するためのポインターを定義したいのですが、どのように定義すればよいでしょうか。
これは、前の記事で説明したマルチレベルポインタを使用します。
たとえばnum[0]
、データ型が型の場合、int*
そのアドレスを格納するためのポインタ変数を定義する必要があります。次にk
、新しく定義されたポインタ変数のデータ型は、元のデータ型より1レベル高い必要があります“ * ”
。
最初にコーディングしてください!!!
int main()
{
int a = 10;
int b = 20;
int c = 30;
//需求: 数组中的每一个元素都是指针(地址)
int* num[3] = {
&a,&b,&c };
printf("%d\n", sizeof(num));
int** k = num;
for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++)
{
printf("%d ", **(k + i));
}
}
上記のコードの分析は次のとおりです。
- 前の分析から、新しく定義されたポインター変数kのデータ型は通常の
int**
型である必要があり、目的は配列のnum
最初の要素のアドレスを保存することであることがわかります。これは。とnum
同等&num[0]
です。したがって、最終的な定義は次のとおりです。int** k = num;
- その後、我々はしたい
k
変数を取得するために、ポインタ変数を介してa
、b
およびc
あるコンテンツ、10
、20
と30
。次にa
、変数の内容を例として取り上げます。この時点で、レベルごとに導出する必要があります。これk
はポインタ変数であるため、つまり、ポインタ変数は配列の最初の要素のアドレスをk
保存しnum
ます。つまりk = &num[0];
、ポインタ変数を介して配列の最初の要素のコンテンツk
を取得num
する必要があり“ * ”
ます。ポインタ変数k 。したがって*k = &a;
、別の“ * ”
操作を実行してもnum[0]
、ポインタ変数が指す対応する変数のa
メモリスペースの内容を抽出できます。つまり**k = 10;
、最終的k
にセカンダリポインタを介して変数a
の内容を取得できます。私たちの目標を達成しました。他は同じです。 - 最終的な操作結果を以下に示します。
- 同時に、みんなに理解してもらうために、特別にみんなに見てもらえる絵を描きました。
関数の仮パラメーターとしてのポインター
最初にコーディングしてください!!!
void swap(int x, int y)
{
int k = x;
x = y;
y = k;
printf("x=%d y=%d\n", x, y);
}
int main()
{
int a = 10;
int b = 20;
swap(a,b);
printf("a=%d b=%d\n", a, b);
system("pause");
return 0;
}
上記のコードの分析:
-
我々は2つの整数変数の和を定義
a
し、b
に値を割り当てる10
和それぞれ20
。それまでに、私たちは最終的にswap
機能しa
、b
交換価値を実行したいと考えています。つまり、最終効果の値a
は20
、b
の値です10
。操作の結果は次のとおりです。
-
上記の結果から、最終的な
a
合計b
値が正常に交換されなかったことがわかります。これはなぜですか。みんなに理解してもらうために、特別にみんなに見てもらえる絵を描きました。
開始a
値10
、b
値20
、次にswap
関数パラメーターx
値10
、y
値を入力します20
。したがって、この場合、値k
を一時的に格納しx
、最後に割り当てられた値k
になるまでの中間整数変数を定義x
しますy
。つまり、最終的に到達しx
、y
値は各効果によって置き換えられますがswap
、実際には、関数の後に終了するx
とy
、一時的な変数は、最終的に仮想メモリに格納されることはありませんa
合計b
値は、まだ本当の変化、持っていないa
ですが10
、最終的な結果は、上図の最終結果と同じであり、かつ価値はあるb
の値20
。だから、どのように我々はないswap
実感の値の交流a
と通じ機能をb
?このとき、ポインタが重宝します! -
変更された
swap
コードは次のとおりです。
void swap(int *x, int *y)
{
int k = *x;
*x = *y;
*y = k;
printf("x=%d y=%d\n", *x, *y);
}
int main()
{
int a = 10;
int b = 20;
swap(&a,&b);
printf("a=%d b=%d\n", a, b);
system("pause");
return 0;
}
また、みんなに理解してもらうために、特別にみんなに見てもらえる絵を描きました。
:上図の分析は以下の通りである。
まず第一に、我々ははっきりと見ることができるswap
のインタフェースパラメータというの着信機能がある&a
の和&b
である、のアドレスa
の合計b
。次に、ポインター変数x
とポインター変数は、y
それぞれ変数a
と変数を指しますb
。次いで、交換swap
のx
和で機能はy
、実際に直接操作の内容可変a
和b
で変装であるが、最終的にa
なる20
、b
となり10
、正常にポインタを介して交換し、次のように、最終的な演算結果です。
結びの言葉
この記事が良いと思うなら、それを気に入ってサポートすることを忘れないでください!!!