C和 C ++ 的区别

1.内联函数: 在函数的调用点,把函数的代码全部展开,编译阶段(一种更安全(进行类型检查)宏)

宏: 预编译阶段(字符串替换,不进行类型检查,无法调式)

内联函数和普通函数的区别:

内联函数没有标准的函数栈帧的开辟和回退

普通函数:

函数调用的开销大于函数执行的开销->写成内联函数

内联函数本文件可见(不产生符号),一般写在头文件中

内联函数和static函数的区别:

本文件可见,作用域相同

Static有正常的函数栈帧的开辟和回退

内联函数不产生符号,静态函数产生符号

Static()产生的符号:是local的    (链接器只处理global的符号)

 

符号解析-〉符号分配内存虚拟地址-〉符号重定位   针对global符号

 

Inline只在release版本起作用

Debug版本里面,inline函数的调用也需要栈帧的开辟和回退(方便调试)

Inline只是对编译器的一个建议  编译器来决定

递归函数不可能处理成内联函数(编译阶段不知道函数展开几次,只有在运行时才知道)

 

2.函数重载:(1.函数名相同,参数列表不同,不能仅通过返回值不同;2.作用域相同;3.对实参的值是否有影响  const/volatile修饰指针/引用)

C:函数产生符号 根据函数名称

C++:函数产生符号 函数名称+形参类型+形参个数 

 3.多态

静多态:重载和模板

动多态:继承派生里的多态(虚函数)

 

C++允许不同作用域产生相同的符号,函数调用时先在局部找,若有,就调用局部的函数

 

编译器的类型转换:

C和 C ++ 的区别

横向:无条件转换,纵向:当出现纵向的两个类型,下面的转换为上面的(提高运算精度)

C和C++代码之间的互相调用

在C++中调用C的函数: 

C和 C ++ 的区别

只需要extern”c”声明

 

在C中调用C++的函数:

Extern”c”  //里面的符号都是按照C规则生成的

{

函数声明;

}

 C和 C ++ 的区别

 

把.cpp文件里的源代码括在extern”c”中,这样.cpp里的代码就会用c编译器编译,或在.cpp文件中加#ifdef_cplusplus  #endif,如果用C++编译器编译的就会按照C风格编译,如果是C编译器,也是会按照C风格编译,这样就保证了不管是C编译器还是C++编译器编译,都会按照C风格编译

 

当C++以库的形式提供源代码,在C中如何调用:(间接调用(重新封装))

C和 C ++ 的区别

 静态链接和动态链接的区别:

静态链接:链接.lib库(在可执行文件生成之前链接,快)

动态链接:链接.dll库(程序运行以后链接,用到哪个才会链接哪个,减少可执行文件的大小)

 

4.Const

C:常变量,不能修改,不能做左值,不是必须初始化的,不能做数组下标

Const修饰的常变量和普通变量的唯一区别:两者编译方式完全一样

常变量定义以后,不能作为左值存在

C++:必须初始化,可以做数组的下标

Const的编译规则(跟宏,inline的编译方式比较像) 所有在使用常量的名字的地方全部替换成常量的初始值

常量-〉常变量     用一个变量去初始化一个常量(编译阶段引用不明确的值得时候),常量退化为常变量

C++中const生成的符号是local的,只允许本文件可见

在const常量定义处外加extern    ->global

 

5.引用:

1.必须要进行初始化 

2.初始化的值必须可以取地址

3.引用不可以改变

4.访问引用变量,永远访问它所引用的内存

定义引用变量是否开辟内存   -〉 开辟内存

引用底层就是用指针实现的  用到引用变量的时候会自动解引用

 

 

Constint *p;

Intconst *p;

Int*const p;  //常量

Constint *const p;  //常量  const直接修饰了变量p

常量被修改:

直接:做左值

间接:常量的指针或者引用泄露出去

Const与一级指针结合:

constint*->int*  错误       int*->const int*  正确

普通指针可以用普通指针指向也可以用常量指针指向

Inta=10;

Int*p=&a;

Int*const p=&a;

Constint *p=&a;

 

 

Inta=10;

Constint *p=&a;

Int*q=p; 

//不可以,因为p可以存变量的地址也可以存常量的地址,一旦指向const int a,就会出问题。

#include<typeinfo>

Cout<<typeif(p).name()<<endl;   

对编译器来说,const如果没有修饰指针/引用,不用考虑const

 

Volatile:

1.   防止编译器对汇编指令进行顺序上的优化

