这一部分是C/C++程序员在面试的时候会被问到的一些题目的汇总。来源于基本笔试面试书籍,可能有一部分题比较老,但是这也算是基础中的基础,就归纳归纳放上来了。大牛们看到一笑而过就好,普通人看看要是能补上一两个模糊的知识点,也算有点进步吧。

1.简述变量声明和定义的区别。

为变量分配地址和存储空间的称为定义,不分配地址的称为声明。一个变量可以在多个地方声明,但是只在一个地方定义。加入extern修饰的是变量的声明,说明此变量将在文件以外或在文件后面部分定义。

2.简述sizeof和strlen的区别

最常考察的题目之一。主要区别如下:

1)sizeof是一个操作符,strlen是库函数。

2)sizeof的参数可以是数据的类型,也可以是变量,而strlen只能以结尾为‘\0‘的字符串作参数。

3)编译器在编译时就计算出了sizeof的结果。而strlen 函数必须在运行时才能计算出来。并且sizeof计算的是数据类型占内存的大小,而strlen计算的是字符串实际的长度。

4)数组做sizeof的参数不退化,传递给strlen就退化为指针了。

3.说说C和C++中的static有什么作用

这个真的在面试的时候被问过。

在C中static用来修饰局部静态变量和外部静态变量、函数。而C++中除了上述功能外,还用来定义类的成员变量和函数。即静态成员和静态成员函数。编程时最常用的是static的记忆性,和全局性的特点可以让在不同时期调用的函数进行通信,传递信息,而C++的静态成员则可以在多个对象实例间进行通信,传递信息。

4.C和C++中动态内存分配有什么方法,有何区别

C里面一般用malloc/free,C++可用malloc/free和new/delete。区别见找工作笔试面试那些事儿(3)---内存管理那些事中的内容。

5.简述C、C++程序编译的内存分配情况

之前提过,主要有静态存储区分配,在堆上和栈上分配三种,具体场景见找工作笔试面试那些事儿(3)---内存管理那些事中的内容。

6.说说strcpy、sprintf与memcpy三个函数

三个函数的功能分别为:

strcpy:实现字符串变量间的拷贝
       sprintf:主要实现其他数据类型格式到字符串的转化

Memcpy:主要是内存块间的拷贝

它们的区别有:

(1)操作对象不同,strcpy的两个操作对象均为字符串,sprintf的操作源对象可以是多种数据类型,目的操作对象是字符串,memcpy 的两个对象就是两个任意可操作的内存地址,并不限于何种数据类型。

(2)执行效率不同,memcpy最高,strcpy次之,sprintf的效率最低。

7.说说拷贝构造函数和赋值运算符

拷贝构造函数和赋值运算符有以下两个不同之处:

(1)拷贝构造函数生成新的类对象,而赋值运算符不能。

(2)由于拷贝构造函数是直接构造一个新的类对象,所以在初始化这个对象之前不用检验源对象是否和新建对象相同。而赋值运算符则需要这个操作,另外赋值运算中如果原来的对象中有内存分配要先把内存释放掉(这一点在之前找工作笔试面试那些事儿(5)---构造函数、析构函数和赋值函数中提到了)。

8.简述类成员函数的重写、重载和隐藏的区别

找工作笔试面试那些事儿(4)---C++函数高级特征中所述。

9.用递归和非递归两种方法翻转一个链表

先定义一下链表:

typedef struct node
{
ElemType data;
struct node * next;
}ListNode;
typedef struct
{
ListNode *head;
int size;
ListNode *tail;
}List;
/*********************************************************
非递归的翻转实际上就是使用循环,依次后移指针,
并将遇到的链表指针反转
*********************************************************/
void ReserveList(List * plist) //非递归实现,
{
ListNode * phead; //新链表的头 开始的第一个节点
ListNode * pt; //旧链表的头 开始的第二个节点
ListNode * pn; //旧链表头的下一个
phead = plist->head;
if(phead && phead->next&& phead->next->next) //首先确定
{
phead = plist->head->next; //新链表就是以第一个节点开始,依次在表头添加节点,添加的节点是旧链表的第一个节点
pt = phead->next; //旧链表,旧链表被取走头结点之后放入新链表的表头,
pn = pt->next;
phead->next = 0;
while(pt)
{
pn = pt->next; //pn是旧链表的第二个节点
pt ->next = phead; //取旧链表的第一个节点插入新链表
phead = pt;
pt = pn; //旧链表往后移动
}
}
plist->head->next = phead; //新链表重新赋值到整个链表
}
/*********************************************************
递归思想,原理也是从就链表上依次取元素放入到新链表
直到原始链表被取完,得到新链表
*********************************************************/
ListNode * ReserveListRe(ListNode * oldlist,ListNode * newlist)
{
ListNode * pt;
pt = oldlist->next; //取旧链表的表头,pt是现在的旧链表
oldlist->next = newlist; //就旧链表插入到新链表
newlist = oldlist; //如果旧链表是空,表示旧链表被取完了,新链表就是翻转之后的链表
return (pt == NULL) ? newlist : ReserveListRe(pt,newlist);
}

