指针是一种数据类型
指针也是一种变量,占有内存空间,用来保存内存地址。
在指针声明时,*号表示所声明的变量为指针。在指针使用时,*号表示操作指针所指向的内存空间的值。
*p相当于通过地址(p变量的值)找到一块内存,然后操作内存。
*p放在等号的左边赋值,就是给内存赋值,*p放在等号的右边取值,就是从内存当中获取值。
指针变量和它指向的内存块是两个不同的概念。
char *p;
char c;
p = 0x1111; //改变指针变量的值,不会改变所指向的内容
*p = 'a'; //不会改变指针变量的值,只会改变所指的内存块的值
*p = 'a'; //给内存赋值
c = *p; //从内存取值
//保证所指向的内存块能够修改
指针时一种数据类型,是指它指向的内存空间的数据类型。指针的步长(p++),根据所指向的内存空间的数据类型来确定。
建立指针指向谁,就把谁的地址赋给指针,不断的给指针变量赋值,就是不断的改变指针变量,和指向的内存空间没有任何关系。
间接赋值(*p)是指针存在的最大意义
指针变量和它指向的内存块变量是两回事,指针指向某个变量,就是把某个变量地址赋给指针。
*p间接赋值成立有三个条件:① 两个变量(一个实参,一个形参)。
② 建立关系,实参取地址赋给形参指针。
③ *p形参去间接修改实参的地址。
#include <iostream>
#include <windows.h>
int main()
{
int iNum = 0; //实参
int* p = NULL;
p = &iNum;
iNum = 1;
std::cout << "iNum = " << iNum << std::endl;
std::cout << "p = " << p << std::endl;
std::cout << "*p = " << *p << std::endl;
*p = 2; //通过*形参 == 间接地改变实参的值
std::cout << "修改后的iNum = " << iNum << std::endl;
std::cout << "修改后的p = " << p << std::endl;
std::cout << "修改后的*p = " << *p << std::endl;
return 0;
}
函数调用时,用n指针(形参)改变n-1(实参)的值。函数调用时,形参传给实参,用实参取地址,传给形参,在被调用函数里面用*p,来改变实参,把运算结果传出来。
这就是指针作为函数参数的精髓所在。
理解指针必须和内存四区概念相结合
1)主调函数 被调函数
主调函数可以把堆区、栈区、全局数据内存地址传给被调用函数。
被调用函数只能返回堆区、全局数据。
2)内存分配的方式
指针做函数参数,是有输入和输出特性的。有的函数会将参数作为返回值使用。将数据作为参数传递进去,直接对参数本身进行修改,则无需再去接受返回值。
应用指针必须和函数调用相结合(指针做函数参数)
指针做函数参数,问题的本质不是指针,而是看内存块,内存块是一维还是二维。如果是基础的int变量,就不需要用到指针了。
一级指针典型用法(指针做函数参数)
一级指针做输入
int showbuf(char *p);
int showArray(int *array,int iNum);
一级指针做输出
int getLen(char *pFileName,int *pFileLen);
二级指针典型用法(指针做函数参数)
二级指针做输入
int main(int arc,char *arg[]);
int shouMatrix(int [3][4],int iLine);
二级指针做输出
int Demo_GetTeacher(Teacher **ppTeacher);
int getData(char **data,int *dataLen);
int getData_Free(void **data);
三级指针输出典型用法
三级指针做输出
int getFileAllLine(char ***content,int *pLine);
指针用法补充
野指针的两种释放形式
int getData(char **data,int *dataLen);
int getData_Free(void *data);
int getData_Free2(void **data);
两次调用
主调函数第一次调用被调用函数求长度,根据长度,分配内存,调用被调用函数。
补充知识
- 指针也是一种数据类型,指针的数据类型就是它所指向的内存空间的数据类型。
- 间接赋值*p是指针存在的最大意义。
- 理解指针必须和内存四区的概念相结合。
- 应用指针必须和函数调用相结合,指针作为函数指针来使用。
- 指针是子弹,函数是枪管。子弹只有沿着枪管发射才能显示它的威力。指针的学习重点就在于接口的封装和设计、模块的划分、解决实际应用问题。
- 指针指向谁就把谁的地址赋给指针。
- 指针指向谁就把谁的地址赋给指针,用它来解决链表更加轻松。
- 链表的入门关键所在是分清楚链表操作和辅助指针变量之间的逻辑关系。
- C/C++语言有它自己的学习特点,如果Java语言的学习特点是学习、应用、开发项目;那么C/C++语言的学习特点是:学习、理解、应用、上项目。
- 学好指针才学会了C语言的半壁江山。
- 理解指针的关键在于内存,没有内存哪来的内存首地址,没有内存首地址,哪来的指针。