拿出小本本记一下C++指针和引用的混淆点

当年这里学得乱七八糟,现在需要反复康康,遇到问题就会补进来噢。

指针

// 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() 是指针的大小,=4sizeof() 是被引用对象的大小
指针声明和定义可以分开,可以先只声明指针变量而不初始化,等用到时再指向具体变量。可以被初始化为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;  // 指针用->获取成员
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值