指针详解

本文详细介绍了C++中的指针概念,包括指针的类型、const用法、指针与数组的关系、空指针、坏指针的避免以及指针运算。还探讨了函数指针、数组指针以及引用作为变量别名的用法。通过实例解析了指针在数组和函数参数传递中的作用,强调了正确管理和使用指针的重要性。
摘要由CSDN通过智能技术生成

指针实际就是保存内存地址的一个变量,指针是有类型的,当对指针进行解引时,会根据指针的类型对所指的内存进行相应的解析,同变量一样也占用一定的内存(32位系统下占4位字节,64位占8位字节)
指针的定义

int a;
int* p = &a;

*代表 p为int类型的指针,&为取地址符

int* p, s1;

在这行代码中p为int类型的指针,s1为整形变量

指针的三种const用法

const int* p;// int const*  p;
	p = &a;
	//这两种定义方法的指针,所指向的数据不能通过该指针进行修改
int a;
int* const p = &a;
//这种方式定义的指针,必须进行初始化,且该指针值不会改变,可以通过指针对其指向的值进行修改
int a;
const int* const p = &a;//或者int const* const p = &a;
//这种方式定义的指针,必须进行初始化,且该指针值不会改变,不可以通过指针对其指向的数据进行修改

指针与数组的纠缠
当函数参数中出现数组时,实际上传递的数组首个元素的地址,而不是把整个数组copy到栈空间,大量的拷贝会使得程序效率下降.因此在函数中对形参传来的数组进行的操作会影响实参里的值

指针数组的定义

int* p[100];

指针数组传参

//方式一: 指针数组传参,声明成指针数组,不指定数组大小
void method_4(int *arr[], int len) { 
    for(int i=0; i<len; i++){ printf(" arr[%d] = %d\n", i, *arr[i]); 
    } 
}
//方式二: 指针数组传参,声明成指针数组,指定数组大小
void method_5(int *arr[10])
{ 
	for(int i=0; i<10; i++){ printf(" arr[%d] = %d\n", i, *arr[i]); 
	} 
}
//方式三: 二维指针传参
//传过去是指针数组的数组名,代表首元素地址,而数组的首元素又是一个指针, 
//就表示二级指针,用二级指针接收
void method_6(int **arr, int len) { 
	for(int i=0; i<len; i++){ printf(" arr[%d] = %d\n", i, *(*(arr+i))); 
	}
}

空指针

  1. 什么是空指针? 空指针,就是值为 0 的指针。(任何程序数据都不会存储在地址为 0 的内存块中,它是被操作系 统预留的内存块。) int *p = 0; 或者int *p = NULL; //强烈推荐
  2. 空指针的使用
    1)指针初始化为空指针 int *select = NULL; 目的就是,避免访问非法数据。
    2)指针不再使用时,可以设置为空指针 int *select = &xiao_long_lv; //和小龙女约会 select = NULL;
    3)表示这个指针还没有具体的指向,使用前进行合法性判断897943840118979438401111 int *p = NULL; // 。。。。 if § { //p 等同于 p!=NULL //指针不为空,对指针进行操作 }

坏指针
int *select; //没有初始化
情形一printf(“选择的房间是: %d\n”, *select);
情形二select = 100; printf(“选择的房间是: %d\n”, *select);

指针也分等级
二级指针只能存放一级指针的地址,三级指针只能存放二级指针的地址,以此类推.(不能越级)

空指针
void => 空类型 void* => 空类型指针,只存储地址的值,丢失类型,无法访问,要访问其值,我们必须对这个指 针做出正确的类型转换,然后再间接引用指针。 所有其它类型的指针都可以隐式自动转换成 void 类型指针,反之需要强制转换

指针运算
(1)指针与整数的运算,指针加减数字表示的意义是指针在数组中位置的移动; 对于整数部分而言,它代表的是一个元素,对于不同的数据类型,其数组的元素占 用的字节是不一样的, 比如指针 + 1,并不是在指针地址的基础之上加 1 个地址,而是在这个指针地址的 基础上加 1 个元素占用的字节数:
 如果指针的类型是 char*,那么这个时候 1 代表 1 个字节地址;
 如果指针的类型是 int*,那么这个时候 1 代表 4 个字节地址;
 如果指针的类型是 float*,那么这个时候 1 代表 4 个字节地址;
 如果指针的类型是 double*,那么这个时候 1 代表 8 个字节地址。
(2)通用公式: 数据类型 *p;
p + n 实际指向的地址:
p 基地址 + n * sizeof(数据类型)
p - n 实际指向的地址:
p 基地址 - n * sizeof(数据类型)
比如
对于 int 类型,比如 p 指向 0x0061FF14,则: p+1 实际指向的是 0x0061FF18,与 p 指向的内存地址相差 4 个字节; p+2 实际指向的是 0x0061FF1C,与 p 指向的内存地址相差 8 个字节
对于 char 类型,比如 p 指向 0x0061FF28,则: p+1 实际指向的是 0x0061FF29,与 p 指向的内存地址相差 1 个字节; p+1 实际指向的是 0x0061FF2A,与 p 指向的内存地址相差 2 个字节

指针和指针可以做减法操作,但不适合做加法运算.
指针和指针做减法适用的场合:两个指针都指向同一个数组,相减结果为两个指针之 间的元素数目,而不是两个指针之间相差的字节数。
如果两个指针不是指向同一个数组,它们相减就没有意义。
不同类型的指针不允许相减(指针之间可以进行比较)

函数指针
//函数指针的定义 把函数声明移过来,把函数名改成 (* 函数指针名)
int (*fp)(const void *, const void *);
/贝尔实验室的C和UNIX的开发者采用第1种形式,而伯克利的UNIX推广者却采用第2 种形式ANSI C 兼容了两种方式/
fp = &compare_int;
(*fp)(&x, &y); //第1种,按普通指针解引的放式进行调用,(*fp) 等同于compare_int
fp(&x, &y); //第2种 直接调用

数组指针
指向数组的指针
数组指针的定义假设指向一个int 类型的数组,数组成员为3个
int (* p)[3];

引用
可以理解为对一个变量起别名,实际上c++是用常指针实现的,所谓明修栈道暗度陈仓

int &a = 10;时是成立的,编译器会在栈开辟int空间,并起一个名字

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值