C++指针详解(精心整理)

     我想你一定和我一样刚开始接触C++的时候,被指针(pointer)引用(reference)内存分区等等诸多概念,弄得很头疼吧。其实回头想想,C/C++,python,java,shell...学习起来都有一个共性,那就是敲敲敲,多敲几遍代码,可能会有一些问题,带着问题去学习,整理它。然后将技术不断的应用于工作中的新场景,很快就可以掌握一门新技术了,不建议毫无基础的情况下,学习特别深的理论知识。

  1、   指针也是一种数据类型

1)指针也是一种变量,占有内存空间,用来保存内存地址

//测试指针变量占有内存空间大小
void main()
{
	int* p = nullptr;
	cout << "指针的大小" << sizeof(p) << endl;
	int a = 10;
	p = &a;
	cout << "指针的大小" << sizeof(p) << endl;
	system("pause");
	return;
}

2)*p操作内存

在指针声明时,*号表示所声明的变量为指针(int* 代表的是指向地址中存储的数据类型为int)

在指针使用时,*号表示 操作 指针所指向的内存空间中的值

         *p相当于通过地址(p变量的值)找到一块内存;然后操作内存

         *p放在等号的左边赋值(给内存赋值)

         *p放在等号的右边取值(从内存获取值)

 

3)指针变量和它指向的内存块是两个不同的概念

//含义1 给p赋值p=0x1111; 只会改变指针变量值,不会改变所指的内容;p = p +1; //p++

//含义2 给*p赋值*p='a'; 不会改变指针变量的值,只会改变所指的内存块的值 

*p可以理解一个钥匙

//含义3 =左边*p 表示 给内存赋值, =右边*p 表示取值 含义不同切结!

//含义4 =左边char *p

//含义5 保证所指的内存块能修改

4)指针是一种数据类型,是指它指向的内存空间的数据类型 

含义1:指针步长(p++),根据所致内存空间的数据类型来确定

p++=è(unsigned char )p+sizeof(a);

结论:指针的步长,根据所指内存空间类型来定。*很重要

        

注意:     建立指针指向谁,就把把谁的地址赋值给指针。图和代码和二为一。        

                不断的给指针变量赋值,就是不断的改变指针变量(和所指向内存空间没有任何关系)。

                改变指针变量的值,更改的是指向的位置,不会更改指向位置内存空间中存储的值

 

2、间接赋值(*p)

1)两码事:指针变量和它指向的内存块变量

2)条件反射:指针指向某个变量,就是把某个变量地址否给指针

3*p间接赋值成立条件:3个条件

void main1()
{
	int a = 0;
	cout <<"原始a:"<< a << endl;
	int* p = &a;
	*p = 10;//通过*p更改p指向内存空间的内容,间接修改a的值
	cout << "修改后a:" << a << endl;

}

    1)2个变量(通常一个实参,一个形参)

    2) 建立关系,实参取地址赋给形参指针

    3) *p形参去间接修改实参的值

4)函数调用时,形参传给实参,用实参取地址,传给形参,在被调用函数里面用*p,来改变实参,把运算结果传出来。

指针作为函数参数的精髓。

3、指针在内存四区中的分布

  1. 主调函数 被调函数
    1. 主调函数可把堆区、栈区、全局数据内存地址传给被调用函数
    2. 被调用函数只能返回堆区、全局数据
  2. 内存分配方式
    1. 指针做函数参数,是有输入和输出特性的。

4、应用指针必须和函数调用相结合(指针做函数参数)

编号

指针函数参数

内存分配方式(级别+堆栈)

主调函数

实参

被调函数

形参

备注

 

01

1级指针

(做输入)

分配

使用

一般应用禁用

分配

使用

常用

Int showbuf(char *p);  

int showArray(int *array, int iNum)

02

1级指针

(做输出)

使用

结果传出

常用

int geLen(char *pFileName, int *pfileLen);

03

2级指针

(做输入)

分配

使用

一般应用禁用

分配

使用

常用

int main(int arc ,char *arg[]); 指针数组

int shouMatrix(int [3][4], int iLine);二维字符串数组

04

2级指针

(做输出)

使用

分配

常用,但不建议用,转化成02

int getData(char **data, int *dataLen);

Int getData_Free(void *data);

Int getData_Free(void **data); //避免野指针

05

3级指针

(做输出)

使用

分配

不常用

int getFileAllLine(char ***content, int *pLine);

int getFileAllLine_Free(char ***content, int *pLine);

指针做函数参数,问题的实质不是指针,而是看内存块,内存块是1维、2维。

  1. 如果基础类int变量,不需要用指针;
  2. 若内存块是1维、2维。

5、一级指针做函数参数

一级指针做输入

int showbuf(char *p)
{
	return sizeof(p);
}
void main()
{
//	char* p = nullptr;
	char tmp[] = "abcdefg2";
	char* p = tmp;
	int m = showbuf(p);
	cout << m << endl;
	system("pause");
	return;
}

一级指针做输出

char* showbuf(char *p)
{
	cout << p << &p << endl;
	return p;
}

理解

主调函数还是被调用函数分配内存

被调用函数是在heap/stack上分配内存

6、二级指针做函数参数

二级指针做输入

int main(int arc ,char *arg[]); 字符串数组

int shouMatrix(int [3][4], int iLine);

二级指针做输出

int Demo64_GetTeacher(Teacher **ppTeacher);

int Demo65_GetTeacher_Free(Teacher **ppTeacher);

int getData(char **data, int *dataLen);

Int getData_Free(void *data);

Int getData_Free2(void **data); //避免野指针

理解

主调函数还是被调用函数分配内存

被调用函数是在heap/stack上分配内存

总结:

1)指针也是一种数据类型,指针的数据类型是指它所指向内存空间的数据类型

2)间接赋值*p是指针存在的最大意义 

3)理解指针必须和内存四区概念相结合 

4)应用指针必须和函数调用相结合(指针做函数参数)

指针是子弹,函数是枪管;子弹只有沿着枪管发射才能显示它的威力;指针的学习重点不言而喻了吧。接口的封装和设计、模块的划分、解决实际应用问题;它是你的工具。

5)指针指向谁就把谁的地址赋给指针 

6)指针指向谁就把谁的地址赋给指针,用它对付链表轻松加愉快

7)链表入门的关键是分清楚链表操作和辅助指针变量之间的逻辑关系

8)C/C++语言有它自己的学习特点;

    若java语言的学习特点是学习、应用、上项目;

    那么C/C++语言的学习特点是:学习、理解、应用、上项目。多了一个步骤吧。

9)学好指针才学会了C语言的半壁江山

10) 理解指针关键在内存,没有内存哪来的内存首地址,没有内存首地址,哪来的指针啊。

 

  • 30
    点赞
  • 183
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值