#include <iostream>
using namespace std;
/*
指针 : 通过指针间接的访问某块内存;
—— 内存的编号都是从 0 开始记录的 , 一般用十六进制数字表示
—— 可以利用指针变量来保存某一特定的地址
( 指针 是一种特殊的内存空间 , 保存着某一变量所在的内存空间的十六位地址 )
( 可理解为 —— 指针 就是 一个地址 , 存的是地址 ,本质是变量 )
定义 : 数据类型 * 变量名 ;
解引用 : 为了查看该指针 所 指向的内存空间所存放的数据
指针所占内存空间 : 在 32 位操作系统下 , 任何类型的指针都占用四个字节
在 64 位操作系统下 , 任何类型的指针都占用八个字节
( 通过修改本界面 菜单栏 ×86 / ×64 选择操作系统类型)
空指针定义 : 指针变量指向内存中编号为 0 的空间
****************************************************************
int * p = NULL; // NULL 代表 0
*****************************************************************
用途 : 初始化指针变量
注意 : 空指针指向的内存是不可以访问的 , 因为 编号 0 ~ 255 之间的内存编号是系统占用的
( 语法无逻辑上的错误 ,在运行过程中会出现错误并提示 “引发了异常,写入访问权限冲突” )
( ******** 其实是虚拟内存 , 内核态可以访问 *********** )
野指针 : 指针变量指向非法内存 , 所以 “ 野 —— 就很过分 ” 。
运行野指针会出错 , 因为程序并没有申请使用野指针指向的内存空间
没有声明 则 没有对该内存空间的使用权限 , 不得 “ 非 法 —— 野 ” 使用 。
请慎用空指针和野指针。
const 修饰指针 : 1. const 修饰指针 —— 常量指针
2. const 修饰常量 —— 指针常量
3. const 即修饰指针 , 又修饰常量
指针和数组 : 利用指针访问数组中元素
指针和函数 : 利用指针做函数的参数 , 可以修改参数的值
1. 值传递(函数)
2. 地址传递 —— 将变量的地址 & 传递给函数 , 函数参数列表定义指针接收该地址
( 会改变实参 )
( 以指针为指向 , 通过解引用 , 对指向的地址 , 对该地址内的值进行修改 ,不会取该值另外 “赋出” )
函数数组指针 : 冒泡排序函数
—— 把数组传送到函数之中 , 需要传递数组首地址 , 用指针去接收
—— 数组长度在函数为计算 ,传递给函数 , 代码更加健壮
*/
// 函数值传递
void swap01(int num0, int num1) {
int temp = num0;
num0 = num1;
num1 = temp;
cout << " swap01 中 num0 = " << num0 << endl;
cout << " swap01 中 num1 = " << num1 << endl;
}
// 函数地址传递
void swap02(int * num2, int * num3) {
int temp = *num2;
*num2 = *num3; // * num2 本身就是解引用指向
*num3 = temp; // (改地址所拥有的值)并对(该地址上的值进行修改)
cout << " swap02 中 num2 = " << num2 << endl;
cout << " swap02 中 num3 = " << num3 << endl;
}
// 冒泡排序
void bubbleSort( int * arr1 , int len) {
for (int num4 = 0; num4 < len - 1; num4++) {
for (int num5 = 0; num5 < len - num4 - 1; num5++) {
if (arr1[num5] > arr1[num5 + 1]) {
int temp = arr1[num5];
arr1[num5] = arr1[num5 + 1];
arr1[num5 + 1] = temp;
}
}
}
}
// 数组打印函数
void printArray(int * arr1 , int len) {
for (int num6 = 0; num6 < len; num6++) {
cout << arr1[num6] << " \t";
}
cout << endl;
}
int main() {
// 1. 定义指针
int a = 10;
// 指针定义的语法 : 数据类型 * 指针变量名
int * p0; // p 代表含义为 point , 用其他字母也可以 , 约定俗成用 p
// 让指针与变量 a 的地址建立联系
p0 = &a;
cout << " a 的地址为 : " << &a << endl;
cout << " 转化为十进制为 :" << (int)&a << endl;
cout << " p 的值为 : " << p0 << endl;
cout << " 转化为十进制为 :" << (int)p0 << endl;
// 2. 使用指针 —— 可以通过 解引用 的方式找到指针执行的内存中的数据
// 指针前加 * 代表解引用 , 找到指针指向的内存所存放的数据
cout << " 未利用解引用 *p 时 , *p 的值为 :" << *p0 << endl;
cout << " 未利用解引用 *p 时 , a 的值为 :" << a << endl;
*p0 = 1000; // 此处 *p 指的数据是上文的 " a = 10 " ,
cout << " 解引用 *p = 1000 \n " ;
cout << " 利用解引用 *p 时 , *p 的值为 : " << *p0 << endl;
cout << " 利用解引用 *p 时 , a 的值为 : " << a << endl;
cin.get();
// 指针所占用的内存空间
int b = 20;
// int * p;
// p = &a;
int * p1 = &a; // 与上面两行代码等价 , 即指针可以在创建时赋值
cout << " sizeof int * = , 即指针的内存空间: " << sizeof(p1) << endl;
cout << " sizeof int * = , 即指针的内存空间: " << sizeof(int *) << endl;
cout << " sizeof double * = , 即指针的内存空间: " << sizeof(double *) << endl;
cout << " sizeof float * = , 即指针的内存空间: " << sizeof(float *) << endl;
cout << " sizeof char * = , 即指针的内存空间: " << sizeof(char *) << endl;
cin.get();
// 空指针
/* **********************************************
// 1. 给指针变量进行初始化
int * p = NULL; // NULL 代表 0
// 2. 空指针不可以被访问
*p = 100 ; // 语法无逻辑上的错误 ,在运行过程中会出现错误并提示 “引发了异常,写入访问权限冲突”
cin.get();
***************************************************/
// 野指针
/* **********************************************
int * p2 = (int *)0x1100 ;
cout << *p << endl;
cin.get(); // 运行野指针会出错 , 因为程序并没有申请使用野指针指向的内存空间
没有声明 则 没有对该内存空间的使用权限 , 不得 “ 非 法 —— 野 ” 使用 。
*****************************************************/
// const 修饰指针 —— 常量指针
int c = 5 , d = 10 ;
const int * p3 = &a; // 用 const 去修饰 指针 ( int * p3 )
// ****************************************************
// *p3 = 20 ; // 错误 , 常量指针指向的内存的值不可修改
// p3 = &d ; // 正确 , 常量指针的指向可以修改
// *********************************************************/
// const 修饰常量 —— 指针常量
int e = 20, f = 30;
int * const p4 = &a; // 用 const 修饰常量 , 为指针常量
// ****************************************************
// *p4 = 20 ; // 正确 , 指针常量指向的内存的值可修改
// p4 = &d ; // 错误 , 指针常量的指向不可以修改
// *********************************************************/
// const 修饰常量 且 修饰指针
int g = 100, h = 200;
const int * const p5 = &g;
// ****************************************************
// *p5 = 20 ; // 错误 ,
// p5 = &d ; // 错误 , 指向 及 指向的值 均不可修改
// *********************************************************/
cin.get();
int arr0[10] = { 0 ,1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
cout << (int)arr0 << endl;
int * p6 = arr0; // 指针指向的该数组的首地址 ,即第一个元素
for (int i = 1; i <= 10; i++) {
cout << " 利用指针访问数组第 "<< i << " 个元素是 : " << *p6 << endl;
cout << " 他们所对应的十进制地址分别为 " << (int)&arr0[i - 1] << endl;
p6++; // 因为指针本身就是整型 , p6++ 为向后偏移四个字节
}
cin.get();
int num0 = 10 , num1 = 20;
cout << " 实参num0 = " << num0 << endl;
cout << " 实参num1 = " << num1 << endl;
swap01(num0, num1);
cout << " 实参num0 = " << num0 << endl;
cout << " 实参num1 = " << num1 << endl;
cin.get();
int num2 = 10, num3 = 20;
cout << " 实参num0 = " << num2 << endl;
cout << " 实参num1 = " << num3 << endl;
swap02(&num2, &num3);
cout << " 实参num0 = " << num2 << endl;
cout << " 实参num1 = " << num3 << endl;
cin.get();
// 函数 数组 指针 —— 冒泡排序案例
// 1. 创建数组
int arr1[10] = { 88 , 42 ,16 , 59 , 67 , 3 , 99 , 85 , 36 , 46 };
// 数组长度
int len = (sizeof(arr1) / sizeof(arr1[2]));
printArray(arr1, len);
// 2. 创建函数 , 实现冒泡排序
bubbleSort(arr1, len);
// 3. 通过函数实现数组打印
printArray(arr1, len);
cin.get();
cin.get();
return 0;
}
Day8:
最新推荐文章于 2024-01-19 14:06:29 发布