参考资料:
[1]程序员面试笔记 第11章 指针和引用
学习建议:
必须先思考!!!
11.1指针及其应用
面试题1:被调函数中修改主调函数中的变量
#include
#include
using namespace std;
void swap(int* a,int* b)
{
int tmp = *a;
*a = *b;
*b =tmp;
}
void sort(int* a,int* b,int* c)
{
//1.确保a最大
if(*a<*b)
swap(a,b);
if(*a<*c)
swap(a,c);
//2.确保b最大
if(*b<*c)
swap(b,c);
}
int main()
{
int a=80,b=90,c=20;
sort(&a,&b,&c);
cout<<"a:"<
面试题2:区分指针和数组
(1)数组名等价于数组首元素的地址
(2)字符数组
char str1[15] = "hello world";
char str2[] = "hello world";
注意:没有显示指明大小的数组,必须在定义的时候初始化。
(3)字符指针
char * str3 ="hello world";
11.2指针常量与常量指针
面试题1:指针常量与常量指针的常见错误
注意:
(1)要明确地址不能修改还是内容不能修改。
(2)可以通过修改地址间接修改指针指向的值!!!https://www.jianshu.com/p/c9717911d040
(3)常量必须在定义的时候初始化!!!
(4)常量地址只能赋值给常量指针!!!
面试题2:指针常量用做函数参数
无特殊的
面试题3:指针常量与字符串常量的冲突
指针str1指向字符串常量,常量的值不能修改
#include
using namespace std;
int main()
{
//指针str1指向字符串常量,常量的值不能修改
//char * const str1 ="apple";
char *str1 = "apple";
str1 = "orange";
cout<
11.3指针数组与数组指针
指针数组:存放指针的数组
int* a[10];
数组指针:指向数组的指针
int(*a)[10];//把()遮起来,指针a指向的是int [10]的数组
面试题1:简述指针数组与数组指针的区别
注意:
int类型的变量是4个字节
地址是的单位是字节
&a和&a[0]的数值是一样的,对&a解引用后是&a[0],对&a[0]解引用后是a[0]。
面试题1:简述数组地址与数组首元素地址的区别
数组地址&a和数组首元素地址&a[0]
要获得数组地址,要用数组指针
int main()
{
int a[6]={1,2,3,4,5,6};
int(*p)[6]=&a;//要获得数组地址,要用数组指针
//int* p = &a[0];
cout<
面试题3:简述指针数组与指向指针的指针区别
先不做。
11.4指向指针的指针
先不做。
11.5函数指针
函数名是函数的入口地址
函数指针使用如下:
int max(int a,int b){return a>b?a:b}
int(*p)(int,int)= max;//如果去掉括号int* p(int,int) 就是函数了
int x=10,y=20;
int z=p(x,y);
面试题1:通过函数指针实现4则运算
动手去写。
面试题2:简化超长的函数指针类型
//将类型int(*)(int,int,int)命名为Pfunc,这样在程序中直接使用Pfunc来代替int(*)(int,int,int)
typedef int(* Pfunc)(int,int,int);
int process(int a,int b,int c,Pfunc func);
11.6this指针
在对象调用类非静态成员函数时,会隐式地将对象的地址作为第一个参数传递给this指针
看到如下就明白了。
stu.setAge(20); => setAge(&stu,20);
setAge(int age); => setAge(Student* this,int age);
面试题1:this指针的常识性问题
在对象调用类非静态成员函数时,会隐式地将对象的地址作为第一个参数传递给this指针
面试题2:链式访问对象成员
链式访问:
int main()
{
Book* book = new Book();
book->setName("C++")->setPrice(11)->setLanguage('E');//链式访问
}
Book* setName(string name)
{
this->name= name;//为了避免名字冲突,访问数据成员时应该使用this指针
return this;//为了支持链式访问,返回对象的地址
}
面试题3:通过空指针调用类的成员函数
成员函数中,若this指针为空指针,利用此this指针访问成员变量会产生运行时错误。
11.7空指针与野指针
空指针:没有指向的指针
int* p=NULL;
野指针(只能避免而无法判断)
指向垃圾的指针
1.指针必须进行初始化
int *p=NULL;
int *p = &a;
int *p = (int *)malloc(sizeof(int));
2.指针指向的变量被free或delete后没有置为NULL
int *p = (int *)malloc(sizeof(int));
free(p);
p=NULL;
面试题1:常见的野指针
1.把*p看成整体就行。指针定义必须进行初始化。
2.指针调用free函数之后得显式地将指针置为NULL。
3.应该使用堆空间进行动态分配内存。使用栈空间,函数调用结束之后栈空间释放。
面试题2:在构造函数中释放对象本身(有点问题)
delete this后,这时指针就变为一个野指针。
delete和free只能释放堆内存。
11.8引用(!!!)
引用就是变量的别名
引用必须在定义时进行初始化
面试题1:指针与引用的区别
1.指针是变量的地址,引用是变量的别名
2.指针可以不初始化,此时指针的值是一个垃圾地址
引用必须进行初始化
3.指针使用期间可以被修改,引用使用期间不能被修改。
4.指针可以设为NULL,引用不能设为NULL。
5.指针可以定义二重指针,引用不能定义二重引用。
因为引用是变量的别名,二重引用没有意义。
6.指针需要先解引用,引用直接使用。
面试题2:指针与引用的使用
注意:
不能成为别名,但是可以赋值啊
#include
using namespace std;
int main()
{
int a =10,b=20;
int &r = a;//r是a的别名
int *p= &a;
int* &rp = p;//rp是p的别名
if((int)&r == (int)&a)
cout<<"(int)&r == (int)&a"<
面试题3:使用常量初始化引用
#include
using namespace std;
void printAge(const int& age)
{
cout<<"The age of the dog is"<