目录
简介
本文对c++指针进行简单介绍,总结了一些指针在使用过程中遇到的问题,希望可以帮助到正在学习指针的你ψ(`∇´)ψ
基本概念总结
Ⅰ、指针
定义指针:type *var_point_;
- 指针是“指向(point to)”另外一种类型的复合类型。复合类型是指基于其它类型定义的类型。
每一个变量都有一个内存地址,每一个内存地址都定义了可使用连字号(&)运算符访问的地址,他表示了在内存中存放数据的一个地址,指针指向这个地址。
指针是一个内存地址长的十六进制数。 - 实例分析
int var = 20;
int *ip;
ip = &var; //将var的地址给了ip
//此时对ip进行操作 = 对该地址进行操作 = 对var进行操作
//修改*ip = 30 相当于 var = 30
Ⅱ、堆指针与栈指针
- 堆指针 申请动态分配,它的值放到堆中
int *ip;
ip = new int();
new 返回新分配的内存单元的地址,因为该指针地址已经动态分配,所以可以直接赋值。
- 栈指针 没有申请动态分配内存,它的值放到堆中
int *p;
int a = 22;
p = &a;
指针p获取了栈中a的地址,属于静态分配,对*p的操作等于对a的操作。
Ⅲ、堆和栈的区别
堆 | 栈 |
---|---|
堆由程序员控制(malloc/free)(new/delete) | 栈由编译器自动管理 |
不连续、空间大、灵活 | 连续,大小由系统研定好 |
频繁的new/delete操作会造成大量内存碎片,降低程序效率 | 先进后出的结构,进出一一对应,不会产生碎片 |
向上,向高地址方向增长 | 向下,向低地址方向增长 |
Ⅳ、内存泄漏
是指程序申请内存后,无法释放已申请的内存空间,内存泄漏多了会导致可用内存空间变小,进一步造成内存溢出。
Ⅴ、空指针与野指针
- NULL指针是一个定义在标准库中的值为零的常量,*ptr = 0,标明该指针不指向一个可访问的内存位置。
- 野指针表示一个没有指向的指针对象,int *p,这里指针p就是野指针。
Ⅵ、各类型变量所占字节数
变量类型 | 字节数 |
---|---|
char | 1 |
short int | 2 |
int | 4 |
long int | 8 |
long long int | 8 |
char* | 8 |
float | 4 |
double | 8 |
Ⅶ、指针的算数运算(*ptr)
- 加减 :若ptr指向一个整数指针,ptr++,会使ptr指向地址加4。
- 比较 :如果ptr1和ptr2指向两个相关的变量,比如同一个数组中的不同元素,则可对ptr1和ptr2进行大小比较。
Ⅷ、指针和数组、指针数组和数组指针
- 指针和数组
Var[3] = {1,2,3};
*(Var + 2) = 300;
Var[2] = 300; //这两步操作等价
- char[]和char*
char a[3] = {'a', 'b', 'c'};
char* a[3] = {"aa", "bb", "cc"};
- a是一个char型指针变量,其值指向可以改变。
b是一个char型数组的名字,也是该数组首元素的地址,其值不可变。 - a = b,代表a,b指向同一区域。
- char*本身是一个字符指针变量,但是它既可以指向字符串常量,又可以指向字符串变量,指针的类型决定了对应字符能不能改变,所以若没有对a进行操作的意向,尽量定义为
const char* a = "string";
- 指针数组
指针数组可以说成是”指针的数组”,意思是说这个数组的所有元素都是指针类型。
char* var[4] = {"one", "two", "three", "four"};
这就相当与定义char *p1 = “one”,char *p1 = “two”,char *p3 = “threefourvar”, char *p4 = “xian”,这是四个指针,每个指针存放一个字符串首地址,然后用arr[4]这个数组分别存放这四个指针,就形成了指针数组。
- 数组指针
数组指针可以说成是”数组的指针”,意思是说这个指针存放着一个数组的首地址,或者说这个指针指向一个数组的首地址。
char (*var)[4];
var是一个指针指向一个char [4]的数组,每个数组元素是一个char类型的变量。
Ⅸ、const与指针
- char*是指向字符串的指针(指向字符串的首个字母),可以指向一串常量字符串。
char a[3] = {'a', 'b', 'c'};
char* a[3] = {"aa", "bb", "cc"};
*a[0] = 'a'是因为*a[0]代表指向字符串的首地址(首个字母)。
- char* const[指向字符的静态指针],const修饰指针,代表不能改变指针。
- const char* 指向静态字符的指针,const修饰char,代表字符不能改变,但是指针可以改变,也就是说该指针可以指向其他const char*
Ⅹ、强指针和弱指针
- 使用范围:
(强指针)局部变量,子对象指针,可影响其生命周期的指针。
(弱指针)父对象指针,某些不能影响其生命周期的对象 - 作用:
(强指针):利用强指针进行资源回收,不需要人工计算new和delete,一个对象在何处(父类或函数中)创建,就在何处回收。
(弱指针):一是为了避免强指针循环依赖,二是保障线程安全,其他对象不是在该类中创建,则不需要改类负责回收,由此使用弱指针。
问题总结
Ⅰ、char*对象输出问题
char *a = "Hello world"
printf("%s,%d,%d,%d\n", a, a, &a, *a);
输出结果:
对象 | 输出值 |
---|---|
a (%s,字符串) | Hello world |
a (%d,整型) | 4669540 |
&a (%d,整型) | 7077612 |
*a (%d,整型) | 72 |
结果分析:
-
a中存放字符串首地址,*a指向字符串首个字母。char* a = "Hello world"在执行时会先声明一个char*对象,然后生成一个string对象字符串,其中存有字符串"Hello world",最后将string对象赋值给char*对象。
对象 | 输出值 | 含义 |
---|---|---|
a (%s,字符串) | Hello world | string对象值 |
a (%d,整型) | 4669540 | string对象地址 |
&a (%d,整型) | 7077612 | 为存放字母H地址的地址 |
*a (%d,整型) | 72 | ASCll码表中大写字母H存放地址 |
后续遇到关于指针的问题会持续更新,如果你对指针有什么疑问欢迎一起讨论。
如果此文帮助到你( •̀ ω •́ )✧,动动小手点个赞可好O(∩_∩)O。
原创文章,转载请标明本文出处。