阅读耗时大概 4 分钟
指针是干什么的
指针是如何定义和使用的
指针变量定义的语法: 数据类型 * 变量名
我们来看下下面这张图:
首先我们声明了a = 10,它在内存中的地址是0x0001, 值是10,如果我们想要获取内存地址,可以用 &a,但是如果我们想要操作这块内存,如何办。我们可以声明一个p变量,指向这块地址 0x0001。
这个p就是指针变量。定义方式 为 int p = a
那你有可能会问,怎么用指针,记住一点,**加 就代表解引用,代表指针指向的内存,p指向内存地址,p指针指向的内存地址 解开就是值*
示例
#include<iostream>using namespace std;int main(){int a = 10;int *p = &a;int *b ;b = &a;cout <<"a == " << a << endl;cout << "&a == " << &a << endl;cout << "p == " << p << endl;cout << "*p == " << *p << endl;cout << "b == " << b << endl;cout << "*b == " << *b << endl;*p = 20;cout << "a == " << a << endl;return 0;}结果a == 10&a == 0x61fe0cp == 0x61fe0c*p == 10b == 0x61fe0c*b == 10a == 20
指针占用空间大小
猜猜指针这种数据类型占用多少内存空间呢?
#include<iostream>
using namespace std;
class Person{
int a;
};
int main(){
int a = 10;
int *p = &a;
cout << sizeof(p) << endl;
cout << sizeof(int *) << endl;
cout << sizeof(char *) << endl;
cout << sizeof(float *) << endl;
cout << sizeof(double *) << endl;
Person *pp ;
cout << sizeof(pp) << endl;
}
结果是
8
8
8
8
8
8
我电脑是 64 位操作系统 ,所以是8个字节,如果是 32 位操作系统,是 4 个字节
空指针
空空如也的指针,指针是空的?
空指针是指 指向内存中编号为0的空间,用来初始化指针变量,但是空指针指向的内存是不可以访问的。你就想想java 对象是null的情景吧
#include<iostream>
using namespace std;
int main(){
int *p = NULL;
cout << p << endl; //这一行输出 0 ,内存编号是 0
cout << *p << endl; //我用vscode 运行 并没有报错 只是终端上一直卡着 ,说明不允许访问
*p = 100; //内存编号 0 到 255 为系统占用内存,不允许用户访问
return 0;
}
野指针
这孩子真野
指针变量指向非法的内存空间
#include<iostream>
using namespace std;
int main(){
int *p = (int *)0x1100;//指针变量p指向内存地址0x1100空间
cout << *p << endl; //vscode 运行卡了一会终止了,什么也没有输出,一些编辑器会报错哟,读写访问冲突
return 0;
}
为什么说 p 是野指针,p指向的地址是自己申请的吗?不是,p有权利操作吗?我并不知道,没有人说它有权利操作这块空间。
Const修饰指针
直接看例子
- 常量指针
const 修饰指针
指针的指向可以修改,但是指针指向的值不能修改
int a = 10;
const int *p = &a; //const 放在指针前面,修饰指针,叫指针常量
*p = 20;
执行结果 报错
int b = 20;
p = &b;
执行正确
- 指针常量
const修饰常量
指针的指向不可以修改,但是值可以修改
int a = 10;
int * const p = &a; //const 放在常量前面
*p = 20;
执行结果
正确
int b = 20;
p = &b;
执行报错
- const修饰常量和指针
指针的指向和指针指向的值都不可以修改
int a = 10;
const int * const p = &a;
总结
const放在 指针(int )前面叫 常量指针,说明指针是常量,常量就不能改咯,就是指针指向不能改咯。
const放在指针(int )后面, 变量(p)前面,叫指针常量,const修饰的是变量(p), 说明这个变量值不能改变。
const修饰什么,什么就不能改。
指针和数据
来一个指针访问数组元素例子
#include<iostream>
using namespace std;
int main(){
int arr[] = {1,2,3,4,5,6,0,1,5,8};
int *p = arr;//指向数组的指针
cout << "第一个元素 " << arr[0] << endl;
cout << "第一个元素 " << (*p) << endl;
for(int i = 0; i< sizeof(arr) / sizeof(int);i++){
cout << *p << "\t" ;
p++;
}
cout << endl;
return 0;
}
输出结果:
第一个元素 1
第一个元素 1
1 2 3 4 5 6 0 1 5 8
所以说指针指向的是 数组第一个地址,不信自己打印去
指针和函数
最大的好处,就是利用指针作函数参数,可以修改实参的值,也就是引用传递,之前普通函数那一章描述过值传递
把值传递代码copy 改一下 运行下示例
#include<iostream>
using namespace std;
void swap(int * a, int * b){
cout << "a = " << *a << endl;
cout << "b = " << *b << endl;
int temp = *a; //只是交换值,可千万别定义 int * temp = a;来修改指向
*a = *b;
*b = temp;
cout << "swap doned a = " << *a << endl;
cout << "swap doned b = " << *b << endl;
}
int main(){
int a = 10;
int b = 20;
swap(&a,&b); //传入引用
cout << "global a = " << a << endl;
cout << "global b = " << b << endl;
return 0;
}
输出结果:
a = 10
b = 20
swap doned a = 20
swap doned b = 10
global a = 10
global b = 20
来一个指针法冒泡
#include<iostream>
using namespace std;
void sort(int * arr, int len){
for(int i = 0;i < len - 1;i++){
bool isSorted = true;
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;
isSorted = false;
}
}
if(isSorted){
break;
}
}
}
int main(){
int arr[] = {8 , 5, 3, 2, 4, 0, 9,1,4,6};
int len = sizeof(arr) / sizeof(int);
sort(arr, len);
for(int i = 0;i < len; i++){
cout << arr[i] << "\t";
}
cout << endl;
return 0;
}
结果输出:
0 1 2 3 4 4 5 6 8 9
