Cのポインタは興味深いものです。ポインターを使用すると、一部のCプログラミングタスクの実行を簡略化でき、動的メモリ割り当てなどの一部のタスクはポインターなしでは実行できません。したがって、優れたCプログラマーになりたい場合は、ポインターを学ぶ必要があります。要点をまっすぐにしましょう
コンテンツ
1.ポインターとは
2.ポインターとポインターの種類
3.ワイルドポインター
4.ポインターと配列
5.ポインター配列
6.好きで行くことを忘れないでください
1.ポインタとは何ですか?
C言語では、変数はメモリに格納され、メモリは実際には順序付けられたバイトの配列であり、各バイトには一意のメモリアドレスがあります。CPUは、メモリアドレス指定を使用して、メモリに格納されている指定されたデータオブジェクトのアドレスを特定します。ここで、データオブジェクトとは、メモリに格納されている指定されたデータ型の値または文字列を指し、それぞれに独自のアドレスがあり、ポインタはこのアドレスを保持する変数です。つまり、ポインタは変数のアドレスを保持する変数の一種です。
簡単に次のように理解できます。
- ポインタは、アドレスであるメモリ内の最小単位(つまり、バイト)の番号です。
- 通常、口頭言語で話されるポインターは、メモリーアドレスを格納するために使用される変数の
要約であるポインター変数を参照します。ポインターはアドレスであり、口頭言語のポインターは、通常、ポインター変数を参照します
。次のコードのメモリ分散で。
#include<stdio.h>
int main()
{
int a[10] = {
0 };
int i = 0;
for (i = 0; i < 10;i++)
printf("%p\n", &a[i]);
return 0;
}
出力は
配列は整数であるため、2つの要素ごとの差は4バイトです。
2.ポインタとポインタの種類
サンプルコード
int num = 10;
p = #
&num(numのアドレス)をpに保存するために、pがポインター変数であることがわかっているので、そのタイプは何ですか?
ポインタ変数に対応するタイプを与えます。
char *pc = NULL;
int *pi = NULL;
short *ps = NULL;
long *pl = NULL;
float *pf = NULL;
double *pd = NULL;
ここでわかるように、ポインターは次のように定義されます:type+*。
実際
、char *型ポインターは、char型変数のアドレスを格納するためのものです。
short *型のポインタは、short型の変数のアドレスを格納するために使用されます。
int *型のポインタは、int型の変数のアドレスを格納するために使用されます。
次のコードを参照してください
int main()
{
int n = 10;
char *pc = (char*)&n;
int *pi = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc+1);
printf("%p\n", pi);
printf("%p\n", pi+1);
return 0; }
要約:ポインターのタイプによって、ポインターが前進または後退する距離(距離)が決まります。
たとえば、intは1ステップで4バイト、charは1ステップで1バイトを取ります...
ポインタの逆参照
#include <stdio.h>
int main()
{
int n = 0x11223344;
char *pc = (char *)&n;
int *pi = &n;
*pc = 0; //重点在调试的过程中观察内存的变化。
*pi = 0; //重点在调试的过程中观察内存的变化。
return 0; }
要約:
ポインターのタイプは、ポインターを逆参照するときに持つ権限の量(操作できるバイト数)を決定します。
例:char *ポインターの逆参照は1バイトにしかアクセスできず、int*ポインターの逆参照は4バイトにアクセスできます。
3.ワイルドポインタ
概念:ワイルドポインターとは、ポインターが指す位置が不明であることを意味します(ランダム、不正確、および明確に制限されていません)
(1)ワイルドポインターの原因
a。ポインターが初期化されていません
#include <stdio.h>
int main()
{
int *p;//局部变量指针未初始化,默认为随机值
*p = 20;
return 0; }
b。ポインターの範囲外アクセス
#include <stdio.h>
int main()
{
int arr[10] = {
0};
int *p = arr;
int i = 0;
for(i=0; i<=11; i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*(p++) = i;
}
return 0;
}
c。ポインタが指すスペースを解放する方法
(2)ワイルドポインタを回避する方法
- ポインタの初期化
- 範囲外のポインタに注意してください
- スペースへのポインターは、NULLに設定されていても解放されます
- ローカル変数のアドレスを返さないようにする
- 使用前にポインタの有効性を確認してください
4.ポインタと配列
上記のコード
#include <stdio.h>
int main()
{
int arr[10] = {
1,2,3,4,5,6,7,8,9,0};
printf("%p\n", arr);
printf("%p\n", &arr[0]);
return 0; }
配列名と配列の最初の要素のアドレスが同じであることがわかります。
**結論:**配列名は、配列の最初の要素のアドレスを表します。( ** sizeof(array)**と&arrayを除く)
次に、ポインタを介して配列に直接アクセスすることもできます。
int main()
{
int arr[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int *p = arr; //指针存放数组首元素的地址
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i<sz; i++)
{
printf("%d ", *(p + i));
}
return 0; }
5.ポインタの配列
ポインタの配列は、その名前が示すように、ポインタを格納するために使用される配列であり、
整数配列、文字配列であることはすでにわかっています。
int arr1[5];
char arr2[6];
ポインタの配列はどうですか?
int* arr3[5];//是什么?
arr3は5つの要素を持つ配列であり、各要素は整数ポインターです。