10.谈谈对C++的引用和C语言的指针的认识

简单说来,引用即别名,指针即地址。具体的部分参见找工作笔试面试那些事儿(2)---函数那些事中的“关于指针和引用”。

重点谈一下它们的区别吧:

(1)引用必须被初始化,但是不分配存储空间。指针不声明时初始化,在初始化的时候需要分配存储空间。

(2)引用初始化以后不能被改变,指针可以改变所指的对象。

(3)不存在指向空值的引用,但是存在指向空值的指针。

11.简述指针常量与常量指针区别

这是一个常见的问题。也就是const char *p和char * const p的差别,前者称为常量指针(指针指向的内容不可变),后者是指针常量(指针本身不可再被重新赋值)。下面是一个比较好记的方法,根据const的位置确定其修饰的内容:

const char* p : 因为const 修饰符在 * 号前面,因此const 修饰的是 (*p),因此p指向的字符串是const的.

char const* p : 等价于const char* p, 因为const 修饰符在 * 号前面,因此const 修饰的是 (*p),因此p指向的字符串是const的.

char* const p: const修饰的是变量p,而变量p是 char* 类型的,所以这个char* 变量本省是const,它的值初始化后就不能变了.

12.数组名和指针的区别

指针是一个变量,有自己对应的存储空间,而数组名仅仅是一个符号,不是变量,因而没有自己对应的存储空间。

1、地址相同,大小不同
示例代码:

      int arr[10];
int* p=arr;
cout<<arr<<endl;
cout<<p<<endl;
cout<<sizeof(arr)<<endl;//结果为40
cout<<sizeof(p)<<endl;//结果为4

2、都可以用指针作为形参

示例程序:

 void fun(int* p)
{
cout<<p[0]<<endl;
} int main()
{
int arr[10]={0};
int* p=arr;
fun(arr);
return 0;
}

3、指针可以自加,数组名不可以

4、作为参数的数组名的大小和指针的大小相同

13.构造函数能否为虚函数,为什么?

构造函数不能是虚函数。而且不能在构造函数中调用虚函数,因为那样实际执行的是父类的对应函数,因为自己还没有构造好。析构函数可以是虚函数,而且,在一个复杂类结构中,这往往是必须的。析构函数也可以是纯虚函数,但纯虚析构函数必须有定义体,因为析构函数的调用是在子类中隐含的。

虚函数的动态绑定特性是实现重载的关键技术,动态绑定根据实际的调用情况查询相应类的虚函数表,调用相应的虚函数。

14.谈谈你对面向对象的认识

说实话,这种开放式的题目实则挺考察对知识的深层把握程度的。

面向对象可以理解成对待每一个问题,都是首先要确定这个问题由几个部分组成,而每一个部分其实就是一个对象。然后再分别设计这些对象,最后得到整个程序。传统的程序设计多是基于功能的思想来进行考虑和设计的,而面向对象的程序设计则是基于对象的角度来考虑问题。这样做能够使得程序更加的简洁清晰。

编程中接触最多的“面向对象编程技术”仅仅是面向对象技术中的一个组成部分。发挥面向对象技术的优势是一个综合的技术问题,不仅需要面向对象的分析,设计和编程技术,而且需要借助必要的建模和开发工具。

15.delete 与 delete []有什么区别? 

这个特别在找工作笔试面试那些事儿(3)---内存管理那些事中提到了,简单说来,delete[]删除一个数组,delete 删除一个指针。

16.写个小程序确定一个数转化成二进制后是1的位的个数

很久以前就开始流传的一道微软面试题。

int func(x)
{
int countx = 0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}

17.将“引用”作为函数返回值类型的格式、好处和需要遵守的规则?

