コンテンツ
ポインタ演算
ポインタ+-整数
ポインタ+-整数は、メモリにアクセスするときにスキップするバイト数です。これは以前に導入されたものなので、ここでは説明しません。
ポインタ-ポインタ
これは配列では非常に一般的です。pointer-pointerは2つのポインター間の要素の数を表します
このように、低アドレス(高アドレス)は負になります。
ポインタポインタメソッドでstrlen関数を実装する
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str)
{
assert(str);//判断指针是否错误
char* tmp = str;
while (*++tmp)
{
;
}
return tmp - str;
}
また、多くのライブラリ関数の実装についても書きました。時間があるときに確認できます。 さまざまなライブラリ関数の実装
ポインタと配列
デバッグからわかるように、配列名と配列の最初の要素のアドレスは同じです。
つまり、配列名は配列の最初の要素のアドレスを表します。
2例を除く
1.sizeof(arr)このときの配列名は配列全体を表します。つまり、sizeofだけに配置された配列名は配列全体を表します。
2.&arrこれは、配列全体を表す配列名であり、配列全体のアドレスが取り出されます。
配列名はアドレスとしてポインタに格納できるため、ポインタを使用して配列内の各要素にアクセスします。
int main()
{
int arr[] = { 0,1,2,3,4 };
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("&arr[%d] = %p\n", i, &arr[i]);
printf("p+%d = %p\n", i, p + i);
}
return 0;
}
演算結果:
したがって、p + iは実際には配列arrの添え字iのアドレスにアクセスしており、逆参照することで配列の内容にアクセスできます。
次に、ポインタを介して配列に直接アクセスできます
int main()
{
int arr[] = { 0,1,2,3,4 };
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;
}
実際、配列arr [i]にアクセスすると、コンパイラはそれを*(arr + i)に変換するため、ポインタへのアクセスは配列へのアクセスと同じになります。
二次ポインタ
ポインタ変数にも独自のアドレスがあるので、ポインタのアドレスを保存できますか?はい。これはセカンダリポインタです。
第2レベルのポインターのアドレスを保存すると、第3レベルのポインターになります(第4レベル、第5レベル....は無限にネストできます)。
aのアドレスはpaに格納され、paのアドレスはppaに格納されます。
paは第1レベルのポインター、ppaは第2レベルのポインターです。
* ppaはppaのアドレスを逆参照してpaを検索し、*ppaは実際にpaにアクセスします。
paのアドレスを間接参照すると、;が見つかります。** ppaも使用できます。これにより、にアクセスすることもできます。
ポインタの配列
ポインターの配列は、ポインター変数の配列です。
配列内の要素には、整数、浮動小数点型、文字型などがあります。ポインターも型であり、配列に格納することもできます。これは、ポインター型の配列(ポインターの配列と呼ばれます)です。
int main()
{
int a = 10;
int b = 20;
int c = 30;
int d = 40;
int e = 50;
int* arr[5] = { &a,&b,&c,&d,&e };//存放整型指针的数组
for (int i = 0; i < 5; i++)
{
printf("%d ", *(arr[i]));//依次对数组中的指针进行访问
}
return 0;
}
配列ポインタ
配列ポインタは、配列全体のアドレスを格納するポインタです。
前に述べたように、さまざまなタイプのポインタ変数が一度にさまざまなメモリサイズにアクセスし、配列全体にアクセスする必要がある場合があります
配列ポインタを使用する必要があります。配列が整数を格納する場合、配列ポインタの型はint(*)[]です。