C++ ポインターの概要

ポインタ(Pointer)は、英語で文字通り解釈すると、特定のオブジェクトを指すものであり、プログラムではデータアドレスを指すアドレスです。

1. ポインタの宣言

変数の型名と変数名の間にアスタリスクを追加します*。アスタリスクは、次のコード*intPtr1の と の*intPtr2そうしないと、宣言時に次の変数名のアスタリスクを見逃す可能性があります。複数のポインター。たとえばintPtr4、整数変数のみを宣言します。

int *intPtr1, *intPtr2;
int* intPtr3, intPtr4;

ポインタを宣言する際には必ず初期化を行ってください(初期化されていない場合、未知のアドレスを指す可能性があります)。

2. ポインタの種類

ポインタの型は、ポインタが指すアドレスに格納されているデータ型を示します。int *ポインタをfloat *ポインタに変換する必要がある場合、プログラムはデータを浮動小数点データとして再解釈するだけです。

void *ポインタはアドレスを表すだけであり、ポインタが指すデータ型は不明ですが、ポインタが指すデータ型は再定義できます。

3. ポインタの基本操作

逆参照*

ポインタが指すアドレスのデータを取得します。
宣言された場合は、*变量名変数がポインタとして使用されることを意味し、それ以外の場合は、*变量名ポインタが指すアドレス内のデータを意味します。

住所を取る&

変数のメモリアドレスを取得し、対応するポインタに代入します。

4. ポインタの算術演算

ポインタと整数の算術演算は、一般的な数値の加算や減算とは異なりますが、ポインタの型に拘束されます。ポインタの算術演算は、現在のポインタが指すアドレスを、ポインタ型の長さ k のアドレスだけ前後に移動します。次のポインタは必ずしも有効なデータを持つアドレスを指しているわけではないため、ポインタ演算を行うときは注意してください。

  • 配列名は、配列の最初の要素へのポインタとみなすことができます。ポインタのさまざまな操作を配列名に適用できますが、配列は静的であり、配列名は唯一の要素を表すため、配列名を再割り当てすることはできません。配列の場合、ポインタのように他のアドレスを指すことはできません。

ポインター間の減算演算は、ポインター アドレス間の距離 (正または負) を返します。この距離もポインターの型にバインドされます。

  string str[] = {
    
     "1","2","3" };
  //取地址
  string *s1 = &str[0];
  string *s2 = &str[1];
  //解引用
  cout << s1 << ' ' << *s1 << endl;
  cout << s2 << ' ' << *s2 << endl;
  //算数操作
  cout << s1 + 1 << ' ' << *(s1 + 1) << endl;
  cout << s2 - s1 << ' ' << s1 - s2 << endl;  //1  -1

ポインタは意味がないので追加できません。

4.定数ポインタ

constオブジェクトへのポインタconst T *ptr1

ptr1 が指すアドレスのデータは変更できませんが、ptr1 が指すアドレスは変更できます。

定数ポインタT *const ptr2

ptr2 が指すアドレスは変更できませんが、そのアドレスに格納されているデータは変更できます。

const オブジェクトへの const ポインタconst T *const ptr3

ptr3 が指すアドレスは変更できず、このアドレスのデータも変更できません。

  int numA = 3;
  //不能修改数据,能改指针的地址
  const int* ptr1 = &numA;
  //*ptr1 = 8;
  ptr1 = &numA + 1;
  
  //能修改数据,不能改指针的地址
  int* const ptr2 = &numA;
  *ptr2 = 9;
  //ptr2 = &numA + 1;
  
  //不能修改数据,也不能改指针的地址
  const int* const ptr3 = &numA;
  //*ptr3 = 9;
  //ptr3= &numA + 1;

5. ポインタ配列と配列ポインタ

  • ポインター配列: T *ptrArr[size]、ptrArr は配列であり、配列内の各要素はポインターです。ポインターの型は ** です。 ** を使用して配列の要素を読み取ることT*ができます。*(ptrArr[i])

  • 配列ポインタ: T (*arrPtr)[size]、arrPtr は配列を指します。配列のアドレスを arrPtr に割り当てる必要があります。逆参照した後、配列と同等になります。** ** を使用して配列の要素を読み取ることができます(*arrPtr)[i]

int num[5] = {
    
     1,2,3,4,5 };
//指针数组:元素是指针的数组
int* ptrArr[5] = {
    
     &num[0],&num[1],&num[2],&num[3],&num[4] };
for (int i = 0; i < 5; ++i) {
    
    
  cout << ptrArr[i] << ':' << *(ptrArr[i]) << ' ';
}; cout << endl;

//数组指针:指向数组的指针
int(*arrPtr)[5] = &num;
for (int i = 0; i < 5; ++i) {
    
    
  cout << ptrArr[i] << ':' << (*ptrArr)[i] << ' ';
}; cout << endl;

6. ポインタからポインタへ

ポインタは任意の変数またはオブジェクトを指すことができ、もちろんポインタを指すこともできます。
ポインタへのポインタが宣言されている場合、ポインタが指すポインタの型を表すために ** が使用されます。ポインタのポインタは通常、関数がパラメータを渡すときに受信ポインタを変更するために使用されます。

const_cast と reinterpret_cast

  • const_cast : 型の const または volatile 属性を変更し、非 const オブジェクトへのポインタまたは参照を返します。このとき、そのデータはポインタまたは参照を通じて変更できます。
    int numA = 3;
    const int* ptr1 = &numA;
    int* ptr2 = const_cast<int*>(ptr1);
    
    const int numB = 3;
    int& numb = const_cast<int&>(numB);
    
  • reinterpret_cast : 変数のデータ型を変更します

7. ポインタの応用例

ポインタを使用して 2 つの配列をソートする


void sortPtr(int rNum, int* a, int aNum, int* b, int bNum) {
    
    
  int* p, * q;
  int* r = (int*)malloc((aNum + bNum) * sizeof(int));
  int* res = r;

  for (p = a, q = b; p < a + aNum && q < b + bNum;) {
    
    
    if (*p > *q) {
    
    
      *r++ = *q++;
    }
    else {
    
    
      *r++ = *p++;
    }
  }
  if (p < a + aNum) {
    
    
    for (; p < a + aNum;)
      *r++ = *p++;
  }
  else if (q < b + bNum) {
    
    
    for (; q < b + bNum;)
      *r++ = *q++;
  }
  for (r = res; r < res + aNum + bNum; ++r) {
    
    
    cout << *r << ' ';
  }
  cout << endl;
}

ポインタを使用して配列を反復処理する

//遍历数组时,要知道该数组的长度,以免指针超出数组的范围,导致读取数据失败
void testStr(string* p, int size) {
    
    
  for (int i = 0; i < size; ++i) {
    
    
    cout << p << endl;
    ++p;
  }
}

//遍历字符数组时,
void testChar(const char* p) {
    
    
  while (*p) {
    
    
    cout << *p << endl;
    ++p;
  }
}

おすすめ

転載: blog.csdn.net/qq_33021529/article/details/127501745
おすすめ