格式:类型标识符&函数名(形参列表及类型说明){ //函数体}

好处:在内存中不产生被返回值的副本;(注意:正是因为这点原因,所以返回一个局部变量的引用是不可取的。因为随着该局部变量生存期的结束,相应的引用也会失效,产生

runtime error!) 注意事项:

(1)不能返回局部变量的引用。

主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。

(2)不能返回函数内部new分配的内存的引用。

虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成内存泄露。

(3)可以返回类成员的引用,但最好是const。

(4)流操作符重载返回值申明为“引用”的作用:

流操作符<<和>>,这两个操作符常常希望被连续使用,例如:cout << "hello" << endl;

因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。

(5)在另外的一些操作符中,却千万不能返回引用:+-*/ 四则运算符。它们不能返回引用。 主要原因是这四个操作符没有side effect,因此,它们必须构造一个对象作为返回值,可选的方案包括:返回一个对象、返回一个局部变量的引用,返回一个new分配的对象的引用、返回一个静态对象引用。

18.谈谈对于关联、聚合(Aggregation)以及组合(Composition)的认识

涉及到UML中的一些概念:

关联是表示两个类的一般性联系,比如“学生”和“老师”就是一种关联关系;

聚合表示has-a的关系,是一种相对松散的关系,聚合类不需要对被聚合类负责,用空的菱形表示聚合关系:从实现的角度讲,聚合可以表示为:

class A {...}  class B { A* a; .....}

组合表示contains-a的关系,关联性强于聚合:组合类与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关系:实现的形式是:

class A{...} class B{ A a; ...}

19.当一个类C 中没有任何成员变量与成员函数,这时sizeof(C)的值是多少。如果不是零,请解释一下编译器为什么没有让它为零。

一个空类对象的大小是1byte。这是被编译器安插进去的一个字节,这样就使得这个空类的两个实例得以在内存中配置独一无二的地址。

20.用变量a给出下面的定义

a) 一个整型数(An integer)

b) 一个指向整型数的指针(A pointer to an integer)

c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an

integer)

d) 一个有10个整型数的数组(An array of 10 integers)

e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)

f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)

g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function

that takes an integer as an argument and returns an integer)

h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型

数( An array of ten pointers to functions that take an integer argument and return an integer )

非常非常经典的一道题,很多笔试面试题是从上述a-h中的一个或者几个,答案如下:

a) int a; // An integer

b) int *a; // A pointer to an integer

c) int **a; // A pointer to a pointer to an integer

d) int a[10]; // An array of 10 integers

e) int *a[10]; // An array of 10 pointers to integers

f) int (*a)[10]; // A pointer to an array of 10 integers

g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer

h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return

an integer

21.成员函数通过什么来区分不同对象的成员数据?为什么它能够区分?

通过this指针来区分的, 因为它指向的是对象的首地址。

22.拷贝构造函数在哪几种情况下会被调用?

1).当类的一个对象去初始化该类的另一个对象时;

2).如果函数的形参是类的对象,调用函数进行形参和实参结合时;

3).如果函数的返回值是类对象,函数调用完成返回时。

23. 流运算符为什么不能通过类的成员函数重载?一般怎么解决?

因为通过类的成员函数重载必须是运算符的第一个是自己,而对流运算的重载要求第一个参数是流对象。一般通过友元来解决。

24. 虚拟函数与普通成员函数的区别?内联函数和构造函数能否为虚拟函数?

区别:虚拟函数有virtual关键字,有虚拟指针和虚函数表,虚拟指针就是虚拟函数的接口,而普通成员函数没有。内联函数和构造函数不能为虚拟函数。

