程序员面试宝典 7 - 指针与引用

指针基本问题

指针和引用的差别

 ★相同点: 
     都是地址的概念; 

      指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。  

★ 区别: 

指针是一个实体,而引用仅是个别名; 
引用使用时无需解引用(*),指针需要解引用; 
引用只能在定义时被初始化一次,之后不可变;指针可变; 

引用没有 const,指针有 const,const 的指针不可变; 

引用不能为空,指针可以为空;由于没有所谓的 null reference 所以所以在使用前不需要进行测试其是否有值.,而使用指针则需要测试其的有效性.


指针未确定指向不能赋值


传递动态内存

1.交换两个数

#include<iostream>
using namespace std;
void swap(int *p,int *q)   //不交换,只是指针的交换,地址的值并没有改变
{
	int *t;
	t=p;
	p=q;
	q=t;
}

void swap2(int *p,int *q)  //成功
{
	int t;
	t=*p;
	*p=*q;
	*q=t;
}
void swap3(int &p,int &q)  //成功
{
	int t;
	t=p;
	p=q;
	q=p;
}


2.这个程序有什么结果?

#include<iostream>
using namespace std;

void GetMemory(char * p,int num)   //在strcpy时程序崩溃,因为没有传递动态内存,实参一直是NULL
{
	 p=(char *)malloc(sizeof(char)*num);   
}

char * GetMemory1(char * p,int num)
{
	 p=(char *)malloc(sizeof(char)*num);
	 return p;
}


void GetMemory2(char ** p,int num)
{
	 *p=(char *)malloc(sizeof(char)*num);   
}

void GetMemory3(int *z)
{
	*z=0;
}
int main()
{
	char *str =NULL;
	str = GetMemory1(str,100);
	strcpy(str,"hello");

	GetMemory2(&str,100);
	strcpy(str,"hello");
	cout<<*str;   //h 
	cout<<str;     // hello 

	int a=1;
	GetMemory3(&a);   //0
	cout<<a;
}

3.这个函数有什么问题?用如何修改?
#include<iostream>
using namespace std;

char *strA()
{
	char str[]="hello";
	return str;      // 局部数组    不合理
}
char *strB()
{
	char *str="hello";
	return str;      // 全局数组
}
char *strC()
{
	static char str[]="hello";
	return str;      // 静态
}

9.下卖弄程序在哪一行崩溃?

#include<iostream>
using namespace std;

struct S
{
	int i;
	int *p;
};
int main()
{
	S s;
	int *p =& s.i;
	p[0]=4;
	p[1]=3;
	s.p =p;
	s.p[1]=1;   //相当于*(&s.i+1),即s.i的地址加1,即s.p,  s.p[1]与s.p其实是同一个地方,所以到s.p[1]=1,那么s.p[0]将指向内存地址为1的地方
	s.p[0]=1;	 //*((int*)1)=2  ,访问0x00000001空间,对于一个未做声明的地址直接进行访问,所以访问出错
}

函数指针

#include"stdio.h"
int max(int x,int y)  
{
	return x>y?x:y;
}
int main()
{
	int (*p)(int ,int )	=	max;   //函数指针
	int a,b,c,d;
	scanf("%d%d%d",&a,&b,&c);  
	d = (*p)((*p)(a,b),c);
	printf("%d",d);
}

float (**def)[10];  //def是一个二级指针,指向的一个一维数组的指针,数组的元素都是float
double * (*gh)[10]  //gh是一个指针,指向一个一维数组,数组元素都是double *
double(*f[10]) (); //f是一个10个元素的数组,元素都是函数的指针,指向的类型是无参且返回double的函数。
int * (  (*b)[10]  ); //同 int *(*b)[10]
long (*fun)(int) ; //函数指针
int(*(*F)(int ,int))(int);//F是一个函数指针,指向的函数类型是两个int参数且返回一个函数指针的函数,返回的函数指针带有一个参数且返回int.

指针数组和数组指针

数组指针:
{int a[4][5];
int (*p)[5]=a;}
p是一个指针变量,它指向包含5个int元素的一维数组,此时p的增量以它所指向的一维数组长度为单位;
*p+i是二维数组a[0][i]的地址;
*(p+2)+3表示a[2][3]地址(第一行为0行,第一列为0列),*(*(p+2)+3)表示a[2][3]的值。
//(*p)[5]其中的5换成其他的数字在vc++6.0环境中都无法通过编译

指针数组:
int *p[]  //数组元素全为指针的数组,ptr里存的是地址,指向位置的值是*ptr[0]、*ptr[1].....
char *n[3]={"gain","much","strong"};   n[0]="gain"、n[1]、n[2]


1.
#include<iostream>
using namespace std;
int main()
{
	int v[2][10]={1,2,3,4,5,6,7,8,9,10,
			11,12,13,14,15,16,17,18,19,20};
	int (*p)[10]=v;
	cout<<**p<<endl;   //1
	cout<<**(p+1)<<endl;   //11
	cout<<*(*p+1)<<endl;   //2
	cout<<*(p[0]+1)<<endl;   //2
	cout<<*(p[1])<<endl; //11
	cout<<(*p)[12]<<endl;  //13
}
#include<iostream>
using namespace std;
int main()
{
	int Test[3]={1,2,3};
	int *p=(int*)(&Test+1);  //Test后面一个位置
	cout<<*(p-1);	     //3
}

4.

指针和句柄

1.指针和句柄的区别和联系是什么?

    指针指向系统中物理内存的地址,而句柄是windows在内存中维护的一个对象内存物理地址列表的整数索引,标记系统资源隐藏系统信息,一种指向指针的指针。

    在windows系统中的内存管理一般会将当前处于空闲状态的对象的内存释放掉,当需要访问的时候再重新提交分配物理内存,从而导致对象的物理地址是变化的,

这样就不允许系统直接通过指针来访问(物理地址不断变化)的对象。

    句柄是一种指向指针的指针。由于windows是一种以虚拟内存为基础的操作系统,其内存管理器经常会在内存中来回的移动对象,以此来满足各种应用程序对内存的需求。

而对象的移动意味着对象内存地址的变化,正是因为如此,如果直接使用指针,在内存地址被改变后,系统将不知道到哪里去再调用这个对象。

    windows系统为论文解决这个问题,系统专门为各种应用程序腾出了一定的内存地址(句柄)专门用来记录这些变化的地址(这些内存地址就是指向指针的指针),这些内存地址本身是一直不变化的。windows内存管理器在移动某些对象之后,他会将这些对象新的内存地址传给句柄,告诉他移动后对象去了哪里。

    句柄(稳定的)----->记载着对象在内存中的地址---->对象在内存中的地址(不稳定的)---->记载着实际对象的地址。

this指针

1.this指针只能在成员函数中使用,全局变量、静态函数都不能使用this
2.this在成员函数的开始前构造,在成员的结束后清除。
3.this指针不呢过不占用对象的内存。
4.采用type XX 的方式定义的话,在栈里分配内存,这是this的值这块内存的位置
  采用new 方式创建对象的话,在堆里分配内存  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值