面试疑难问题

问题1: 局部变量作为地址返回

char *strA()// 局部变量数组不能做为返回,返回后会导致失效,用malloc返回作为修改

{

char str[] = "hello world";

        return str;

}

voidGetMemory(char *p)//局部分配的堆内存,作为形参的赋值

{

p = (char*)malloc(100);//获取地址需要地址的地址

}

voidTest(void)

{

char *str = NULL;
GetMemory(str); 
strcpy(str, "hello world");
printf(str);

}

请问运行Test函数会有什么样的结果?
答:str会是NULL,赋值给一个空指针会导致程序崩溃,需要修改为指针的指针


//struct 内存

1、 sizeof应用在结构上的情况 
请看下面的结构: 
struct MyStruct { 
double dda1; 
char dda; 
int type 
}; 
对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你

会这样求: 
sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13 
但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。你知道为什
么在VC中会得出这样一个结果吗? 

其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,

VC规定各成员变量存放的起始地址相对于构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数

下面列出常用类型的对齐方式(vc6.0,32位系统)。

类型      对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量) 
Char      偏移量必须为sizeof(char)即1的倍数 
Short     偏移量必须为sizeof(short)即2的倍数 
int   偏移量必须为sizeof(int)即4的倍数 
float 偏移量必须为sizeof(float)即4的倍数 
double  偏移量必须为sizeof(double)即8的倍数 

各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对

齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边

界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员

变量申请空间后,还会根据需要自动填充空缺的字节。 
下面用前面的例子来说明VC到底怎么样来存放结构的。 
struct MyStruct 

double dda1; 
char dda; 
int type 
}; 
为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个

成员dda1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(doub

le)的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员dda分配空

间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数

,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用 sizeof(char)=1个字

节;接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址

的偏移量为9,不是sizeof (int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自

动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起

始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方

,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总

的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的

类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整

个结构的大小为:sizeof(MyStruct)=8+1+ 3+4=16,其中有3个字节是VC自动填充的,没有

放任何有意义的东西


参考:http://blog.csdn.net/ehui928/article/details/546391

//多重继承中的变量值,如下例题

class A1
{
public:
int n;
};

class B1
{
public:
int n;
};

class C1:public B1,public A1
{
public:
int n;
};

C1  c;
c.A1::n = 10;
c.B1::n = 20;

cout<<c.A1::n<<" "<<c.B1::n<<" "<<c.n<<endl;//作用域的作用,其中c.n没有初始化

//动态链接库 导出函数和导出类

导出类和导出函数方式一样,只是导出类尽量按照虚基类的方式,否则需要把基类和类的结构

可以参考如下文章:http://www.360doc.com/content/11/0805/17/6675409_138289992.shtml


//设计模式的单例模式

单例模式属于对象创建型模式,其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点。

如下可以使用单例模式:

1.当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
2.当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

public class Singleton   //采用private 的方式可以保证的实例只能创建一个
{
private Singleton(){
        generator = new Random;
        }
        
        public void SetSeed(int seed){
        generator.SetSeed(seed);
}
       
       public int nextInt(){
generator.nextInt();
}
       
       public staticsynchronized Singleton getInstance(){
       if(NULL == instance)
                {
instance = new Singleton();
       }
        return instance;
}
private Random    genreator;
        private static Singleton instance;

//类中的静态成员变量

class base
{
public:
base(){cout << "base constructor"<<endl;}
};

class child
{
public:
static base a;
public:
child(){cout << "child constructor"<<endl; }
};

定义 child childclass; //只打印child constructor;


//string 类

class string{

    public :
             string(const char* str = NULL);
             string(const string& other);
             virtual ~string();
            string& operator =(const string& other);
             string& operator =(const char* str);

             const char * operator[](int i)const;
    private :
             char* m_pData;
    };
 string::string(const char* str)   
 {                                 
      if(NULL == str)                 
      {                               
            m_pData = new char[1];        
            assert(m_pData != NULL);      
            m_pData[0] = '\0';           
      }                               
      else                            
      {                               
            m_pData = new char[strlen(str) + 1];
            assert(m_pData != NULL);      
            strcpy(m_pData , str);        
      }                               
}                                 

string::string(const string& other)
{                                  
          m_pData = new char[strlen(other.m_pData) + 1];
          assert(m_pData != NULL);         
          strcpy(m_pData , other.m_pData); 
}                                  
string::~string()                  
{                                  
       delete []m_pData;

        m_pData=NULL;                
    }                                  
string& string::operator = (const string& other)
{                                  
      if( &other == this )           
      {                                
         return *this;                 
      }                                
      delete []m_pData;                
      m_pData = new char[strlen(other.m_pData) + 1];
      assert(m_pData != NULL);         
      strcpy(m_pData , other.m_pData); 
      return *this;                    

}                                  
string& string::operator = (const char* str)
{                                  
      delete []m_pData;                
      if(NULL == str)                 
      {                               
        m_pData = new char[1];        
        assert(m_pData != NULL);      
        m_pData[0] = '\0';           
      }                               
      else                            
      {                               
        m_pData = new char[strlen(str) + 1];
        assert(m_pData != NULL);      
        strcpy(m_pData , str);        
      }                               
      return *this;                   

}

const char & String::operator[](int i)const{

     return str[i];

}

转载:http://zhangqiuxi.blog.163.com/blog/static/83511432007316101454246/


memcpy和strcpy的区别

http://www.360doc.com/content/12/0731/11/9688385_227424314.shtml


如何判断两个无环交叉

http://blog.csdn.net/adyw2565876/article/details/49095795

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值