[原创] 程序员面试宝典:第七章 指针与引用
1. 指针 vs. 引用
- 非空区别: 引用不能为 NULL
- 合法性: 引用永远合法
- 可修改区别:引用的指向只能初始化,不能修改
- 存储空间区别:引用不是变量,本身并不占用任何存储空间
- 应用区别: 根据上述特点,决定应用场景
2. 指针作为函数参数:void fun ( char * p);fun(str);
- *p 只是str的副本,虽然与str指向相同,可以修改str指向地方的内容,但不能修改str的指向!函数返回时,*p消失。可以用以下方法,改变str的指向。
- void GetMemory ( char ** p)
- char * GetMemory ( char * p)
3. 数组与指向常量的指针:
- char a[] = "abc" 局部数组
- char *a = "abc" 局部指针,指向数据区字符串常量,这个常量不可修改!
4. 指针相减结果为“元素个数”,而不是真正地址空间的差:
- int *p, *q; q-p; 相当于 (p指向的地址)-(q指向的地址)/ sizeof(int)
- 不同类型的指针不能相减!
5. 类中的函数对于类中变量的引用,采用的是相对于类的偏移地址的方式(并不是通过变量名匹配的)。
6. 函数指针: void ( * fun) ( void )
- Int ( * ( *F ) (int, int) ) ( int )
- F 指向函数 A
- A:两个int参数,返回一个函数指针B
- B:指向函数C
- C:一个int参数,int返回值
7. 指针数组与数组指针:
- 指针数组:int *p[] 一个数组,里边的元素都是指针
- 数组指针:int (*p)[] 一个指针,指向一个数组,指针加1,则指向下一个数组(移动整个数组长度)!
- 主要看p和[]结合(是数组),还是与*结合(是指针),默认[]有优势
- float (**def)[10]:def 指向(指向 float[10] 的指针)
- float *(*def)[10]:def 指向(float * [10] 数组)
8. 数组名就是数组首地址(并且是常量,不可改变!!),对数组名取地址,得到的是数组指针
- int a[10]; int *ptr = (int *)(&a + 1); ptr指向a中最后一个元素之后
9. delect p; 释放p所指向的内存区域,但是没有改变p的指向!!需要p = NULL; 空指针
10. 两种动态内存分配方式:
- malloc / free:分配内存的函数,需要给出具体分配内存的大小,不运行构造/析构函数
- new / delete:C++运算符,分配内存,自动计算分配内存的大小,且运行相应的构造/析构函数
11. 句柄:32位 int,windows 对象物理地址的索引,指向指针的指针。
- 句柄地址(稳定)-> 记载着对象在内存中的地址 -> 对象在内存中的地址(不稳定)-> 实际对象
12. 管理指针成员 (类中的指针成员的复制控制,解决多个类对象共享一个指针的问题)
- 具有指针成员的对象一般需要定义复制控制成员
- 常规指针:共享,无法防止悬垂
- 智能指针:共享,通过计数类,记录有多少对象共享一个指针(不能用static,因为不同对象(如基类和子类)可以有相同指针),在最后一个共享对象消除之后,计数类负责指针的撤销。
- 值型类:将指针成员所指的基础值的副本给每个对象。