【程序员面试宝典】错题好题汇总ch7

错题,知识盲点、查漏补缺
好题,开阔思路、锻炼思维

ch7 指针与引用
 
1.
传递动态内存
 1 #include<iostream>
 2 #include<iomanip>
 3 #include<cstdlib>
 4 #include<cstring>
 5 using namespace std;
 6  
 7 void GetMemory(char *p,int num){
 8  
 9  p = (char*)malloc(sizeof(char)*num);
10 }
11 void GetMemory_plus(char **p,int num){
12  
13  *p = (char*)malloc(sizeof(char)*num);
14 }
15 int main(){
16  
17  char*str = NULL;
18  //GetMemory(str,100);//如果注释掉下一行,程序会崩溃,因为str还是空的
19  GetMemory_plus(&str,100);
20  strcpy(str,"hello");
21  cout<<setw(8)<<"str : "<<str<<endl;
22  cout<<setw(8)<<"*str : "<<*str<<endl;
23  cout<<setw(8)<<"&str : "<<&str<<endl;
24  return 0;
25 }
View Code

 

结果与分析:
GetMemory()函数中,p只是str的一个副本,p的改变不影响str。
但是GetMemory_plus中,传入的str的地址&str,后面*p的赋值自然会影响&str。
 
 
2.字符串常量
 1 #include<iostream>
 2 #include<iomanip>
 3 #include<cstdlib>
 4 #include<cstring>
 5 using namespace std;
 6  
 7 char *strA(){
 8  char str[] = "Hello,world";
 9  return str;
10 }
11 char *strB(){
12  char *str = "Hello,world";
13  return str;
14 }
15 int main(){
16  
17  cout<<strA()<<endl;//可以输出一些东西,但是违背函数的栈帧机制。char []是局部变量,“helloworld”保存在栈中。
18  cout<<strB()<<endl; //没问题。char *定义了一个字符串常量,保存在只读的数据段。
19  return 0;
20 } 
View Code

 

结果与分析:
 
 
总结扩展:
charp[]="hello";//1
char*p="hello";//2
char*p;p=(char*)malloc(sizeof(char)*6);strcpy(p,"hello");//3
 
这三种情况下:
1中所有6个char字符都连续的存放在栈区。
2中的"Hello"存在程序内存的常量区中,是编译时就固定下来的(不可更改),然后p是一个指向常量区"hello"的指针,p本身存在栈区。
3中malloc向堆申请了空间,p存放在栈区,指向malloc申请出来的地址,最后"hello"就被copy到了p所指向的地址。
 
3.
内存偏移:
 1 #include<stdio.h>
 2 #include<iostream>
 3 using namespace std;
 4 class A{
 5  public:
 6   A(){
 7    m_a = 1;m_b = 2;
 8   }
 9   ~A(){
10   };
11   void fun(){
12    printf("%d %d\n",m_a,m_b);
13    printf("%x\n",(int)&m_a);
14    printf("%x\n",(int)&m_b);
15   }
16  private:
17   int m_a;
18   int m_b;
19 };
20 class B{
21  public:
22   B(){
23    m_c = 3;
24   }
25   ~B(){
26   };
27   void fun(){
28    printf("%d",m_c);
29   }
30  private:
31   int m_c;
32 };
33 int main(){
34  A a;
35  a.fun();
36  B *pb = (B*)(&a);
37  pb->fun();
38 }
View Code

 

结果与分析:
 
B*pb = (B*)(&a);
强制把a地址的内容看作一个B类的对象,也就是说pb指向的是a类的内存空间;
pb->fun();
正常情况,B中只有一个int m_c,B对象的内存空间中只有一个m_c,fun()函数就会去对象的内存首地址去寻找m_c,然后打印。
现在的话,fun()函数再去对象的内存首地址去取m_c的时候,就会把m_a打印出来。
 
4.
#include<iostream>
using namespace std;
 
int main(){
 
 int a[] = {1,2,3,4,5};
 cout<<*(a)<<endl;
 int *ptr = (int*)(&a + 1);
 int *ptr1 = (a + 1);
 cout<<*(a + 1)<<*(ptr - 1)<<*(ptr1)<<endl;
 int b[2][5] = {{1,2,3,4,5},{6,7,8,9,0}};
 int *p = (int*)(b[0] + 1);
 int *p1 = (int*)(&b[0] + 1);
 cout<<*p<<*p1<<endl;
 return 0;
}

 

结果与分析:
 
总结起来就是:
数组名本身就是指针,再加上&,就变成了双指针,这里的双指针就是二维数组,加1,就是数组整体加一行。
 
5.
auto_ptr是安全指针,如下定义是正确的:
std::auot_ptr <object> pObj(new Object);
std::auto_ptr <Object> source(){return new Object;}

 auto_ptr不可以放在容器中。因为auto_ptr的拷贝不等价,原来的一份会被删除。

 
 
 
posted @ 2015-04-11 19:55  Qin&Yang  阅读(233)  评论(0编辑  收藏  举报