c&c++的若干条知识点汇总

来源:互联网 发布:现在做淘宝还有前景吗 编辑:程序博客网 时间:2024/06/12 15:52

1、c++是不是类型安全的?

     不是。两个不同类型的指针之间可以强制转换(用reinterpretcast)。C#是类型安全的。

2、文件头包含

     (1)头文件中的ifndef/define/endif的作用?

    防止该头文件被重复引用。

      (2)include<file.h> 与 #i nclude "file.h"的区别?

前者是从Standard Library的路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h。

3、mian执行前,还会执行什么代码?

       全局对象的构造函数会在main函数之前执行;

4、局部变量 

将局部便令尽可能置于最小作用域内,在声明变量时将其初始化。C++允许在函数的任何位置声明变量,离第一次使用越近越好,而且应该使用初始化代替声明+赋值的方式。

int i ;    i = f() ;//初始化和声明分离    int i = f() ; //初始化时声明

5、0与NULL

整数用0,实数用0.0,指针用NULL,字符串用‘\0’

答案:

BOOL : if ( !a )or if(a)

int : if ( a ==0)

float : constEXPRESSION EXP = 0.000001

if ( a < EXP&& a >-EXP)

pointer : if ( a != NULL) or if(a == NULL)

6、sizeof

尽量使用sizeof(varname)代替sizeof(type):因为使用sizeof(varname)是因为变量类型改变时代码自动同步,有些情况下sizeof(type)或许还有意义,但是尽量避免,因为如果变量改变不能同载(overload)和重写(overried)的区别?

7、重载和重写的区别

从定义上来说:

重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。

重写:是指子类重新定义复类虚函数的方法。---虚函数的实现

从实现原理上来说:

重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和function func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!

重写:和多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)。

8、内存分配问题

从静态存储区域分配:内存在程序编译的时候就已经分配好了,这块内存在程序整个运行期间都存在,如全局变量,static变量。

在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时,这些存储单元都自动释放。栈内存分配运算置于处理器的指令集中,效率很高,但是分配的内存容量有限。

从堆上分配(动态内存分配)程序在运行的时候用malloc或者new申请任意多少的内存,程序员负责在何时用free或delete释放内存。动态内存的生存期自己决定,很灵活。

9、动态数组

申请的时候,从外向内,逐级申请;

释放的时候,从内向外,逐级释放;

c中:

申请:array = (int***)malloc(n1*sizeof(int**)) ;for(int i = 0 ; i < n1 ; i++){array[i] = (int***)malloc(n2*sizeof(int*)) ;for( int j = 0 ; j < n2 ; j++){array[i][j] = (int*)malloc(n3*sizeof(int)) ;}}释放:for(int i = 0 ; i < n2 ; i++)free(array[i][j]) ;for( int i = 0 ; i < n1 ;i++)free(array[i]);free array ;

c++中有两种方法,一是new-delete;一种是使用vector,推荐使用vector

一维:Int *p = new int[len] ; //new开辟新的空间之后,会返回这段内存的首地址;Delete[] p ;二维:Int **p = new int*[n1] ;For(int I = 0 ;i< n1 ; i++)P[i] = new int[n2] ;For(int I = 0 ;i< n1 ; i++)Delete[] P[i] ;P[i] = NULL ;Delete[] p ;使用vector:一维:Vector<int>  array(len) ;二维:Vector< vector<int> >   vecint(m ,vector<int>(n)); m行,n列Vecint[i][j]三维:Vector< vector<vector<int> > >  vecint(m ,vector< vector< int> >( n ,vector<int>(l) ) )  ; Vecint[i][j][l]

10、inline会一直展开么?

不一定,看编译器。

Inline对编译器来说只是一种建议,编译器可以选择忽略这个建议。比如,如果你将一个长达1000多行的函数指定为inline,编译器就会忽略这个inline,将这个函数还原为普通函数。

调用inline函数的时候,要保证内联函数的定义让编译器看到,也就是说内联函数的定义要在头文件中,这与通常的函数定义不太一样。但是如果你习惯将函数定义放在cpp文件中,或者想让头文件看起来简单一点,可以这样做:

//someInLine.h #ifndef SOMEINLINE_HInline Type Example(void);//…..其它的函数声明#include “someInLine.cpp”#endif// someInLine.cpp#include “someInLine.h”Type Example(void){//….}

11、malloc/free与new/delete

malloc/freec/c++语言的标准库函数,new/deletec++运算符。对于非内部数据类的对象而言,光用malloc/free不能满足动态对象的要求

new自动计算需要分配的空间,malloc需要手动计算;

new是类型安全的,malloc不是

new将调用constructor,而malloc不用;delete调用destructor,而free不能;

new/delete不需要库支持;malloc/free需要;

new/delete完全覆盖了malloc/free,为什么还需要malloc/free呢?

因为c++程序经常要调用c函数,而c程序只能用malloc/free管理动态内存;如果用free释放new,不能析构出错;用delete释放“malloc申请的动态内存”,理论上讲不会出错,但是程序可读性会变差。所以两者一般配对使用。

PS: Delete只会调用一次析构函数;

Delete[] 会调用每一个成员的析构函数;

12、基类的析构函数为什么要为虚函数?

如果基类的虚函数析构为虚函数,派生类在析构的生活,会首先析构派生类,再析构基类;如果基类的析构函数不是虚的,那么当删除对象的时候,就不能析构整个析构链。

13、尽可能使用const

任何可以使用const的情况下都要使用const;在声明变量或参数前面加上关键字const用于指明变量值不可修改,为类中的函数加上const限定表明该函数不会修改类成员变量的状态。Const变量、数据成员、函数、参数为编译时类型检查加上了一层保障,更好的尽早发现错误,强烈建议在一下几种情况下使用const:

  • 如果函数不会修改传入的引用或者指针类型的参数,这时参数用该是const类型;
  • 尽可能将函数声明为const,访问函数应该总是const,其他函数如果不会修改任何数据成员也应该是const,不要调用非const函数,不要返回对数据成员的非const指针或者引用;
  • 如果数据成员在对象构造之后不再改变,也将其定义为const;

14、值传递与引用

按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,调用代码中的原始值也随之改变。

可参考:http://blog.csdn.net/wfwd/archive/2006/05/30/763551.aspx

15、迭代器

使用迭代器时,通常可以编写程序使得要求迭代器有效的代码范围相对较短。然后,在该范围内,严格检查每一条语句,判断是否有元素添加或删除,从而相应地调整迭代器的值。

任何insert 或 push 操作都可能导致迭代器失效。当编写循环将元素插入到 vector 或deque 容器中时,程序必须确保迭代器在每次循环后都得到更新。resize 操作可能会使迭代器失效。在 vector 或 deque 容器上做resize 操作有可能会使其所有的迭代器都失效。对于所有的容器类型,如果 resize 操作压缩了容器,则指向已删除的元素迭代器失效。

0 0
原创粉丝点击