2.   防止寄存器存储变量的副本值  应用在多线程程序中

Barrier:防止运行时cpu对指令顺序上的调优

 

 

Const&的结合:  const int &b     int const &b

Int  *const ptemp=(int*)0x0018ff44;   int *const&p=ptemp;

Int*const &p=(int*)0x0018ff44;

*p=10;

 

Const引用常量包括可寻址的常量和不可寻址的常量(都需要常引用)

当引用一个不可寻址的常量时,系统会自动产生一个临时量让我们来引用

引用不参与类型

 

 

Const跟二级指针的结合:

类型必须完全匹配

Constint **q;

Int*const *q;

Int** const q;

 

Int a=10;

Const Int *p=&a;

Constint **q=&p;   //**q<->*p    *q<->P

//const int b=10;   *q=&b; 即:p=&b(普通指针指向常量的地址)

//errorp有可能指向常量的地址  p可能修改常量的值   int**->cons tint**

Error:     Const int*->int*;   Int **->cnst int**;   cons tint**->int**

Const在中间转化为一级指针

Inta=10;

Const Int *p=&a;  //如果p指向常量的地址,会有修改常量的隐患

Constint **q=&p;   //*q==p

 

Inta=10;

 Int *p=&a; //如果p指向常量的地址,会有修改常量的隐患

Constint *const*q=&p;   //*q==p

 

Inta=10;

Const Int *p=&a;

Constint *&q=p;  //  p==q    同上

 

Inta=10;

Int*p=&a;

Int*const *q=&p;//(const前面的指针/引用不起作用) ok: int *->const int*

 

Int  a=10;

Int*p=&a;

Int** const q=&p;  //ok  :const没有修饰指针/引用

 

Inta=10;

ConstInt *p=&a;

const Int **q=&p;  

//error:  cons tint**->int**  p如果指向常量的地址,会有风险

 

 

Inta=10;

Int*const p=&a;

Int*const*q=&p;   //error: const int*->int *  p的地址被泄露出去了

 

 

函数的返回值:

x<=4      eax

4<x<=8   eax edx

>8  调用之前产生临时量 函数调用时,先压实参,把临时量的地址当最后一个参数压栈,通过ebp+8返回

 

临时量产生:

函数调用之前;

函数的return之时;

函数调用之后;

 

引用:引用必须初始化  引用必须可以取地址  一经引用不能再引用其他变量

寄存器带回的值不可以取地址

要引用常量,而且常量没办法取地址,可以通过常引用来引用(可以产生临时量),引用的是临时量的地址

 

不能返回局部变量的指针/地址,作用域过了

 

6.New:   先开辟内存  再初始化

1.开辟内存   

2.初始化自定义类型的变量(初始化类的对象)   

New->malloc  初始化(内置类型  自定义 调用构造函数)

Delete->析构 free

Malloc参数>=0都会分配内存    空闲链表  位图

Eg:申请一个字节,其实会向内核申请好多页面, 其他的空闲内存可供下一次申请内存时使用,减少用户——〉内核的访问,节省时间

new和malloc的区别:

C和 C ++ 的区别

*存储区(free   store)是C++两个动态内存区域之一,使用new和delete来予以分配和释放。在*存储区(free   store)中,对象的生存周期可以比存放它的内存区的生存周期短;这也就是说,我们可以获得一片内存区而不用马上对其进行初始化;同时,在对象被销毁之后,也不用马上收回其占用的内存区。在对象被销毁而其占用的内存区还未被收回的这段时间内,我们可以通过void*型的指针访问这片区域,但是其原始对象的非静态成员以及成员函数(即使我们知道了它们的地址)都不能被访问或者操纵。  

C和 C ++ 的区别

<128kbrk() 小内存       128K mmap()(大内存

 

 7.作用域

C的作用域:

局部作用域    全局作用域

C++的作用域:

局部作用域   类作用域  名字空间作用域namespace->全局的名字空间作用域和局部的名字空间作用域

Intgdata=20;  //全局作用域

Namespacemyname

{

Intgdata=10;  //名字空间作用域

}

 

Usingmyname::gdata; 

//using声明,把名字空间里的gdata暴露在全局作用域下,在使用using myname::gdata时可以不写名字空间作用域

 

Usingnamespace myname;

 //using指示符,把名字空间myname里的内容全暴露在全局作用域下

Intmain()

{

Intgdata=30;  //局部作用域

Cout<<gdata<<endl;

Return0;

}