一、C和C++的区别是什么?

C是面向过程的语言,C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛。

C中函数不能进行重载,C++函数可以重载

C++在C的基础上增添类,C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制),而对于C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事务)控制。

C++中struct和class除了默认访问权限外,别的功能几乎都相同。

二、关键字static、const、extern作用

static和const的作用在描述时主要从类内和类外两个方面去讲:

static关键字的作用:

(1)函数体内static变量的作用范围为该函数体,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

(2)在模块内的static全局变量和函数可以被模块内的函数访问,但不能被模块外其它函数访问;

(3)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

(4)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

const关键字的作用:

(1)阻止一个变量被改变

(2)声明常量指针和指针常量

(3)const修饰形参,表明它是一个输入参数,在函数内部不能改变其值

(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量(const成员一般在成员初始化列表处初始化)

(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为”左值”。

extern关键字的作用:

(1)extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。

(2)extern "C"的作用是让 C++ 编译器将extern "C"声明的代码当作 C 语言代码处理,可以避免 C++ 因符号修饰导致代码不能和C语言库中的符号进行链接。

三、sizeof和strlen的区别

(1)sizeof是运算符,而strlen是函数;

(2)sizeof的用法是sizeof(参数),这个参数可以是数组,指针,类型,对象,甚至是函数,其值在编译的时候就计算好了,而strlen的参数必须是字符型指针(char*),其值必须在函数运行的时候才能计算出来;

(3) sizeof的功能是获得保证能容纳实现的建立的最大对象的字节的大小,而strlen的功能是返回字符串的长度,切记这里的字符串的长度是包括结束符的;

(4)当数组作为参数传递给函数的时候,传的是指针,而不是数组,传递数组的首地址;

char str[20] = "0123456789";
int a = strlen(str); //10
int b = sizeof(str);//20

  

四、指针和引用的区别

(1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。

(2)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)

(3)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化

(4)指针的值在初始化后可以改变,即指向其它的存储单元,而引用初始化后就不会再改变。

(5)"sizeof引用"得到的是所指向的变量(对象)的大小,而"sizeof指针"得到的是指针本身的大小。

(6)作为参数传递时,二者有本质不同:指针传参本质是值传递,被调函数的形参作为局部变量在栈中开辟内存以存放由主调函数放进来的实参值,从而形成实参的一个副本。而引用传递时,被调函数对形参的任何操作都会通过一个间接寻址的方式影响主调函数中的实参变量。

如果想通过指针参数传递来改变主调函数中的相关变量,可以使用指针的指针或者指针引用。

五 、指针数组、数组指针、函数指针

指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身的大小决定,每一个元素都是一个指针,在32 位系统下任何类型的指针永远是占4 个字节。它是“储存指针的数组”的简称。

数组指针:首先它是一个指针,它指向一个数组。在32 位系统下任何类型的指针永远是占4 个字节,至于它指向的数组占多少字节,不知道,具体要看数组大小。它是“指向数组的指针”的简称。

一个小栗子:

    int arr[] ={1,2,3,4,5};
int *ptr =(int *)(&arr+1); //2 5
int *ptr =(int *)(arr+1); //2 1
cout<<*(arr+1)<<" "<<*(ptr-1)<<endl;

  

//数组名arr可以作为数组的首地址,而&a是数组的指针。 //arr和&arr指向的是同一块地址,但他们+1后的效果不同,arr+1是一个元素的内存大小(增加4) //而&arr+1增加的是整个数组的内存 

数组指针(行指针)

  int a[2][3] = {{1,2,3},{4,5,6}};
int (*p)[3];
p = a;
p++;
cout<<**p<<endl; //4 the second rank

  

六、C++内存布局

C/C++程序编译时内存分为5大存储区

(1)栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量值等,其操作方法类似数据结构中的栈。

(2)堆区(heap):一般由程序员分配释放,与数据结构中的堆毫无关系,分配方式类似于链表。

(3)全局/静态区(static):全局变量和静态变量的存储是放在一起的,在程序编译时分配。

(4)文字常量区:存放常量字符串。

(5)程序代码区:存放函数体(类的成员函数、全局函数)的二进制代码

int a=0; //全局初始化区
char *p1; //全局未初始化区
void main()
{
int b; //栈
char s[]="bb"; //栈
char *p2; //栈
char *p3="123"; //其中,“123\0”常量区,p3在栈区
static int c=0; //全局区
p1=(char*)malloc(10); //10个字节区域在堆区
strcpy(p1,"123"); //"123\0"在常量区,编译器 可能 会优化为和p3的指向同一块区域

  

C/C++内存分配有三种方式:

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

(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。

栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。

动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏。

另外频繁地分配和释放不同大小的堆空间将会产生堆内碎块。

七、堆和栈的区别

(1)申请方式

stack:

由系统自动分配。例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间

heap:

需要程序员自己申请,并指明大小,在c中malloc函数

如p1 = (char *)malloc(10);

在C++中用new运算符

如p2 = (char *)malloc(10);

但是注意p1、p2本身是在栈中的。

(2)申请后系统的响应

栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

堆: 首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲 结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

(3)申请大小的限制及生长方向

栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也可能是1M,它是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小 。

堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

(4)申请效率的比较:

栈由系统自动分配,速度较快。但程序员是无法控制的。

堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.

另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。

(5)堆和栈中的存储内容

栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的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不是库函数。

(3)C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。

(4)new可以认为是malloc加构造函数的执行。new出来的指针是直接带类型信息的。而malloc返回的都是void指针。

九 、常见的内存错误及对策

(1)内存尚未分配成功,却使用了它;

解决办法:在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口使用assert(p != NULL) 进行检查,如果是用malloc或者new来申请的,应该用

if (p == NULL)或者 if (p != NULL)来进行防错处理。

(2)内存分配虽然成功,但是尚未初始化就引用它;

错误原因:一是没有初始化的观念,二是误以为内存的缺省初值全为零,导致引用初值错误(如数组)。

解决办法:内存的缺省初值是什么并没有统一的标准,尽管有些时候为零值,但是宁可信其有,不可信其无,无论以何种方式创建数组,都要赋初值。

(3)内存分配成功并初始化,但是超过了内存的边界;

这种问题常出现在数组越界,写程序是要仔细。

(4)忘记释放内存,造成内存泄露;

含有这种错误的函数每次被调用都会丢失一块内存,开始时内存充足,看不到错误,但终有一次程序死掉,报告内存耗尽。

(5)释放了内存却继续使用它

产生原因:1.程序中的对象调用关系过于复杂,难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。

2.函数return语句写错了,注意不要返回指向“栈内存”的指针或者引用,因为该内存在函数体结束时理论上被自动销毁。

3.使用free或者delete释放了内存后,没有将指针设置为null,导致产生野指针。

解决办法:小心仔细。

内存管理需要遵循的规则

(1)用malloc 或者 new 申请内存之后,应该立即检查指针值是否为 NULL ,防止使用指针值为NULL的内存;

(2)不要忘记数组和动态内存赋初值,防止未被初始化的内存作为右值使用;

(3)避免数组或者指针下标越界,特别要当心“多1”或者“少1”的操作;

(4)动态内存的申请与释放必须配对,防止内存泄露;

(5)用free或者delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”;

十、字节对齐问题

为什么要使用字节对齐?

字节对齐是C/C++编译器的一种技术手段,主要是在可接受空间浪费的前提下,尽可能地提高对相同元素过程的快速处理。(比如32位系统,4字节对齐能使CPU访问速度提高)

需要字节对齐的根本原因在于CPU访问数据的效率问题。

字节对齐的原则

精美面试题。

以上是文章全部内容,有需要学习交流的友人请加入C++交流群,有问题一起交流,一起进步!前提是你是学技术的。感谢阅读!喜欢点个关注吧。

点此加入该群

2019 C/C++《阿里》面试题总结的更多相关文章

  1. 2019大厂Java岗面试题全曝光,刷完这1020道,金三银四大厂等你

    2019大厂Java岗面试题全曝光,刷完这1020道,金三银四大厂等你 前言: 本文收集整理了各大厂常见面试题N道,你想要的这里都有 内容涵盖:Java.MyBatis.ZooKeeper.Dubbo ...

  2. 2019年最新阿里Java工程师面试题

    一.单选题(共10题,每题5分) 1 关于设计模式遵循的原则,说法错误的是?   A.组合优于继承 B.针对实现编程 C.对扩展开放,对修改关闭 D.降低对象之间的耦合 参考答案:B 答案解析: 设计 ...

  3. 2019届校招前端面试题整理——HTML、CSS篇

    前言 2019届校招陆陆续续开始了,整理了一些高频的面试题. HTML部分 1. 什么是<!DOCTYPE>? DOCTYPE是html5标准网页声明,且必须声明在HTML文档的第一行.来 ...

  4. 直击 KubeCon 2019 现场,阿里云 Hands-on Workshop 亮点回顾

    2019 年 6 月 24 日,KubeCon + CloudNativeCon 第二次在中国举办.此次大会阿里共有 26 个技术演讲入选,并有两场沙龙活动,阿里云专家也与技术极客们也再次相聚.Kub ...

  5. 【Android归纳】阿里笔试题之Android网络优化

    记得这是阿里校招笔试的一道问答题 答案是小伙伴们之后一起拼出来的,不乏有些飘忽的东西,须要的朋友能够做个參考(详细细节能够自行百度).欢迎提出更好的建议. 在client方面: 1.降低网络请求的数量 ...

  6. 干货 干货 2019阿里巴巴Android40道基本面试题

    找工作还是需要大家不要经常,有我们干这一行的接触人本来就不多 难免看到面试官会紧张,主要是因为怕面试官问的问题到不上来,那时候不要着急 ,答不上了的千万不然胡扯一些,直接就给面试官说这块我还没接触到, ...

  7. 2019 北森java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.北森等公司offer,岗位是Java后端开发,因为发展原因最终选择去了北森,入职一年时间了,也成为了面试官,之 ...

  8. 2019 多点Dmalljava面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.多点Dmall等公司offer,岗位是Java后端开发,因为发展原因最终选择去了多点Dmall,入职一年时间了 ...

  9. 2019 美柚java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.美柚等公司offer,岗位是Java后端开发,因为发展原因最终选择去了美柚,入职一年时间了,也成为了面试官,之 ...

  10. 2019 开创java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.开创等公司offer,岗位是Java后端开发,因为发展原因最终选择去了开创,入职一年时间了,也成为了面试官,之 ...

随机推荐

  1. 26.Apache Solr RCE

    多事之秋,刚爆出来shiro的RCE,紧接着solr服务器就出了RCE 自从漏洞爆出来已经一段时间,复现漏洞多如牛毛,我这里来水一篇 漏洞简介 什么是solr服务器? Solr是一个独立的企业级搜索应 ...

  2. 大规模定制模式之于MES的三点思考

    大规模定制(Mass Custermization) ,其目标是大规模生产定制化产品,并且在效率.质量(一致性)等指标方面与大规模批量生产等齐. 这是一种理想或者追求,其提出的背景是目前越发普遍的多品 ...

  3. Docker容器进入的4种方式以及tomcat查看日志

    docker logs 查看实时日志 原文:http://www.cnblogs.com/qufanblog/p/6927411.html docker logs -f -t --since=&quo ...

  4. List转换数组 数组转换List

    数组转List package listtoArray; import java.util.ArrayList;import java.util.Arrays;import java.util.Col ...

  5. Linux Shell脚本编程while语句

    Linux Shell脚本编程while语句案例 1,每隔3秒,打印一次系统负载 #!/bin/bash while truedo    uptime    sleep 3done 2,把监控结果保存 ...

  6. 《linux就该这么学》课堂笔记16 bind域名解析

    1.DNS域名解析服务 DNS(Domain Name System,域名系统)是一项用于管理和解析域名与IP地址对应关系的技术,就是能够接受用户输入的域名或IP地址,然后自动查找与之匹配(或者说具有 ...

  7. robotframework连接mysql

    1.安装mysql数据库,并启动,创建数据库test及user表(可以自定义) 2.配置robotframework环境加载DatabaseLibrary 3.安装pymysql,下载地址:https ...

  8. wordpress添加post_type自定义文章类型

    wordpress很强大,能当博客也能进行二次开发出很完善的内容管理系统满足企业运营需求,比如可以添加products产品模型.汽车模型等,如何实现呢?添加post_type自定义文章类型就可以了 p ...

  9. 【java】oracle好用,但java运行缺失右括号

    可能原因SQL拼接有空格被省略导致sql粘连. 解决办法,扩大拼接或者缩小拼接范围.

  10. 使用plv8+hashids生成短链接服务

    有写过一个集成npm plv8 以及shortid生成短链接id服务,实际上我们可以集成触发器自动生成url对应的短链接地址,hashids也是一个不错的选择. 以下是一个别人写的一个博客实现可以参考 ...