C++面试题-----C++基础知识篇(补充)

tdcall、stdcall、pascall是什么?C++默认是哪种?

__cdecl、__stdcall是声明的函数调用协议。主要是传参和弹栈方面的不同。

__cdecl:一般c++用的是__cdecl

函数参数按照从右到左的顺序入栈

由调用函数者把参数弹出栈以清理堆栈

PS:那么为什么还需要_cdecl呢?当我们遇到这样的函数如fprintf()它的参数是可变的,不定长的。

__stdcall:windows里大都用的是__stdcall(API)

函数参数按照从右到左的顺序入栈

被调用的函数在返回前清理传送参数的栈

__fastcall:约定用于对性能要求非常高的场合

约定将函数的从左边开始的两个大小不大于4个字节(DWORD)的参数分别放在ECX和EDX寄存器,其余的参数仍旧自右向左压栈传送,

被调用的函数在返回前清理传送参数的堆栈

static_cast, dynamic_cast, reinterpret_cast, const_cast区别比较

static_cast <new_type> (expression) 静态转换

static_cast最接近于C风格转换了,但在无关类的类指针之间转换上,有安全性的提升

该运算符把exdivssion转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

①用于类层次结构中基类和子类之间指针或引用的转换。

进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。

②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。

③把空指针转换成目标类型的空指针。

④把任何类型的表达式转换成void类型。

注意:static_cast不能转换掉exdivssion的const、volitale、或者__unaligned属性。

dynamic_cast <new_type> (expression) 动态转换

动态转换确保类指针的转换是合适完整的,它有两个重要的约束条件,其一是要求new_type为指针或引用,其二是下行转换时要求基类是多态的(基类中包含至少一个虚函数)。

该运算符把exdivssion转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;

如果type-id是类指针类型,那么exdivssion也必须是一个指针,如果type-id是一个引用,那么exdivssion也必须是一个引用。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;

在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

reinterpret_cast <new_type> (expression) 重解释转换

这个转换是最“不安全”的,两个没有任何关系的类指针之间转换都可以用这个转换实现

const_cast <new_type> (expression) 常量向非常量转换

这个转换好理解,可以将常量转成非常量。

C++内存分配有几种方式

  1. 在静态存储区分配:此时的内存在程序编译的时候已经分配好,并且在程序的整个运行期间都存在。全局变量,static变量等在此存储。

  2. 在栈区分配:相关代码执行时创建,执行结束时被自动释放。局部变量在此存储。栈内存分配运算内置于处理器的指令集中,效率高,但容量有限。

  3. 在堆区分配:动态分配内存。用new/malloc时开辟,delete/free时释放。生存期由用户指定,灵活。但有内存泄露等问题。

常见内存错误及对策

1. 内存分配未成功,却被使用。

对策:使用内存之前检查是否分配成功。用p!=NULL判断。

2. 内存分配成功,未初始化就被使用。

内存的缺省值没有统一的标准。大部分编译器以0作为初始值,但不完全是。
对策:内存初始化时赋初值。

3. 内存操作越界。

对策:只能是小心了。

4. 释放了内存,仍然使用。

(1) 使用显示delete和free的野指针。
对策:释放完内存,将指针置为NULL。

(2) 使用隐式delete和free的野指针。主要是指函数返回指向栈内存的指针或引用。
对策:当然是不要返回就可以了。

5. 未释放内存,导致内存泄露。

用new/malloc开辟了内存,没用delete/free释放.
对策:new和delete的个数一定相同;malloc和free的个数一定相同;new[]和[]delete一定对应。

模板的实现可以放在cpp里吗?为什么?

模板声明和实现要放在一个文件。因为放在CPP里面实现会编译不过。

