指针
一、概念
指针也就是内存地址,指针变量是用来存放内存地址的变量(指针变量的内容存储的是其指向的对象的首地址)。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。
举个🌰子: int *a ; 则 *a就是指针变量的数据本身,a就是指针变量的地址(指向的变量的地址)。
[*了解]:不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。
二、定义方法
int *a;
char *b;
float *c;
结构体类型(自定义) *d;
...
注: int* a;int*a;int *a;都能被识别,同等意思;
三、初始化
只有初始化才能操作数据,如果不初始化,指针变量就没有初始的存储单元(存放的位置)不能赋值数据,初始化就是给予指针一个可操作的地址单元,通俗来讲就是给予一个存放数据的小格子。
注:int *a = 1; ❌ //该情况是没有初始化就赋值了。
int *a = (int *)malloc(sizeof(int));
int *a = new int;
int *a = &已定义的int型变量;//使用如下
int num;
//格式①
int *a = # //&取出num变量的地址
//格式②
int *a;
a = #
四、应用
操控int变量
代码
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int num = 1;
int *a;
a = #
cout<<a; //输出的是a指针指向的地址,即num的地址
cout<<*a<<endl; //输出的是a指向的地址的数据,即num值
*a = 10; //赋值
//a = 10 //a只接受地址,*a才是对数据的操作,此处报错
cout<<*a<<endl;
*a += 1; //运算
cout<<*a<<endl;
return 0;
}
结果
0x7fff0fc960a41 //地址每次运行都不同,只供参考
10
11
操作数组(重点)
代码
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
int num[4] = {10,20,30};
int *a = num; //*a是地址
// *a = 5;
cout<<"a首元地址 :"<<a<<endl; //a首元地址
printf("a[0] :%d\n",*a); //a[0]
printf("a[0]+1 :%d\n",*a+1); //a[0]+1
//两种取值方式
printf("a[1] :%d\n",*(a+1));
printf("a[1] :%d",a[1]); //**重点,常用
return 0;
}
结果
a首元地址 :0x7fff9d358af0
a[0] :10
a[0]+1 :11
a[1] :20
a[1] :20
数值交换
代码
#include<iostream>
using namespace std;
void exchange(int *a,int *b){
int c = *a;
*a = *b;
*b = c;
}
void swap(int &a,int &b){
int c = a;
a = b;
b = c;
}
int main(){
int a = 1,b = 2;
//指针实现变量交换
exchange(&a,&b);
printf("exchange:a:%d b:%d\n",a,b);
//取地址符 实现变量交换
int c = 3,d = 4;
swap(c,d);
printf("swap:c:%d d:%d",c,d);
return 0;
}
结果
exchange:a:2 b:1
swap:c:4 d:3
数据结构——结构体+指针 创建 链表
指针本身就像一个链子,它可以拴住和他相同类型的元素
利用此特性我们就可以构建一种数据结构——链表
| 指针域 next 0x777 | 数据域 date | 元素0:地址:0x666
|
===> | 指针域 next 0x888 | 数据域 date | 元素1:地址:0x777
|
===> | 指针域 next | 数据域 date | 元素2:地址:0x888
补充:”->“ 用来操作指针结构体中变量 | “.”用来获取普通结构体的变量
元素0->date 就是元素0的值
元素0->next 就是元素2的地址(有了地址就可以对值操作)
元素0->next.date 就是元素2的值
代码
#include<iostream>
#include<cstdio>
using namespace std;
//结构体
struct Node/*Node 结构体类型名称,命名方便内部套娃*/{
Node *next;//指针构建链表
int date;
}*head;//head表头,不存值;
//头插法
void insert(int num){
//创建结点(也要是指针类型,要与结构体对应)
Node *p = new Node;
//写入数据
p->date = num;
//插入表头
//注意修改的是头结点(head)的指针域(next)
//head = p ❎会导致头结点被覆盖
p->next = head->next;
head->next = p;
}
int main(){
//初始化
head = new Node;
//插入元素 3个 [1,2,3]
insert(1);
int a = 2;
insert(a);
insert(a+1);
//遍历(头插法输出是逆序)
for(Node *p = head->next;p != NULL;p = p->next){
printf("%d ",p->date);
}
return 0;
}
结果
3 2 1
五、拓展
指向指针的指针
🌰子:int **a; //指向int指针的指针
a存放——int指针的地址
*a的数据是——int指针指向地址
不明白看下图
int num = 1;
int *b = #
int **a = &b;
多级指针
结构体+指针 模拟的链表有点相似
是不是明白了什么。。。(不要套娃🪆!!!)
写的有点着急,有错误请指正,多多包涵(#.#)