找工作笔试面试那些事儿(8)---常问的CC++基础题的更多相关文章

  1. 找工作笔试面试那些事儿(13)---操作系统常考知识点总结 ZZ 【操作系统】

    http://blog.csdn.net/han_xiaoyang/article/details/11285485 上一节对数据库的知识做了一个小总结,实际找工作过程中,因为公司或单位侧重点不一样, ...

  2. 找工作笔试面试那些事儿(16)---linux相关知识点(1)

    linux这部分的知识倒不是笔试面试必考的内容,不过现在很多公司开发环境都在linux系统下,一些简单的知识还是需要了解一下的,笔试面试中万一碰到了,也不会措手不及.作为菜硕的我,又因为读研期间的项目 ...

  3. 找工作笔试面试那些事儿(10)---SQL语句总结

    SQL语句中常用关键词及其解释如下: 1)SELECT 将资料从数据库中的表格内选出,两个关键字:从 (FROM) 数据库中的表格内选出 (SELECT).语法为 SELECT "栏位名&q ...

  4. 找工作Java面试 题搜集

    面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面: 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注这些行为的 ...

  5. BTA 常问的 Java基础40道常见面试题及详细答案

    原文:http://www.ymq.io/2018/03/10/java/ 八种基本数据类型的大小,以及他们的封装类 引用数据类型 Switch能否用string做参数 equals与==的区别 自动 ...

  6. BTA 常问的 Java基础40道常见面试题及详细答案(山东数漫江湖))

    八种基本数据类型的大小,以及他们的封装类 引用数据类型 Switch能否用string做参数 equals与==的区别 自动装箱,常量池 Object有哪些公用方法 Java的四种引用,强弱软虚,用到 ...

  7. 猿灯塔:疫情冲击,去体验远程面试被怼10分钟,今年Java开发找工作真难

    网行业,美团王兴曾说:“2019年可能会是过去十年里最差的一年,却是未来十年里最好的一年”.没想到预言竟然快成真了? 年前很多企业一波裁员,2020年又受疫情影响,延长了假期,各大企业复工时间拉长,招 ...

  8. 安卓开发视频教程!想找工作的你还不看这份资料就晚了!Android校招面试指南

    前言 准备面试其实已经准备了挺久了,当时打算面试准备了差不多以后,跟公司谈谈涨薪的事情,谈不拢的话,就年后直接找其他的公司.谁想到婚假还没休完,老板就在公司宣布了撤出上海的决定,愿意去深圳的就去,不愿 ...

  9. 我在北京找工作(五):备战阿里巴巴java笔试<1>:筑基

    @@@2013年9月11日 还在北京昌平区@@@ 好几天没有往博客上贴我的面试备战笔记了,今天开始分享一下备战阿里巴巴校招的笔经,当然重点是java方向的题目~. 插一段2014年阿里巴巴校招的消息: ...

随机推荐

  1. linux命令:find

    先上例子: find ./*_src -type f | xargs grep -ils "date" 在指定的那些文件夹下面,递归寻找包含“date” 字符串的普通文件. fin ...

  2. Selenium 出现: Caused by: java.lang.ClassNotFoundException: org.w3c.dom.ElementTraversal

    webDriver 运行的时候出现: Caused by: java.lang.ClassNotFoundException: org.w3c.dom.ElementTraversal 解决办法: 只 ...

  3. jQuery ajax表单提交实现局部刷新

    jQuery Ajax 异步提交 Form 表单,如果使用 get 请求,注意中文乱码问题,jquery 会先使用 iso8859-1 解码,然后发给服务器,如果使用 post 请求,则直接将中文内容 ...

  4. Android NDK 简单介绍、工具安装、环境配置

    NDK全称:Native Development Kit. 1.NDK是一系列工具的集合. * NDK提供了一系列的工具,帮助开发人员高速开发C(或C++)的动态库,并能自己主动将so和java应用一 ...

  5. 深入理解extern使用方法

    一. extern做变量声明 l  声明externkeyword的全局变量和函数可以使得它们可以跨文件被訪问. 我们一般把全部的全局变量和全局函数的实现都放在一个*.cpp文件中面,然后用一个同名的 ...

  6. 九度OJ 1065 输出梯形 (模拟)

    题目1065:输出梯形 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3745 解决:2043 题目描写叙述: 输入一个高度h.输出一个高为h.上底边为h的梯形. 输入: 一个整数h(1& ...

  7. SRM 627 D1L2GraphInversionsDFS查找指定长度的所有路径 Binary indexed tree (BIT)

    题目:http://community.topcoder.com/stat?c=problem_statement&pm=13275&rd=16008 由于图中边数不多,选择DFS遍历 ...

  8. EasyUI - Resizable 调整大小

    效果: html代码: <div id="rr" style="width: 100px; height: 100px; border: 2px solid #cc ...

  9. NetBeans + Xdebug 调试WordPress

    用NetBeans进行WordPress的相关开发和定制很顺手,配合Xdebug后调试起来也很方便. 详细配置过程如下(本例中Xampp安装目录为D:\xampp): 1: 下载xdebug(版本需匹 ...

  10. Swift代码实现加载WEBVIEW

    let webview = UIWebView(frame:self.view.bounds) webview.bounds=self.view.bounds //远程网页 webview.loadR ...