C++ 入門 05 — ポインター

1. ポインタの基本概念

ポインタの役割: ポインタを通じて間接的にメモリにアクセスできます

  • メモリ番号は0から記録されており、一般的には16進数で表されます。

  • ポインタ変数を使用してアドレスを保存できます

 

2. ポインタ変数の定義と使用方法

ポインタ変数定義の構文:数据类型 * 变量名;

例:

#include <iostream>
using namespace std;

int main() {

	//1、指针的定义


	int a = 10; //定义整型变量a
	int* p;  //指针定义语法: 数据类型 * 变量名 ;


	//指针变量赋值
	p = &a; //指针指向变量a的地址
	cout << "数据a的地址"<< & a << endl; //打印数据a的地址
	cout <<"指针变量p的值:"<< p << endl;  //打印指针变量p


	//2、指针的使用
    // 通过解引用的方式找到指针指向的内存
	//指针前加*表示解引用,通过*操作指针变量指向的内存
	cout << "通过*操作指针变量指向的内存 *p = " << *p << endl;

	system("pause");

	return 0;
}

 

実行結果は次のようになります。
a = 10;

p = &a; (p は変数 a のアドレスを表すポインタ変数)

*p=a=10; (*p は、アプリケーション ポインタ変数内のアドレスを通じて、アドレス内の対応するデータにアクセスします)

 

ポインタ変数と通常の変数の違い

  • 通常の変数にはデータが格納され、ポインタ変数にはアドレスが格納されます。

  • ポインタ変数は、「*」演算子を使用して、ポインタ変数が指すメモリ空間で操作できます。このプロセスは逆参照と呼ばれます。

要約 1: & 記号を使用して変数のアドレスを取得できます

要約 2: ポインタを使用してアドレスを記録する

要約 3: ポインタ変数を逆参照すると、ポインタが指すメモリを操作できるようになります。

 

3. ポインタが占めるメモリ空間

質問: ポインターもデータ型ですが、このデータ型はどれくらいのメモリ領域を占有するのでしょうか?

 

例:

#include <iostream>
using namespace std;

int main() {
	
	// 指针所占内存空间
	// 初始化
	int a = 10;
	int* p;
	p = &a; //指针指向数据a的地址

	cout << *p << endl; //* 解引用
	cout << sizeof(p) << endl;
	cout << sizeof(char*) << endl;
	cout << sizeof(float*) << endl;
	cout << sizeof(double*) << endl;

	system("pause");

	return 0;
}

 

概要: 32 ビット オペレーティング システムでは、すべてのポインター タイプは 4 バイトです

 

4. ヌルポインタとワイルドポインタ

4.1 ヌルポインタ

Null ポインタ: ポインタ変数はメモリ内の番号 0 の空間を指します

目的:ポインタ変数が最初にどこを指しているかわからない場合は、番号 0 のスペースを指すことができます。つまり、ポインタ変数を初期化できます< /span>

注:null ポインタが指すメモリにはアクセスできません

例 1: Null ポインター

#include <iostream>
using namespace std;

int main() {

	// 空指针
	// 1.空指针用于给指针变量进行初始化

	//指针变量p指向内存地址编号为0的空间
	int* p = NULL;

	//访问空指针报错 
	// *p = 100; // 会报错
	//内存编号0 ~255为系统占用内存,不允许用户访问
	cout << *p << endl;

	system("pause");

	return 0;
}

 

4.2 野指针

ワイルド ポインタ: ポインタ変数が不正なメモリ領域を指しています

例 2: ワイルド ポインター

int main() {
​
    //指针变量p指向内存地址编号为0x1100的空间
    int * p = (int *)0x1100;
​
    //访问野指针报错 
    cout << *p << endl;
​
    system("pause");
​
    return 0;
}

概要: null ポインタもワイルド ポインタも、私たちが申請した領域ではないため、アクセスしないでください。

5. const 変更ポインタ

const がポインターを変更する場合には 3 つの状況があります。

  1. const 変更ポインタ --- 定数ポインタ

  2. const 変更された定数 --- ポインタ定数

  3. const はポインタと定数を変更します

定数ポインタ:

const がポインタ int *p を変更すると、*p は変更できなくなります。

 

 ポインタ定数:

const は定数 p=&a を変更するため、p=&a の値は変更できません。

const はポインタと定数を変更します。

要約:

const が何かを変更する場合、変更されたものは変更できません。

 

例:

#include <iostream>
using namespace std;

int main() {

	int a = 10;
	int b = 10;

	// 1.常量指针
	//const修饰的是指针,指针指向可以改,指针指向的值不可以更改
	const int* p1 = &a;
	p1 = &b; //正确
	//*p1 = 100;  报错

     // 2.指针常量
	//const修饰的是常量,指针指向不可以改,指针指向的值可以更改
	int* const p2 = &a;
	//p2 = &b; //错误
	*p2 = 100; //正确

	//const既修饰指针又修饰常量
	const int* const p3 = &a;
	//p3 = &b; //错误
	//*p3 = 100; //错误

	system("pause");

	return 0;
}

ヒント: const の右辺がポインタか定数かを確認し、ポインタの場合は定数ポインタ、定数の場合はポインタ定数です。

6. ポインタと配列

機能:ポインタを使用して配列内の要素にアクセスする

例:

#include <iostream>
using namespace std;

int main() {

	// 利用指针访问数组中的元素

	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };

	int* p = arr;  //指向数组的地址  arr就是数组的地址

	cout << "第一个元素: " << arr[0] << endl;
	cout << "指针访问第一个元素: " << *p << endl;

	for (int i = 0; i < 10; i++)
	{
		//利用指针遍历数组
		cout << *p << endl;
		p++; // 让指针向后偏移4个字节
	}

	system("pause");

	return 0;
}

7. ポインタと関数

関数:ポインタを関数パラメータとして使用して、実際のパラメータ値を変更します

例:

#include <iostream>
using namespace std;

//实现2个数字进行交换


//方式1:值传递
void swap1(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
}
//方式2:地址传递
void swap2(int* p1, int* p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

int main() {

	int a = 10;
	int b = 20;
	swap1(a, b); // 值传递不会改变实参
	cout << "通过值传递swap1(int a, int b)的结果: "  << endl;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;


	swap2(&a, &b); //地址传递会改变实参
	cout << "通过地址传递swap2(int* p1, int* p2)的结果: " << endl;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	system("pause");

	return 0;
}

例証します: 

 

概要: 実際のパラメータ (関数に渡される元のデータ) を変更したくない場合は値転送を使用し、実際のパラメータを変更したい場合はアドレス転送を使用します。

8. ポインタ、配列、関数

ケースの説明:関数をカプセル化し、バブル ソートを使用して整数配列を昇順に並べ替えます

たとえば、配列: int arr[10] = {4,3,6,9,1,2,10,8,7,5};

例:

#include <iostream>
using namespace std;

//冒泡排序函数
void bubbleSort(int* arr, int len)  //int * arr 也可以写为int arr[]
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}

//打印数组函数
void printArray(int arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << endl;
	}
}

int main() {

	int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
	int len = sizeof(arr) / sizeof(int);

	bubbleSort(arr, len);

	printArray(arr, len);

	system("pause");

	return 0;
}

 

概要: 配列名がパラメーターとして関数に渡されると、配列名は最初の要素へのポインターに縮退されます。

おすすめ

転載: blog.csdn.net/m0_55196097/article/details/134100128