编写高性能c/c++程序-面试指南(一)

目录

程序的版式

关于代码的空格规范

对齐

长行拆分

修饰符的位置

注释

类的版式

命名规则

共性规则

简单的 Windows 应用程序命名规则

简单的 Unix 应用程序命名规则

表达式和基本语句

运算符的优先级

复合表达式

if 语句

循环语句的效率

for 语句的循环控制变量

switch 语句

goto 语句

常量

为什么需要常量

const 与 #define 的比较

常量定义规则

类中的常量

函数设计

参数的规则

返回值的规则

函数内部实现的规则

其它建议

使用断言

引用与指针的比较

内存管理 

内存分配方式

常见的内存错误及其对策

指针与数组的对比


程序的版式

 

一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样 的代码容易阅读,并且方便于写注释。

if、for、while、do 等语句自占一行,执行语句不得紧跟其后。不论 执行语句有多少都要加{}。这样可以防止书写失误。

尽可能在定义变量的同时初始化该变量(就近原则) 引用处和其定义处相隔比较远,变量的初始化很容易被忘记。

 

关于代码的空格规范

【规则 2-3-1】关键字之后要留空格。象 const、virtual、inline、case 等关键字之后 至少要留一个空格,否则无法辨析关键字。象 if、for、while 等关键字之后应留一个 空格再跟左括号‘(’,以突出关键字。

 

【规则 2-3-2】函数名之后不要留空格,紧跟左括号‘(’,以与关键字区别

【规则 2-3-3】‘(’向后紧跟,‘)’、‘,’、‘;’向前紧跟,紧跟处不留空格。

【规则 2-3-4】‘,’之后要留空格,如 Function(x, y, z)。如果‘;’不是一行的结束 符号,其后要留空格,如 for (initialization; condition; update)

 

【规则 2-3-5】赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符, 如“=”、“+=” “>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元 操作符的前后应当加空格。

 

对齐

【规则 2-4-1】程序的分界符‘{’和‘}’应独占一行并且位于同一列,同时与引用 它们的语句左对齐

【规则 2-4-2】{ }之内的代码块在‘{’右边数格处左对齐。

 

长行拆分

【规则 2-5-1】代码行最大长度宜控制在 70 至 80 个字符以内。代码行不要过长,否 则眼睛看不过来,也不便于打印。 z 【规则 2-5-2】长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以 便突出操作符)。拆分出的新行要进行适当的缩进,使排版整齐,语句可读。

if ((very_longer_variable1 >= very_longer_variable12) 
&& (very_longer_variable3 <= very_longer_variable14) 
&& (very_longer_variable5 <= very_longer_variable16){ 
  dosomething(); 
} 
virtual CMatrix CMultiplyMatrix (CMatrix leftMatrix, 
  CMatrix rightMatrix); 
for (very_longer_initialization; 
  very_longer_condition; 
  very_longer_update) 
{ 
  dosomething(); 
} 

 

修饰符的位置

【规则 2-6-1】应当将修饰符 * 和 & 紧靠变量名

例如: char *name; int *x, y; // 此处 y 不会被误解为指针

 

注释

【规则 2-7-1】注释是对代码的“提示”,而不是文档。程序中的注释不可喧宾夺主, 注释太多了会让人眼花缭乱。注释的花样要少。

【规则 2-7-2】如果代码本来就是清楚的,则不必加注释。否则多此一举,

例如 i++; // i 加 1,多余的注释

【规则 2-7-3】边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码 的一致性。不再有用的注释要删除

【规则 2-7-4】注释应当准确、易懂,防止注释有二义性。错误的注释不但无益反而 有害

【规则 2-7-5】尽量避免在注释中使用缩写,特别是不常用缩写。

【规则 2-7-6】注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不 可放在下方。 z 【规则 2-7-8】当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注 ,便于阅读

 

类的版式

建议读者采用“以行为为中心”的书写方式,即首先考虑类应该提供什么样的函数。

  

命名规则

该命名规则的主要思想是“在变量和函数名中加入前缀以增进人们对程序的理解”。

倘若采用“匈牙利”命名规则,则应当写成

int iI, iJ, ik; // 前缀 i 表示 int 类型 
​
float fX, fY, fZ; // 前缀 f 表示 float 类型 

共性规则

【规则 3-1-1】标识符应当直观且可以拼读,可望文知意,不必进行“解码”

【规则 3-1-2】标识符的长度应当符合“min-length && max-information”原则。

【规则 3-1-3】命名规则尽量与所采用的操作系统或开发工具的风格保持

例如 Windows 应用程序的标识符通常采用“大小写”混排的方式,如 AddChi

而Unix 应用程序的标识符通常采用“小写加下划线”的方式,如 add_child。

【规则 3-1-4】程序中不要出现仅靠大小写区分的相似的标识符。 例如: int x, X; // 变量 x 与 X 容易混淆 void foo(int x); // 函数 foo 与 FOO 容易混淆 void FOO(float x);

【规则 3-1-6】变量的名字应当使用“名词”或者“形容词+名词”。 例如: float value; float oldValue; float newValue;

【规则 3-1-7】全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组)。 类的成员函数应当只使用“动词”,被省略掉的名词就是对象本身。 例如: DrawBox(); // 全局函数 box->Draw()// 类的成员函数

【规则 3-1-8】用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。 例如: int minValue; int maxValue; int SetValue(…); int GetValue(…);

【建议 3-1-1】尽量避免名字中出现数字编号,如 Value1,Value2 等,除非逻辑上的 确需要编号。这是为了防止程序员偷懒,

 

简单的 Windows 应用程序命名规则

【规则 3-2-1】类名和函数名用大写字母开头的单词组合而成。 例如: class Node; // 类名 class LeafNode; // 类名 void Draw(void); // 函数名 void SetValue(int value); // 函数名

【规则 3-2-2】变量和参数用小写字母开头的单词组合而成。

【规则 3-2-3】常量全用大写的字母,用下划线分割单词。 例如: const int MAX = 100; const int MAX_LENGTH = 100;

【规则 3-2-4】静态变量加前缀 s_(表示 static)。 例如: void Init(…) { static int s_initValue; // 静态变量 … }

【规则 3-2-6】类的数据成员加前缀 m_(表示 member),这样可以避免数据成员与 成员函数的参数同名。 例如: void Object::SetValue(int width, int height) { m_width = width; m_height = height; }

【规则 3-2-7】为了防止某一软件库中的一些标识符和其它软件库中的冲突,可以为 各种标识符加上能反映软件性质的前缀。例如三维图形标准 OpenGL 的所有库函数 均以 gl 开头,所有常量(或宏定义)均以 GL 开头。

 

简单的 Unix 应用程序命名规则

 

表达式和基本语句

运算符的优先级

 

【规则 4-1-1】如果代码行中的运算符比较多,用括号确定表达式的操作顺序,避免 使用默认的优先级

 

复合表达式

如 a = b = c = 0 这样的表达式称为复合表达式。允许复合表达式存在的理由是:(1) 书写简洁;(2)可以提高编译效率。但要防止滥用复合表达式

 

【规则 4-2-1】不要编写太复杂的复合表达式

例如: i = a >= b && c < d && c + f <= g + h ; // 复合表达式过于复杂

【规则 4-2-2】不要有多用途的复合表达式。 例如: d = (a = b + c) + r ; 该表达式既求 a 值又求 d 值。应该拆分为两个独立的语句: a = b + c; d = a + r;

【规则 4-2-3】不要把程序中的复合表达式与“真正的数学表达式”混淆

 

if 语句

布尔变量与零值比较

【规则 4-3-1】不可将布尔变量直接与 TRUE、FALSE 或者 1、0 进行比较

假设布尔变量名字为 flag,它与零值比较的标准 if 语句如下: if (flag) // 表示 flag 为真 高质量 C++/C 编程指南,v 1.0 2001 Page 28 of 101 if (!flag) // 表示 flag 为假 其它的用法都属于不良风格,例如: if (flag == TRUE) if (flag == 1 ) if (flag == FALSE) if (flag == 0)

 

整型变量与零值比较

【规则 4-3-2】应当将整型变量用“==”或“!=”直接与 0 比较

假设整型变量的名字为 value,它与零值比较的标准 if 语句如下: if (value == 0) if (value != 0) 不可模仿布尔变量的风格而写成 if (value) // 会让人误解 value 是布尔变量 if (!value)

浮点变量与零值比较

【规则 4-3-3】不可将浮点变量用“==”或“!=”与任何数字比较

千万要留意,无论是 float 还是 double 类型的变量,都有精度限制。所以一定要避 免将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。 假设浮点变量的名字为 x,应当将 if (x == 0.0) // 隐含错误的比较

转化为 if ((x>=-EPSINON) && (x<=EPSINON)) 其中 EPSINON 是允许的误差(即精度

 

指针变量与零值比较

【规则 4-3-4】应当将指针变量用“==”或“!=”与 NULL 比较。 指针变量的零值是“空”(记为 NULL)。尽管 NULL 的值与 0 相同,但是两者意义不 同。假设指针变量的名字为 p,它与零值比较的标准 if 语句如下: if (p == NULL) // p 与 NULL 显式比较,强调 p 是指针变量 if (p != NULL) 不要写成 if (p == 0) // 容易让人误解 p 是整型变量 if (p != 0) 或者 if (p) // 容易让人误解 p 是布尔变量 if (!p)

 

循环语句的效率

【建议 4-4-1】在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的 循环放在最外层,以减少 CPU 跨切循环层的次数。例如示例 4-4(b)的效率比示例 4-4(a)的高

 

【建议 4-4-2】如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到 2001 Page 30 of 101 循环体的外面。示例 4-4(c)的程序比示例 4-4(d)多执行了 N-1 次逻辑判断。并且由 于前者老要进行逻辑判断,打断了循环“流水线”作业,使得编译器不能对循环进 行优化处理,降低了效率。如果 N 非常大,最好采用示例 4-4(d)的写法,可以提高 效率。如果 N 非常小,两者效率差别并不明显,采用示例 4-4(c)的写法比较好,因 为程序更加简洁。

 

for 语句的循环控制变量

【规则 4-5-1】不可在 for 循环体内修改循环变量,防止 for 循环失去控制。 【建议 4-5-1】建议 for 语句的循环控制变量的取值采用“半开半闭区间”写法。

switch 语句

goto 语句

 

常量

为什么需要常量

【规则 5-1-1】 尽量使用含义直观的常量来表示那些将在程序中多次出现的数字或 字符串。

例如: #define MAX 100 /* C 语言的宏常量 */ const int MAX = 100; // C++ 语言的 const 常量 const float PI = 3.14159; // C++ 语言的 const 常量

const 与 #define 的比较

C++ 语言可以用 const 来定义常量,也可以用 #define 来定义常量。但是前者比后 者有更多的优点: (1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安 全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会 产生意料不到的错误(边际效应)。 (2) 有些集成化的调试工具可以对 const常量进行调试,但是不能对宏常量进行调试。

【规则 5-2-1】在 C++ 程序中只使用 const 常量而不使用宏常量,即 const 常量完 全取代宏常量。

 

常量定义规则

【规则 5-3-1】需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义 文件的头部。为便于管理,可以把不同模块的常量集中存放在一个公共的头文件中。 【规则 5-3-2】如果某一常量与其它常量密切相关,应在定义中包含这种关系,而不 高质量 C++/C 编程指南,v 1.0 2001 Page 34 of 101 应给出一些孤立的值。 例如: const float RADIUS = 100; const float DIAMETER = RADIUS * 2;

 

类中的常量

 

 

函数设计

本章重点论述函数的接口设计和内部实现的一些规则。 函数接口的两个要素是参数和返回值。C 语言中,函数的参数和返回值的传递方式 有两种:值传递(pass by value)和指针传递(pass by pointer)。C++ 语言中多了引用传 递(pass by reference)。由于引用传递的性质象指针传递,而使用方式却象值传递,初 学者常常迷惑不解,容易引起混乱

 

参数的规则

【规则 6-1-1】参数的书写要完整,不要贪图省事只写参数的类型而省略参数名字。 如果函数没有参数,则用 void 填充。 例如:

void SetValue(int width, int height); // 良好的风格 
void SetValue(int, int); // 不良的风格 
float GetValue(void); // 良好的风格 
float GetValue(); // 不良的风格 

【规则 6-1-2】参数命名要恰当,顺序要合理。

例如编写字符串拷贝函数 StringCopy,它有两个参数。如果把参数名字起为 str1 和 str2,例如 void StringCopy(char *str1, char *str2);

 

【规则 6-1-3】如果参数是指针,且仅作输入用,则应在类型前加 const,以防止该 指针在函数体内被意外修改

void StringCopy(char *strDestination,const char *strSource); 

【规则 6-1-4】如果输入参数以值传递的方式传递对象,则宜改用“const &”方式来 传递,这样可以省去临时对象的构造和析构过程,从而提高效率。

 

【建议 6-1-1】避免函数有太多的参数,参数个数尽量控制在 5 个以内。如果参数太 多,在使用时容易将参数类型或顺序搞错

【建议 6-1-2】尽量不要使用类型和数目不确定的参数。

int printf(const chat *format[, argument]…);

 

 

返回值的规则

【规则 6-2-1】不要省略返回值的

【规则 6-2-2】函数名字与返回值类型在语义上不可冲突

【规则 6-2-3】不要将正常值和错误标志混在一起返回。正常值用输出参数获得,而 错误标志用 return 语句返回

【建议 6-2-1】有时候函数原本不需要返回值,但为了增加灵活性如支持链式表达, 可以附加返回值。 例如字符串拷贝函数 strcpy 的原型: char *strcpy(char *strDest,const char *strSrc); strcpy 函数将 strSrc 拷贝至输出参数 strDest 中,同时函数的返回值又是 strDest。这 样做并非多此一举,可以获得如下灵活性: char str[20]; int length = strlen( strcpy(str, “Hello World”) );

 

【建议 6-2-2】如果函数的返回值是一个对象,有些场合用“引用传递”替换“值传 递”可以提高效率。而有些场合只能用“值传递”而不能用“引用传递”,否则会出 错。

 

函数内部实现的规则

规则 6-3-1】在函数体的“入口处”,对参数的有效性进行检查。 很多程序错误是由非法参数引起的,我们应该充分理解并正确使用“断言”(assert) 来防止此类错误。

【规则 6-3-2】在函数体的“出口处”,对 return 语句的正确性和效率进行检查

 

其它建议

【建议 6-4-1】函数的功能要单一,不要设计多用途的函数。

【建议 6-4-2】函数体的规模要小,尽量控制在 50 行代码之内。

【建议 6-4-3】尽量避免函数带有“记忆”功能。相同的输入应当产生相同的输出。 带有“记忆”功能的函数,其行为可能是不可预测的,因为它的行为可能取决于某 高质量 C++/C 编程指南,v 1.0 2001 Page 41 of 101 种“记忆状态”。这样的函数既不易理解又不利于测试和维护。在 C/C++语言中,函数的 static 局部变量是函数的“记忆”存储器。建议尽量少用 static 局部变量,除非必需。

【建议 6-4-4】不仅要检查输入参数的有效性,还要检查通过其它途径进入函数体内 的变量的有效性,例如全局变量、文件句柄等。

【建议 6-4-5】用于出错处理的返回值一定要清楚,让使用者不容易忽视或误解错误 情况

 

使用断言

如果程序在 assert 处终止 了,并不是说含有该 assert 的函数有错误,而是调用者出了差错,assert 可以帮助我们 找到发生错误的原因

【规则 6-5-1】使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况 之间的区别,后者是必然存在的并且是一定要作出处理的。

z 【规则 6-5-2】在函数的入口处,使用断言检查参数的有效性(合法性)。

z 【建议 6-5-1】在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?” 一旦确定了的假定,就要使用断言对假定进行检查。

z 【建议 6-5-2】一般教科书都鼓励程序员们进行防错设计,但要记住这种编程风格可 能会隐瞒错误。当进行防错设计时,如果“不可能发生”的事情的确发生了,则要 使用断言进行报警。

 

引用与指针的比较

 

 

内存管理 

内存分配方式

  1. 从静态存储区域分配。

  2. 在栈上创建。

  3. 从堆上分配,亦称动态内存分配。

 

 

常见的内存错误及其对策

常见的内存错误及其对策如下: 内存分配未成功,却使用了它。

编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是, 在使用内存之前检查指针是否为 NULL。如果指针 p 是函数的参数,那么在函数的入口 处用 assert(p!=NULL)进行检查。如果是用 malloc 或 new 来申请内存,应该用 if(p==NULL) 或 if(p!=NULL)进行防错处理。

 

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

犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值 全为零,导致引用初值错误(例如数组)。

内存分配成功并且已经初始化,但操作越过了内存的边界。

例如在使用数组时经常发生下标“多 1”或者“少 1”的操作。特别是在 for 循环语 句中,循环次数很容易搞错,导致数组操作越界

 

忘记了释放内存,造成内存泄露。

含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你 看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。 动态内存的申请与释放必须配对,程序中 malloc 与 free 的使用次数一定要相同,否 则肯定有错误(new/delete 同理)

 

释放了内存却继续使用它

有三种情况:

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

(2)函数的 return 语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”, 因为该内存在函数体结束时被自动销毁。 (3)使用 free 或 delete 释放了内存后,没有将指针设置为 NULL。导致产生“野指针”。

z 【规则 7-2-1】用 malloc 或 new 申请内存之后,应该立即检查指针值是否为 NULL。 防止使用指针值为 NULL 的内存。 z

【规则 7-2-2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右 值使用。

z 【规则 7-2-3】避免数组或指针的下标越界,特别要当心发生“多 1”或者“少 1” 操作。

z 【规则 7-2-4】动态内存的申请与释放必须配对,防止内存泄漏。

z 【规则 7-2-5】用 free 或 delete 释放了内存之后,立即将指针设置为 NULL,防止产 生“野指针”。

 

 

C、C++语言是IT行业的主流编程语言,也是很多程序员必备的软件基本功,是软件开发行业招聘考查的重点。本书以流行的面试题讲解为主要内容,介绍了C、C++语言基本概念,包括保留字、字符串、指针和引用、结构体、库函数等各个方面的基础知识,介绍了面向对象编程基本概念,包括如何实现继承、多态和封装等。还介绍了排序算法及数据结构的实现,包括链表、堆栈、队列和树。此外,本书开始用两章篇幅详细介绍了中英文面试的注意事项、常见问题及程序员的职业规划等软件工程师的常识。最后四章详细讲解了现在流行的智力测试题。 第一篇 求职 第1章 应聘求职 1.1 企业与人才 1.1.1 企业需要什么样的人才 1.1.2 如何成为企业需要的人才 1.2 做好面试的准备 1.2.1 面试衣着 1.2.2 简历 1.3 面试 1.3.1 面试注意事项 1.3.2 面试问题分析 问题一:“请自我介绍一下。” 问题二:“谈谈你的家庭情况。” 问题三:“你有什么业余爱好?” 问题四:“你最崇拜谁?” 问题五:“谈谈你的缺点。” 问题六:“谈一谈你的一次失败经历。” 问题七:“你为什么选择我们公司?” 问题八:“对这项工作,你可预见到哪些困难?” 问题九:“如果我们录用你,你将怎样开展工作?” 问题十:“与上级意见不一致,你将怎么办?” 问题十一:“我们为什么要录用你?” 问题十二:“你能为我们做什么?” 问题十三:“你是应届毕业生,缺乏经验,如何能胜任这项工作?” 问题十四:“你希望与什么样的上级共事?” 问题十五:“你在前一家公司的离职原因是什么?” 1.4 为明天做好计划 第2章 英文面试 2.1 英文电话面试 2.1.1 英文电话面试注意事项 2.1.2 英文电话面试常见   问题 问题一:When will you graduate? 问题二:How do you normally handle criticism? 问题三:Why should we hire you? 问题四:Please tell me something unreflected at your resume/about yourself/ your experience/your activities. 2.1.3 英文电话面试常用词汇 2.2 英文面试 2.2.1 英文简历 2.2.2 英文面试流程 2.2.3 英文面试注意事项 2.2.4 英文面试常见问题 问题一:What is your strongest trait? 问题二:How would your friends or colleagues describe you? 问题三:What personality traits do you admire? 问题四:What leadership qualities did you develop as an administrative personnel? 问题五:How do you normally handle criticism? 问题六:What do you find frustrating in a work situation? 问题七:How do you handle your failure? 问题八:What kinds of people do you like to work with? 2.2.5 英文面试常用词汇 2.3 计算机专业英语面试常用词汇 第二篇 C/C++面试题 第3章 C/C++程序基础 3.1 基本概念 面试题1:什么是C语言语句 面试题2:变量的声明和定义有什么区别 面试题3:下列字符中,哪些不是C语言关键字 面试题4:下列变量定义中,哪些是合法的 面试题5:如何以最简单的方式让电脑蜂鸣器发出声音 3.2 编程规范 面试题6:谈谈你对编程规范的理解或认识 面试题7:函数、变量等命名都有哪些规则 面试题8:写出bool、int、float、指针变量与“零值”比较的if语句 3.3 数据类型 面试题9:写出代码的输出结果 面试题10:C语言中不合法的整型常数 面试题11:short i = 0; i = i + 1L;这两句有错吗 面试题12:char x[] = {"abcd"}和 char y[] = {'a','b','c','d'} 有不同吗 面试题13:char型数据在内存中的存储形式 3.4 运算符 面试题14:请写出下列代码的输出内容 面试题15:运算符的优先级问题 面试题16:&&和&,||和|有什么区别 面试题17:什么是左值,什么是右值 面试题18:请写出程序的运行结果 面试题19:sizeof和strlen的区别 3.5 结构体 面试题20:结构体是什么样的数据类型 面试题21:结构体可以直接赋值吗 面试题22:组织WAV文件头,并解析WAV格式的各项信息 面试题23:计算学生不及格的人数打印他们的性别、姓名和成绩 面试题24:结构体内存对齐问题 3.6 C和C++的区别 面试题25:关键字static在C和C++中的区别 面试题26:C语言的结构体和C++的有什么区别 面试题27:C中的malloc和C++中的new有什么区别 面试题28:C++的引用和C语言的指针有什么区别 第4章 预处理、保留字 4.1 预处理 面试题1:简述#ifdef、#else、#endif和#ifndef的作用 面试题2:宏定义和函数 面试题3:用#define声明一个常数 面试题4:写一个“标准”宏MIN 面试题5:typedef和define有什么区别 面试题6:#define CHAR char*和typedef char* CHAR各有什么优劣 面试题7:谈谈你对typedef的认识 4.2 const(常量) 面试题8:关键字const是什么 面试题9:说明以下a声明的含义 面试题10:const、define定义常量的区别 4.3 static(静态)和extern 面试题11:static有什么作用 面试题12:extern有什么作用 面试题13:简述变量存储类型 4.4 volatile 面试题14:volatile有什么作用 面试题15:一个参数可以既是const又是volatile吗 面试题16:一个指针可以是volatile吗 第5章 引用和指针 5.1 引用 面试题1:什么是引用 面试题2:常引用有什么作用 面试题3:流操作符重载为什么返回引用 5.2 指针 面试题4:说明以下声明的含义 面试题5:简述指针常量与常量指针区别 面试题6:写出以下代码的输出结果 面试题7:找出代码的错误 5.3 指针和数组 面试题8:写出代码的输出结果 面试题9:请问这段程序有问题吗 面试题10:a和&a有什么区别 面试题11:请问代码有什么问题 面试题12:数组名和指针的区别 5.4 函数指针 面试题13:请解析(*(void (*)())0)()的含义 面试题14:指出程序的错误 5.5 “野指针” 面试题15:如何避免“野指针” 面试题16:程序是否正确 面试题17:指出程序的错误 5.6 动态内存 面试题18:简述C、C++程序编译的内存分配情况 面试题19:以下四段代码中哪段没有错误 第6章 字符串 6.1 数字字符串 面试题1:编码实现数字转化为字符串 面试题2:编码实现字符串转化为数字 6.2 字符串函数 面试题3:编写一个标准strcpy函数 面试题4:简述strcpy、sprintf与memcpy的区别 6.3 字符串与数组 面试题5:找出程序的错误之处 面试题6:判断程序会出现什么问题 第7章 嵌入式编程 面试题1:编码实现某一变量某位清或置 面试题2:用C编写一个死循环程序 面试题3:用变量a给出下面的定义 面试题4:设置地址为0x67a9的整型变量的值为0xaa66 面试题5:评论下面这个中断函数 面试题6:评价一个代码片段 第8章 面向对象 8.1 面向对象的基本概念 面试题1:谈谈你对面向对象的认识 面试题2:面向对象的三大特征 面试题3:面向过程和面向对象有什么区别 8.2 类的成员变量和成员函数 面试题4:简述类public、protected、private的作用 面试题5:写出代码的打印结果 面试题6:写出程序的打印结果 面试题7:C++的空类有哪些成员函数 8.3 构造函数和析构函数 面试题8:构造函数能否为虚函数 面试题9:简述子类与父类的析构、构造函数的调用顺序 面试题10:编写类String 的构造函数、析构函数和赋值函数 8.4 拷贝构造函数 面试题11:谈谈对拷贝构造函数和赋值运算符的认识 面试题12:写出当定义#define _INMAIN 0和不定义时代码打印结果 第9章 继承与多态 9.1 继承 面试题1:指出程序的错误 面试题2:用C++设计一个不能被继承的类 9.2 虚函数和纯虚函数 面试题3:下面说法中正确的是哪个 面试题4:写出程序的打印结果 面试题5:访问基类的私有虚函数 9.3 多态 面试题6:简述类成员函数的重写、重载和隐藏的区别 面试题7:简述多态实现的原理 第10章 数据结构 10.1 链表 面试题1:链表和数组有什么区别 面试题2:寻找单链表中间结点 面试题3:怎样把一个单链表反序 10.2 单循环链表 面试题4:根据需求建立一个单向循环链表 面试题5:检测一个较大的单向链表是否带环 10.3 双向链表 面试题6:按要求构造一个双向链表 面试题7:编程实现双链表插入新结点 面试题8:编程实现双链表删除指定结点 10.4 栈和队列 面试题9:简述队列和栈的异同 面试题10:建立一个链式栈 面试题11:建立一个链式队列 面试题12:能否用两个栈实现一个队列的功能 10.5 二叉树 面试题13:建立一个二叉树 面试题14:计算一棵二叉树的深度 面试题15:在二元树中找出和为某一值的所有路径 第11章 排序 11.1 插入排序 面试题1:编码实现直接插入排序 面试题2:编码实现希尔(Shell)排序 11.2 交换排序 面试题3:编码实现冒泡排序 面试题4:编码实现快速排序 11.3 选择排序 面试题5:编码实现直接选择排序 面试题6:编程实现堆排序 11.4 基数排序 面试题7:编程实现基数排序 第三篇 智力测试 第12章 基本方法 面试题1:斯密斯夫妇握手问题 面试题2:5个强盗分100颗宝石 面试题3:分牛 面试题4:谁在说谎 面试题5:是亏了还是赚了 面试题6:小虫分裂问题 面试题7:飞机绕地球环行问题 第13章 数学能力 面试题1:用一笔画出经过9个点的4条直线 面试题2:在9个点上画10条线 面试题3:100盏灯 面试题4:找出不同的球 面试题5:时针、分针和秒针重合问题 面试题6:可以喝多少瓶汽水 面试题7:怎样拿到第100号球 面试题8:烧绳计时 面试题9:分金条 面试题10:至少有多少人及格 面试题11:如何取3升水 面试题12:将16升水平均分给四个人 面试题13:如何将140克的盐分成50、90克各一份 面试题14:蜗牛几天能爬到井口 面试题15:100美元的差额到哪里去了 面试题16:点击鼠标比赛 面试题17:小猴最多能运回多少根香蕉 面试题18:算出小张买了几瓶啤酒、几瓶饮料 面试题19:牧场有多少匹马 面试题20:找出不同的苹果 面试题21:如何穿越沙漠 第14章 推理能力 面试题1:怎么少了100元 面试题2:村里有多少条病狗 面试题3:他们都在做什么 面试题4:躯体与灵魂 面试题5:小明一家能否安全过桥 面试题6:过河   问题 面试题7:这是张什么牌 面试题8:说谎岛上的两个部落 面试题9:谁是特尔斐城的预言家 面试题10:哪个政党获胜 面试题11:每个护士星期几休息 面试题12:每个人系的圆牌都是什么颜色的 面试题13:帽子问题 面试题14:谁是凶手 面试题15:他们的头发是什么颜色的 面试题16:谁是漂亮的青年 面试题17:哪个袋子里有金子 面试题18:他们星期几在说谎 面试题19:剩下的是什么牌 面试题20:老李的儿子们是做什么的 面试题21:史密斯家的门牌号 面试题22:尤克利地区的电话 面试题23:乡村庙会的15点游戏 面试题24:各家的孩子得了第几名 面试题25:经理应该带谁出差 面试题26:法官的判决 面试题27:张老师的生日是哪一天 面试题28:谁是M小姐的情人 面试题29:他们分别是哪国人 面试题30:他们分别是做什么的 面试题31:他们都会说什么语言 面试题32:怎么把马匹从甲村拉到乙村 面试题33:谁打碎了花瓶 面试题34:分机票 面试题35:石头有多重 面试题36:该释放谁 面试题37:谁打碎的玻璃 面试题38:谁是最优秀的医生 面试题39:今天星期几 面试题40:五个人进行汽车竞赛 面试题41:下一行是什么 面试题42:三筐水果各是什么 面试题43:最后剩下的是谁 第15章 反应能力 面试题1:下水道的井盖 面试题2:30秒答题 面试题3:一分钟答题 面试题4:镜子中的你 面试题5:埃及古币 面试题6:投硬币 面试题7:他在撒谎吗 面试题8:制造零件 面试题9:不喜欢正方形窗户的人 面试题10:孩子租房 面试题11:重男轻女的国度 面试题12:分遗产 面试题13:栽果树 面试题14:聪明的农民 面试题15:聪明的死刑犯 面试题16:幼儿园中奇怪的人 面试题17:奇怪的城镇 面试题18:聪明的商人 面试题19:渡船过河 面试题20:愚蠢的长工 面试题21:红球和白球 面试题22:小明坐在了哪里 面试题23:乌龟赛跑 面试题24:老师的爱恋 面试题25:爬楼梯 面试题26:马丁先生的约会 面试题27:巧入房间 面试题28:管子中的球 面试题29:女儿的错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值