当年这里学得乱七八糟,现在需要反复康康,遇到问题就会补进来噢。
指针
// int* ptr = arr; 等价于 int*ptr = &arr[0];
// int ar[] = &arr[1]; 将arr[1]的地址,赋值给ar[],即 &ar[0] = &arr[1], ar[]以arr[1]为首地址
void fun(int* ptr, int ar[], int val){
*ptr = 3; // ptr为指针,指向arr首地址,改变ptr所指地址保存的值,就改变了arr[0] = 3
*ar = 3; // *ar为取ar[0]地址保存的值,并改为3,
val = 3; // 改变形参的值,对实参无影响
}
int main(){
int arr[3]={1,2};
fun(arr, &arr[1], arr[2]);
printf("%d%d%d",arr[0],arr[1],arr[2]);
} // 输出 3 3 0
int arr[]={6,12,8,9,10};
int * ptr;
ptr=arr; // ptr指向arr首地址 arr[0]
//Eg1
cout<<*(ptr+2); // 8 // 选择ptr指针所指地址后面2单元的地址,即arr[2],再取其值 8
*(ptr+2)+=2; // 更改 ptr指针所指地址后面2单元的地址 所存元素的值,再改变此值 8+2
printf("%d,%d ",*ptr,*(ptr+2)); // 6 10 // ptr本身的指向没变,仍指向arr[0]
//Eg2
cout<<*(ptr++)<<endl; // 6 // 先取ptr所指地址保存的值6,再将ptr指针后移两单元,指向arr[1]
cout<<*ptr<<endl; // 12 // 上一行已经改变了ptr的指向,取其值:12
*(ptr+2)+=2; // 更改 ptr指针所指地址后面2单元的地址 所存元素的值,再改变此值9+2
printf("%d,%d ",*ptr,*(ptr+2)); // 12 11
// 初始ptr指向arr[0],在第9行移动后指向arr[1],ptr在11行指向不动--arr[1],只更改了arr[3]的值
指针和引用区别?
指针 | 引用 |
---|---|
指针是具体变量,需要占用存储空间。 | 引用只是别名,不占用具体存储空间,只有声明没有定义 |
sizeof() 是指针的大小,=4 | sizeof() 是被引用对象的大小 |
指针声明和定义可以分开,可以先只声明指针变量而不初始化,等用到时再指向具体变量。可以被初始化为NULL | 引用在声明时必须初始化为另一变量,必须有具体实体 |
指针变量可以重新指向别的变量。 | 引用一旦初始化之后就不可以再改变(变量可以被引用为多次,但引用只能作为一个变量引用) |
作为参数传递,指针需要被解引用才可以对对象进行操作 | 作为参数传递,直接对引用的修改会改变引用所指向的对象 |
有const指针,指针可以有多级 | 没有const引用,且引用只有一级 |
使用++运算符的意义不一样 | |
返回动态内存分配的对象or内存,必须使用指针 | 若使用引用,可能引起内存泄漏 |
区别以下指针类型?
int *p[10]
int (*p)[10]
int *p(int)
int (*p)(int)
- int *p[10]表示指针数组,强调数组概念,是一个数组变量,数组大小为10,数组内每个元素都是指向int类型的指针变量。
- int (*p)[10]表示数组指针,强调是指针,只有一个变量,是指针类型,不过指向的是一个int类型的数组,这个数组大小是10。
- int *p(int)是函数声明,函数名是p,参数是int类型的,返回值是int *类型的。
- 可理解为 int* p (int) →→ type p (int)
- int (*p)(int)是函数指针,强调是指针,该指针指向的函数具有int类型参数,并且返回值是int类型的。
- *p是一体的,是个指针
常量指针和指针常量区别?
- 常量指针读成常量的指针,是指向一个只读变量的指针。如 int const *p 或 const int *p,即不可更改p的值。
- 指针常量是一个不能改变指向的指针。如int *const p。
数组名和指针(这里为指向数组首元素的指针)
- 二者均可通过增减偏移量来访问数组中的元素。
- 数组名不是真正意义上的指针,可以理解为常指针,所以数组名没有自增、自减等操作。
- 当数组名当做形参传递给调用函数后,就失去了原有特性,退化成一般指针,多了自增、自减操作,但sizeof运算符不能再得到原数组的大小了。
野指针是什么?
向一个已删除对象or未申请访问受限内存区域的指针
- 也叫空悬指针,不是指向null的指针,是指向垃圾内存的指针。
产生原因及解决办法:
- 指针变量没有及时初始化。 ∴ 定义指针变量,要么及时初始化,要么置空。
- 指针free或delete之后没有及时置空。 ∴ 释放操作后立即置空。
获取成员
在写链表或者二叉树的时候,避免不了会用到指针or引用,来康康吧~
struct Node {
int val;
Node *next; // 指针
Node(int x) : val(x), next(NULL) {}
};
int main (){// a->b->c->d->e
// A: 结构体abe
Node a(1);
Node b(2);
Node e(5);
// B: 结构体类型的指针,即指向结构体的指针cd
Node *c = nullptr;
Node *d = nullptr;
// 指针用->获取成员
c->val = 3;
d->val = 4;
/* 左侧next为一个指针,赋值时应赋一个地址给它,所以等号右侧为:
(1) &A(取abe的地址)
(2) B (指针cd本身是一个变量,它存了一个值,该值是它所指向变量的地址)*/
a.next = &b; // 指针用->获取成员
b.next = c;
(*c).next = d; // 👈此处的*是解引操作,*c是对结构体的引用,等价于上面这行的用法
d->next = &e; // 指针用->获取成员
}