volatile

  1. volatile的本意是“易变的” 因为访问寄存器要比访问内存单元快的多,所以编译器一般都会作减少存取内存的优化,但有可能会读脏数据。当要求使用volatile声明变量值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。精确地说就是,遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问;如果不使用valatile,则编译器将对所声明的语句进行优化。(简洁的说就是:volatile关键词影响编译器编译的结果,用volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算不要进行编译优化,以免出错)
  2. 看两个事例:
    1>告诉compiler不能做任何优化
    比如要往某一地址送两指令:
    int *ip =…; //设备地址
    *ip = 1; //第一个指令
    *ip = 2; //第二个指令
    以上程序compiler可能做优化而成:
    int *ip = …;
    *ip = 2;
    结果第一个指令丢失。如果用volatile, compiler就不允许做任何的优化,从而保证程序的原意:
    volatile int *ip = …;
    *ip = 1;
    *ip = 2;
    即使你要compiler做优化,它也不会把两次付值语句间化为一。它只能做其它的优化。
    volatile关键字的使用示例

struct和class有什么区别?

C++中,class与struct都可以定义一个类。他们有以下两点区别:

  1. 默认继承权限,如果不指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理;

  2. 成员的默认访问权限。class的成员默认是private权限,struct默认是public权限。

以上两点也是struct和class最基本的差别,也是最本质的差别;

但是在C++中,struct进行了扩展,现在它已经不仅仅是一个包含不同数据类型的数据结构了,它包括了更多的功能。

Struct能包含成员函数、有自己的构造函数、可以有析构函数、支持继承、支持多态、支持Private、Protected、Public关键字。

如果是class的父类是struct关键字描述的,那么默认访问属性是什么?

当出现这种情况时,到底默认是public继承还是private继承,取决于子类而不是基类。

class可以继承自struct修饰的类;同时,struct也可以继承自class修饰的类,继承属性如下列描述:

class A{};

class B:A{}; // private 继承

struct B:A{}; // public 继承

最后,那么到底是使用struct,还是使用class呢?

一般来说,两个关键字都是可以的,但是由于编程规范的问题,如果要定义的是一种数据结构,那么用struct,如果是一种对象的话,那么用class。

default

default也是一种case,但它是指“除了指定的几个case以外的其他情况”,它无论放在哪个位置,都是等待读完所有case且没有符合的条件下再被使用。
唯一需要注意的就是,default和其他case一样都是一直往下读的,碰到break停止。而我们平常使用时将其放在句尾,还有在每个语句后打break的习惯,可能会让我们混肴这一点,产生default就是结束语这样简单的思维错误。

内存页面大小

绝大多数处理器上的内存页的默认大小都是 4KB,虽然部分处理器会使用 8KB、16KB 或者 64KB 作为默认的页面大小,但是 4KB 的页面仍然是操作系统默认内存页配置的主流;除了正常的内存页大小之外,不同的处理器上也包含不同大小的大页面,我们在 x86 处理器上就可以使用 2MB 的内存页。

计算机网络

ip地址0,0,0,0是什么意思

首先说一下ip地址:127.0.0.1,这是大家最熟悉不过的本地loopback(回环)地址,代表本地主机,在windows和linux上等价于localhost,可在C:\Windows\System32\drivers\etc\hosts文件中修改主机名或定义ipv6地址(# ::1 localhost)。
192.168.1.x,是公网ip地址,这些是在网络中代表本机的ip地址,可通过此ip地址远程访问或控制主机。
0.0.0.0,最特殊的一个ip地址,代表的是本机所有ip地址,不管你有多少个网口,多少个ip,如果监听本机的0.0.0.0上的端口,就等于监听机器上的所有ip端口。换句话说,就是只要数据报目的地址是你机器上的一个ip地址,那么就能被接受。这个ip相当于java中的this,代表当前设备的IP。

端口占用命令

netstat -ano:可以看到系统当前所有的端口使用情况;
netstat -ano |findstr “端口号”,然后回车就可以看到这个端口被哪个应用占用;

mtu

最大传输单元(Maximum Transmission Unit,MTU)用来通知对方所能接受数据服务单元的最大尺寸,说明发送方能够接受的有效载荷大小。

内存转储文件

内存转储是用于系统崩溃时,将内存中的数据转储保存在转储文件中,供给有关人员进行排错分析用途。而它所保存生成的文件就叫做内存转储文件。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值