天下

记录修行的印记

求一个数,二进制表示中含有多少个1

// 1. 求一个数,二进制表示中含有多少个1.
int func(x)
{
    
int countx = 0;
    
while(x)
    {
        countx 
++;
        x 
= x&(x-1);
    }
    
return countx;


// 2. 请编写函数 strcpy。
char *strcpy(char *strDest, const char *strSrc)
{
    
if ( strDest == NULL || strSrc == NULL)  // 必须
        return NULL ;
    
if ( strDest == strSrc)            // good
        return strDest ;
    
char *tempptr = strDest ;
    
while*strDest++ = *strSrc++ );
    
return tempptr ;
}

// 3.  下面关于“联合”的题目的输出?
union {
    
int i;
    
char x[2];
}a;
void main()
{
    a.x[
0= 10;
    a.x[
1= 1;
    printf(
"%d",a.i);
}
//答案:266 (低位低地址,高位高地址,内存占用情况是Ox010A)

// 4. 在C++ 程序中调用被C 编译器编译后的函数,为什么要加 extern "C"
首先,作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。
通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。
例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。
这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数
extern "C"是连接申明(linkage declaration),被extern "C"修饰的变量和函数是按照C语言方式编译和连接的.

// 5. 关联、聚合(Aggregation)以及组合(Composition)的区别?
关联  是表示两个类的一般性联系,比如“学生”和“老师”就是一种关联关系;
聚合  表示has
-a的关系,是一种相对松散的关系,聚合类不需要对被聚合类负责,如下图所示,用空的菱形表示聚合关系:
        聚合可以表示为: 
class A {};  class B{ A* a; ..}
组合  表示contains
-a的关系,关联性强于聚合:组合类与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关系:
        实现的形式是: 
class A{};   class B{ A a; }

// 6. 面向对象的三个基本特征,并简单叙述之?
1. 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(privateprotected,public)
2. 继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、
         接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合
=>接口继承以及纯虚函数)构成了功能复用的两种方式。
3. 多态:是将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。
         简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

// 7. 多态的作用?
主要是两个:
1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;
2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。
        
// 8. New delete 与malloc free 的联系与区别?
答案:
都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,
new 会自动调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor.

// 9. 有哪几种情况只能用intialization list 而不能用assignment?
答案:当类中含有const、reference 成员变量;基类的构造函数都需要初始化表。

// 10. main 函数执行以前,还会执行什么代码?
答案:全局对象的构造函数会在main 函数之前执行。

// 11. 描述内存分配方式以及它们的区别?
1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。
    动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。

// 12. 当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零.
答案:肯定不是零。举个反例,如果是零的话,声明一个class A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了。

// 13. static_cast, dynamic_cast和reinterpret_cast的区别和应用
C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:
TYPE b 
= (TYPE)a。
const_cast,字面上理解就是去const属性。
static_cast,命名上理解是静态类型转换。如int转换成char。
dynamic_cast,命名上理解是动态类型转换。如子类和父类之间的多台类型转换。
reinterpret_cast,仅仅重新解释类型,但没有进行二进制的转换。
//推荐: http://www.shenmiguo.com/archives/2009/275_cplus-type-cast.html

// 14. C++关键字:mutable、volatile、explicit以及__based
volatile: 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,
        优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
        
// http://www.cnblogs.com/koya/articles/849158.html
mutable: 他只能用于类的非静态和非常量数据成员.如果一个类的成员函数被声明为const类型,表示该函数不会改变对象的状态,
        也就是该函数不会修改类的非静态数据成员.但是有些时候需要在该类函数中对类的数据成员进行赋值.这个时候就需要用mutable了
        
// http://www.360doc.com/content/10/0613/11/1595686_32846874.shtml
explicit
    它的作用是
"禁止单参数构造函数"被用于自动型别转换,典型的例子是容器类型,在这种类型的构造函数中你可以将初始长度作为参数传递给构造函数.
__based: 
    该关键字主要用来解决一些和共享内存有关的问题,它允许指针被定义为从某一点开始算的32位偏移值,而不是内存种的绝对位置

explicit 它的作用是"禁止单参数的构造函数"被用于后台自动类型转换,意味着单参数构造函数不能用来创建隐式临时对象!
否则一些宽松的规则将允许在没有显式类型转换操作的情况下进行类型转换。
考虑下面的例子:
IntCell obj;
obj 
= 37;//should not compile:type mismatch

C
++拥有宽松的规则,通常,单参数构造函数定义了一个隐式类型转换,该转换创建一个临时对象,从而赋值(或函数参数)变成兼容的。
在本例中,编译器试图将
obj 
= 37;
转换为
IntCell tempobj 
= 37;
obj 
= tempobj;


// 15. 类成员函数的重载、覆盖和隐藏区别?
a.成员函数被重载的特征:
1)相同的范围(在同一个类中);
2)函数名字相同;
3)参数不同;
4virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
1)不同的范围(分别位于派生类与基类);
2)函数名字相同;
3)参数相同;
4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

// 16. 如何打印出当前源文件的文件名以及源文件的当前行号?
cout << __FILE__ ;
cout
<<__LINE__ ;
__FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。

// 17. main 主函数执行完毕后,是否可能会再执行一段代码,给出说明?
答案:可以,可以用_onexit 注册一个函数,它会在main 之后执行.

// 18. 如何判断一段程序是由C 编译程序还是由C++编译程序编译的?
#ifdef __cplusplus
    cout
<<"c++";
#else
    cout
<<"c";
#endif


class IntCell
{
public :
    
explicit IntCell(int val=0):m_val(val){}
private:
    
int m_val;
};


posted on 2013-03-18 15:02 天下 阅读(602) 评论(0)  编辑 收藏 引用 所属分类: C/C++


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2013年3月>
242526272812
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿(4)

随笔分类(378)

随笔档案(329)

链接

最新随笔

搜索

最新评论