C和C++

C内存:

1.堆,(malloc的作用是开辟一个空间来供你使用,)

2.栈(局部变量、函数参数)

3.程序代码区(存放二进制代码)

4.全局、静态存储区(全局变量,static变量)

5.常量存储区(常量

C++

1.自由存储区(new)

2.static变量会初始化为缺省值,堆和栈上的变量是随机的不确定的。

2.堆和栈的区别

1.堆存放动态分配的对象----new出来的对象,生存期由程序控制

2.栈用来保存定义在函数内的非static对象,局部变量,仅仅在程序块内有意义

3.静态内存用来存放static对象,类static数据成员,以及定义在函数外部的变量

4.栈和静态内存的对象由编译器自动创建和销毁

3. 堆和自由存储区的区别?

堆是C语言和操作系统的术语,是操作系统维护的一块动态分配内存;自由存储是C++中通过new与delete动态分配和释放对象的抽象概念。他们并不是完全一样。
从技术上来说,堆(heap)是C语言和操作系统的术语。堆是操作系统所维护的一块特殊内存,它提供了动态分配的功能,当运行程序调用malloc()时就会从中分配,稍后调用free可把内存交还。而自由存储是C++中通过new和delete动态分配和释放对象的抽象概念,通过new来申请的内存区域可称为自由存储区。基本上,所有的C++编译器默认使用堆来实现自由存储,也即是缺省的全局运算符new和delete也许会按照malloc和free的方式来被实现,这时藉由new运算符分配的对象,说它在堆上也对,说它在自由存储区上也正确。
 

4. 程序编译的过程?

预处理、编译、汇编和链接

在这里插入图片描述

 

5. 计算机内部如何存储负数和浮点数?

负数比较容易,就是通过一个标志位和补码来表示。
拓展问题:

  • 什么是补码?
    负数补码为反码加1
    正数补码为原码

  • 负数为什么用补码?
    统一加减法,正负零问题

float 32位

在这里插入图片描述

 

double 64位

在这里插入图片描述

7. 左值和右值

 

  • 可以取地址的,有名字的,非临时的就是左值
  • 不能取地址的,没有名字的,临时的,通常生命周期就在某个表达式之内的就是右值

8. 什么是内存泄漏?面对内存泄漏和指针越界,你有哪些方法?你通常采用哪些方法来避免和减少这类错误?

用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元即为内存泄露。

第二部分:C v.s. C++

1. C和C++的区别?

C++是C的超集;
        C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制),

        C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事务)控制。

2. int fun() 和 int fun(void)的区别?
 

        在c中,int fun() 会解读为返回值为int(即使前面没有int,也是如此,但是在c++中如果没有返回类型将报错),输入类型和个数没有限制, 而int fun(void)则限制输入类型为一个void。


        在c++下,这两种情况都会解读为返回int类型,输入void类型

3. const 有什么用途


主要有三点:

1).定义只读变量,或者常量(只读变量和常量的区别参考下面一条);
2).修饰函数的参数和函数的返回值;
3).修饰函数的定义体,这里的函数为类的成员函数,被const修饰的成员函数代表不能修改成员变量的值,因此const成员函数只能调用const成员函数, 可以访问非const成员,但是不能修改;
 

4. 在C中用const 能定义真正意义上的常量吗?C++中的const呢?

不能。c中的const仅仅是从编译层来限定,不允许对const 变量进行赋值操作,在运行期是无效的,所以并非是真正的常量(比如通过指针对const变量是可以修改值的),

但是c++中是有区别的,c++在编译时会把const常量加入符号表,以后(仍然在编译期)遇到这个变量会从符号表中查找,所以在C++中是不可能修改到const变量的。
 

1). c中的局部const常量存储在栈空间,全局const常量存在只读存储区,所以全局const常量也是无法修改的,它是一个只读变量。
2). 这里需要说明的是,常量并非仅仅是不可修改,而是相对于变量,它的值在编译期已经决定,而不是在运行时决定。
3).c++中的const 和宏定义是有区别的,宏是在预编译期直接进行文本替换,而const发生在编译期,是可以进行类型检查和作用域检查的。
4).c语言中只有enum可以实现真正的常量。
5 ). c++中只有用字面量初始化的const常量会被加入符号表,而变量初始化的const常量依然只是只读变量。
6). c++中const成员为只读变量,可以通过指针修改const成员的值,另外const成员变量只能在初始化列表中进行初始化。
 

5. 宏和内联(inline)函数的比较?
1). 首先宏是C中引入的一种预处理功能;
2). 内联(inline)函数是C++中引入的一个新的关键字;C++中推荐使用内联函数来替代宏代码片段;
3). 内联函数将函数体直接扩展到调用内联函数的地方,这样减少了参数压栈,跳转,返回等过程;
4). 由于内联发生在编译阶段,所以内联相较宏,是有参数检查和返回值检查的,因此使用起来更为安全;

6. C++中有了malloc / free , 为什么还需要 new / delete?

1). malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
2). 对于非内部数据类型(自定义类型)的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。
由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作的运算符delete注意new/delete不是库函数
 

7. C和C++中的强制类型转换?

类型转换构造函数可以通过explicit来抑制其被隐式的调用)

1). static_cast   . 用于基本类型间的转换

2). dynamic_cast         用于有继承关系的类指针间的转换

3). reinterpret_cast        用于指针间的类型转换

4). const_cast        用于去掉变量的const属性

8. static 有什么用途

  • 1). 静态(局部/全局)变量
  • 2). 静态函数
  • 3). 类的静态数据成员
  • 4). 类的静态成员函数

9. 类的静态成员变量和静态成员函数各有哪些特性?


1). 静态成员变量需要在类内声明(加static),在类外初始化(不能加static),如下例所示;
2). 静态成员变量在类外单独分配存储空间,位于全局数据区,因此静态成员变量的生命周期不依赖于类的某个对象,而是所有类的对象共享静态成员变量;
3). 可以通过对象名直接访问公有静态成员变量;
4). 可以通过类名直接调用公有静态成员变量,即不需要通过对象,这一点是普通成员变量所不具备的。

C++语言支持函数重载,C语言不支持函数重载

11. 头文件中的 ifndef/define/endif 是干什么用的? 

相同点:
它们的作用是防止头文件被重复包含。

12. 当i是一个整数的时候++i和i++那个更快一点?i++和++i的区别是什么?

答:理论上++i更快,实际与编译器优化有关,通常几乎无差别。

i++和++i的考点比较多,简单来说,就是i++返回的是i的值,而++i返回的是i+1的值。

 第三部分:数组、指针 & 引用

1. 指针和引用的区别?

相同点:

  • 1). 都是地址的概念;
  • 2). 都是“指向”一块内存。指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名;
  • 3). 引用在内部实现其实是借助指针来实现的,一些场合下引用可以替代指针,比如作为函数形参。

不同点:

  • 1). 指针是一个实体,而引用(看起来,这点很重要)仅是个别名
  • 2). 引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;
  • 3). 引用不能为空,指针可以为空;
  • 4). “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;
  • 5). 指针和引用的自增(++)运算意义不一样;
  • 6). 引用是类型安全的,而指针不是 (引用比指针多了类型检查)
  • 7). 引用具有更好的可读性和实用性。

3. 三目运算符

在C中三目运算符(? :)的结果仅仅可以作为右值,比如如下的做法在C编译器下是会报错的,但是C++中却是可以是通过的。这个进步就是通过引用来实现的,因为下面的三目运算符的返回结果是一个引用,然后对引用进行赋值是允许的

第四部分:C++特性

1. 什么是面向对象(OOP)?面向对象的意义?

Object Oriented Programming, 面向对象是一种对现实世界理解和抽象的方法、思想,通过将需求要素转化为对象进行问题处理的一种思想。其核心思想是数据抽象、继承和动态绑定(多态)。
面向对象的意义在于:将日常生活中习惯的思维方式引入程序设计中;将需求中的概念直观的映射到解决方案中;以模块为中心构建可复用的软件系统;提高软件产品的可维护性和可扩展性。

2. 解释下封装、继承和多态?

1). 封装
封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为)。
封装的意义在于保护或者防止代码(数据)被我们无意中破坏。
从封装的角度看,public, private 和 protected 属性的特点如下。

  • 不管哪种属性,内类都是可以访问的
  • public 是一种暴露的手段,比如暴露接口,类的对象可以访问
  • private 是一种隐藏的手段,类的对象不能访问
  • protected 成员和 public 一样可以被子类继承

2). 继承
继承主要实现重用代码,节省开发时间。
子类可以继承父类的一些东西。

  • a.公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态(基类的私有成员仍然是私有的,不能被这个派生类的子类所访问)。
  • b.私有继承(private) 私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员(并且不能被这个派生类的子类所访问)。
  • c.保护继承(protected) 保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员(并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的)

3).多态
多态是指通过基类的指针或者引用,在运行时动态调用实际绑定对象函数的行为。与之相对应的编译时绑定函数称为静态绑定。多态是设计模式的基础,多态是框架的基础。

        浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 。
        深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象。
区别:

浅拷贝:引用类型其中一个对象改变了地址,就会影响另一个对象

深拷贝:改变新对象不会影响原对象,他们之前互不影响

4. 构造函数和析构函数的执行顺序?

  • 1). 首先调用父类的构造函数;
  • 2). 调用成员变量的构造函数;
  • 3). 调用类自身的构造函数。

用顺序与构造函数的调用顺序刚好相反,也即后构造的先析构

3. map 和 unordered_map 的区别?各自的优缺点?

        map 的内部实现是一个红黑树,红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜索树),其具有如下性质:红黑树具有自动排序的功能,因此map内部的所有元素都是有序的

        unordered_map 的内部实现是 hash 表。其具有如下性质:哈希表的建立比较耗费时间,占用内存相比红黑树要高

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值