C++基础知识

1.new、delete、malloc、free关系

malloc与free是C++/C语言的标准库函数;
new与delete是C++的运算符。它们都可用于申请动态内存和释放内存。

new调用对象的构造函数,delete会调用对象的析构函数。

由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。

2.delete与 delete []区别

delete只会调用一次析构函数,而delete[]会调用每一个成员的析构函数。
delete与new配套,delete []与new []配套

对于内建简单数据类型,delete和delete[]功能是相同的。
对于自定义的复杂数据类型,delete和delete[]不能互用。
delete[]删除一个数组,delete删除一个指针。

3.多态,虚函数,纯虚函数

C++的多态性具体体现在运行和编译两个方面:

  • 在程序运行时的多态性通过继承和虚函数来体现;
  • 在程序编译时多态性体现在函数和运算符的重载上;

从基类继承来的纯虚函数,在派生类中仍是虚函数。如果一个类中至少有一个纯虚函数,那么这个类被称为抽象类(abstract class)。
抽象类必须用作派生其他类的基类,而不能用于直接创建对象实例。

4.什么是“引用”?

引用就是某个目标变量的“别名”,对应用的操作与对变量直接操作效果完全相同。申明一个引用的时候,要对其进行初始化。
“引用作参数”
使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;
使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差。
“常引用”
要保护传递给函数的数据不在函数中被改变,就应使用常引用。
“引用”作函数返回值
在内存中不产生被返回值的副本;
无法返回局部变量的引用;
无法返回函数内部new分配的内存的引用;

5.结构与联合

结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在。

6.重载(overload)和重写(overried)

重载:是指允许存在多个同名函数,而这些函数的参数表不同(重载和多态无关);
重写:是指子类重新定义父类虚函数的方法(和多态真正相关)。

7.分别写出BOOL,int,float,指针类型的变量a 与“零”的比较语句
BOOL : if ( !a ) or if(a)
int : if ( a == 0)
float : const EXPRESSION EXP = 0.000001
if ( a < EXP && a >-EXP)
pointer : if ( a != NULL) or if(a == NULL)
8.const与#define

const作用:定义常量、修饰函数参数、修饰函数返回值三个作用。被Const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。

9.数组与指针

数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。
修改内容上的差别

char a[] = “hello”;
a[0] = ‘X’;
char *p = “world”; // 注意p 指向常量字符串
p[0] = ‘X’; // 编译器不能发现该错误,运行时错误

使用sizeof 的差别
用运算符sizeof 可以计算出数组的容量(字节数);
sizeof( p ) 为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。C++/C 语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。
注意 当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。

char a[] = "hello world";
char *p = a;
cout<< sizeof(a) << endl; // 12 字节
cout<< sizeof(p) << endl; // 4 字节
计算数组和指针的内存容量
void Func(char a[100])
{
cout<< sizeof(a) << endl; // 4 字节而不是100 字节
}
10.复杂声明
int (*s[10])(int) ;
//函数指针数组,每个指针指向一个int func(int param)的函数;

void * ( * (*fp1)(int))[10];
 //fp1是一个指针,指向一个函数,
//这个函数的参数为int型,函数的返回值是一个指针,
//这个指针指向一个数组,这个数组有10个元素,每个元素是一个void*型指针。

float (*(* fp2)(int,int,int))(int); 
//fp2是一个指针,指向一个函数,这个函数的参数为3个int型,
//函数的返回值是一个指针,这个指针指向一个函数,
//这个函数的参数为int型,函数的返回值是float型。

int (* ( * fp3)())[10](); 
//fp3是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是一个指针,
//这个指针指向一个数组,这个数组有10个元素,每个元素是一个指针,指向一个函数,
//这个函数的参数为空,函数的返回值是int型。
11.内存的分配方式
  • 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。
  • 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。
  • 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。
12.全局变量和局部变量

生命周期:
全局变量随主程序创建和创建,随主程序销毁而销毁;
局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在;
使用方式:
通过声明后全局变量程序的各个部分都可以用到;局部变量只能在局部使用;分配在栈区。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值