目次
7ポインター
7.1ポインタの基本概念
ポインタの役割:メモリはポインタを介して間接的にアクセスできます。
メモリ番号は0から記録され、通常は16進数で表されます。
ポインタ変数を使用してアドレスを保存できます。
メモリには0から始まるアドレス番号があり、通常は16進数を使用して番号を表します。ポインタを使用して、アドレス番号を記録できます。
int a = 10; // 4バイトのスペース
変数を作成するたびに、アドレス番号を記録する必要があります。このデータを使用するのは不便なので、この変数を使用できます。
住所番号がわかれば、データも取得できます。ポインタはアドレスです。アドレス番号を記録してください。
7.2ポインタ変数の定義と使用
ポインター変数定義構文:
数据类型 * 变量名;
例
ポインタ変数と通常の変数の違い:
通常の変数はデータを格納し、ポインタ変数はアドレスを格納します。
ポインタ変数は、「*」演算子を使用して、ポインタ変数が指すメモリ空間を操作できます。このプロセスは、間接参照と呼ばれます。
メモリはpで見つけることができ、メモリは* pで変更できます。
ポインタの役割(目的):メモリに間接的にアクセスし、メモリへの読み取りおよび書き込み操作(変更、アクセス)を行うことができます!
#include <iostream>
using namespace std;
int main()
{
//1、指针的定义
int a = 10; //定义整型变量a
//指针定义的语法:数据类型 * 指针变量名 ;
int *p; // point代表指针
//指针变量赋值 让指针记录变量a的地址
p = &a; //指针p指向(等于)变量a的地址【取地址符号& 取变量a的地址】建立变量与指针之间的关系
cout << "a的地址为:" << &a << endl; //打印数据a的地址:0x61fe14
// cout << "a的地址为:" << (int)&a << endl; //十六进制转整型
cout << "指针p为:" << p << endl; //打印指针变量p:0x61fe14【指针就是一个地址,记录地址编号!】
//2、指针的使用
//可以通过“解引用”的方式来找到指针指向的内存
//指针前加一个* 代表 解引用,找到指针指向的内存中的数据
//通过*操作指针变量指向的内存
cout << "*p = " << *p << endl; // 10
*p = 1000; //解引用 通过指针间接地找到了a的内存 通过解引用拿到p指向的内存中的数据(进行 修改、读取)
cout << "a = " << a << endl;
cout << "*p = " << *p << endl;
system("pause");
return 0;
}
要約1:&記号を使用して変数のアドレスを取得できます。
要約2:ポインターを使用してアドレスを記録します。
要約3:ポインター変数を逆参照します。ポインターが指すメモリーを操作できます。
7.3ポインタが占めるメモリ空間
質問:ポインタもデータ型ですが、このデータ型はどのくらいのメモリスペースを占有しますか?
概要:すべてのポインタータイプは、32ビットオペレーティングシステムでは4バイト、64ビットオペレーティングシステムでは8バイトです。
例
#include <iostream>
using namespace std;
int main() //指针所占内存空间
{
int a = 10;
// int *p;
// p = &a; //指针指向数据a的数据地址
int *p = &a; //建立关系
//在32位操作系统下,指针是占4个字节空间大小(不管是什么数据类型)
//在64位操作系统下,指针是占4个字节空间大小(不管是什么数据类型)
cout << *p << endl; //10 * 解引用
cout << "sizeof(p) = " << sizeof(p) << endl; //8 查看变量(数据类型)占用的内存空间
cout << "sizeof(int *) = " << sizeof(int *) << endl; //8
cout << "sizeof(float *) = " << sizeof(float *) << endl; //8
cout << "sizeof(double *) = " << sizeof(double *) << endl; //8
cout << "sizeof(char *) = " << sizeof(char *) << endl; //8
system("pause");
return 0;
}
7.4ヌルポインタとワイルドポインタ
ヌルポインタ:ポインタ変数は、メモリ内の0という番号のスペースを指します。メモリースティックには、0から始まり増加する独自の番号があります。0の番号が付いたポインタを指すことは、「nullポインタ」と呼ばれます。
目的:ポインタ変数を初期化します。ポインタがどこを指すかわからなくなるとすぐに、メモリ内の0という番号のスペースを指します。
注: NULLポインターが指すメモリーにはアクセスできません。nullポインタが指すメモリにアクセスする権利はありません。0から255までのメモリはシステムによって占有されています。アクセスされると、エラーが発生します。
例1:ヌルポインター
#include <iostream>
using namespace std;
int main() //空指针
{
//1、空指针用于给指针变量进行初始化
// int * p;//指针指向哪?未知!所以,一般会让指针指向NULL(空)
int *p = NULL; //指针变量p指向内存地址编号为0的空间
//2、空指针是不可以进行访问的
//0~255之间的内存编号是系统占用的,因此不可以访问
*p = 100; //直接引用 操作内存
//访问空指针报错
//内存编号0 ~255为系统占用内存,不允许用户访问
cout << *p << endl;
//system("pause");
return 0;
}
例2:ワイルドポインター
ワイルドポインタ:ポインタ変数が不正なメモリスペースを指しています。不正なメモリスペース:ユーザーが要求したメモリスペースではありません。
#include <iostream>
using namespace std;
int main() //野指针 在程序中,尽量避免出现野指针
{
// int *p = NULL;
//指针变量p指向内存地址编号为0x1100的空间【0x1100:十六进制数字】
int *p = (int *)0x1100; //变为地址:(int *)强转为指针类型
//0x1100随便在内存中指向了这样一个编号,这个编号中的数 无权利操作!没有申请,无权利操作!
//举例:花钱买房间A(int a = 10; int *p = &a;),没有权利去房间B(房间B->野指针)
cout << *p << endl; //访问野指针报错
system("pause");
return 0;
}
総括する
概要:ヌルポインターとワイルドポインターは、申請したスペースではないため、アクセスしないでください。
7.5const変更されたポインター
const変更ポインターには3つのケースがあります。
constの変更ポインタ-定数ポインタ のconst int型* P1 =&;
const変更定数-ポインタ定数 int * const p2 =&a;
constは、ポインターと定数の両方を変更します
1、const変更されたポインター-定数ポインター
赤いボックス:制限されており、変更できません。黒い線:変更できます。
2.const修正定数-ポインター定数
赤い線:制限されており、変更できません。黒いボックス:変更できます。
3. constは、ポインターと定数の両方を変更します
例
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int b = 10;
//int *p0 = &a; //普通写法
//1、常量指针(记法:const在前 先常量 后指针)
//const修饰的是指针,指针的指向可以更改,指针指向的值不可以更改(可以理解为const 修饰的是解引用 int*,所以指针指向的值不可以更改)
const int *p1 = &a;
p1 = &b; //正确
// *p1 = 20; //错误
//2、指针常量(记法:int* 在前 先指针 后常量)
//const修饰的是常量,指针的指向不可以更改,指针指向的值可以更改(可以理解为const修饰的是指针本身,所以指针指向的值不可以修改)
int *const p2 = &a;
*p2 = 100; //正确
//p2 = &b; //错误,指针常量 指针的指向不可以更改
//3、const既修饰指针又修饰常量
const int *const p3 = &a;
//指针的指向和指针指向的值都不可以改
//*p3 = 100; //错误
//p3 = &b; //错误
system("pause");
return 0;
}
ヒント: constの右側がポインターであるか定数であるか、ポインターが定数ポインターであるか、定数がポインター定数であるかを確認します。
7.6ポインタと配列
役割:ポインターを使用して、配列内の要素にアクセスします。配列:連続空間には、同じタイプのデータ要素が格納されます。
例
#include <iostream>
using namespace std;
int main()
{
//指针和数组
//让(利用)指针也能访问数组中的每一个元素
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
cout << "第一个元素为:" << arr[0] << endl;
int *p = arr; //指向数组的指针 数组是整型的,所以创建整型指针,指向数组的地址 arr数组名就是数组的首地址
//指针指向数组首地址,对指针进行解引用的操作,就可以解出数组中的第一个元素
cout << "利用指针访问第一个元素:" << *p << endl; //*p解引用
p++; //指向数组中的第二个元素,让指针向后偏移(移动)4个字节(整型指针)
cout << "利用指针访问第二个元素:" << *p << endl; //*p解引用
cout << "利用指针遍历数组:" << endl;
int *p2 = arr;
for (int i = 0; i < 10; i++) //利用指针遍历数组
{
// cout << arr[i] << endl;
cout << *p2 << endl;
p2++;
}
system("pause");
return 0;
}
7.7ポインタと関数
役割:ポインターを関数パラメーターとして使用して、実際のパラメーターの値を変更します。
例
ポインタはアドレスを保持します。アドレスを渡すことにより、実際のパラメータデータを間接的に変更することができます。
#include <iostream>
using namespace std;
//1、值传递:实现两个数字进行交换
void swap01(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "swap01中 a = " << a << endl;
cout << "swap01中 b = " << b << endl;
}
//2、地址传递
void swap02(int *p1, int *p2)
{
int temp = *p1; //解出内存 解引用
*p1 = *p2;
*p2 = temp;
cout << "swap02中 *p1 = " << *p1 << endl;
cout << "swap02中 *p2 = " << *p2 << endl;
}
int main() //指针和函数
{
int a = 10;
int b = 20;
//1、值传递不会改变实参
swap01(a, b);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
//2、地址传递会改变实参
//将a、b变量地址传入函数体中,用指针接受地址【如果是地址传递,可以修饰实参】
swap02(&a, &b);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
system("pause");
return 0;
}
概要:実際のパラメーターを変更したくない場合は、値で渡します。実際のパラメーターを変更したい場合は、アドレスで渡します。
7.8ポインタ、配列、関数
ケースの説明:関数をカプセル化し、バブルソートを使用して、整数配列の昇順ソートを実現します。
たとえば、array:int arr [10] = {4,3,6,9,1,2,10,8,7,5};
例
#include <iostream>
using namespace std;
//冒泡排序函数【参数1:数组首地址;参数2:数组长度】
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]) //如果j > j + 1的值,交换数字
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//打印数组函数
void printArray(int arr[], int len) //void printArray(int *arr, int len)
{
for (int i = 0; i < len; i++)
{
// cout << arr[i] << endl;
cout << arr[i] << "、";
}
}
int main()
{
//1、创建一个数组
int arr[10] = {4, 3, 6, 9, 1, 2, 10, 8, 7, 5};
//数组长度
int len = sizeof(arr) / sizeof(int);
//2、创建一个函数实现冒泡排序
bubbleSort(arr, len); //传递数组地址arr:数组名就是数组的首地址
//3、打印排序后的数组
printArray(arr, len); //传递数组地址arr
system("pause");
return 0;
}
概要:配列名がパラメーターとして関数に渡されると、最初の要素へのポインターに縮退します。