C++指针详解(精⼼整理)
我想你⼀定和我⼀样刚开始接触C++的时候,被指针(pointer)引⽤(reference)内存分区等等诸多概念,弄得很头疼吧。其实回头想想,C/C++,python,java,学习起来都有⼀个共性,那就是敲敲敲,多敲⼏遍代码,可能会有⼀些问题,带着问题去学习,整理它。然后将技术不断的应⽤于⼯作中的新场景,很快就可以掌握⼀门新技术了,不建议毫⽆基础的情况下,学习特别深的理论知识。
1、指针也是⼀种数据类型
1)指针也是⼀种变量,占有内存空间,⽤来保存内存地址
//测试指针变量占有内存空间⼤⼩
void main()
{
int* p = nullptr;
cout << "指针的⼤⼩" << sizeof(p) << endl;
int a = 10;
p = &a;
cout << "指针的⼤⼩" << sizeof(p) << endl;
system("pause");
sizeof 指针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、应⽤指针必须和函数调⽤相结合(指针做函数参数)
编号指针函数参数
内存分配⽅式(级别+堆栈)主调函数
实参
被调函数
形参
备注
011级指针
(做输⼊)堆分配使⽤⼀般应⽤
禁⽤
栈分配使⽤常⽤
Int showbuf(char *p);
int showArray(int *array, int iNum)
021级指针
(做输出)
栈使⽤结果传出常⽤
int geLen(char *pFileName, int *pfileLen);
032级指针
(做输⼊)堆分配使⽤⼀般应⽤
禁⽤
栈分配使⽤常⽤
int main(int arc ,char *arg[]); 指针数组
int shouMatrix(int [3][4], int iLine);⼆维字符串数组
堆使⽤分配常⽤,但不建议⽤,转化成02 042级指针
(做输出)
int getData(char **data, int *dataLen);
Int getData_Free(void *data);
Int getData_Free(void **data); //避免野指针
堆使⽤分配不常⽤053级指针
(做输出)
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) 理解指针关键在内存,没有内存哪来的内存⾸地址,没有内存⾸地址,哪来的指针啊。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论