char c = ‘\72‘;
中的\72代表一个字符,72是八进制数,代表ASCII码字符“:”。10*a++
中a先进行乘法运算再自增(笔试中经常喜欢出这类运算符优先级容易混淆的输出问题)。- const和static的作用
太常见的问题了,下面给出一个较详细的参考答案:
static关键字:
1)函数体内static变量的作用范围为函数体。不同于auto变量。该变量的内存只被分配一次。因此其值在下次调用时仍维持上次的值。
2)在模块内的static全局变量可以被模块内的所有函数访问。但不能被模块外的其他函数访问。
3)在模块内的static函数只可被这一模块内的其它函数调用。这个函数的使用范围被限制在声明它的模块内。
4)在类中的static成员变量属于整个类所有,对类的所有对象只有一份复制。
5)在类中的static成员函数属于整个类所有,这个函数不接受this指针,因而只能访问类的static成员变量。
const关键字:
1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化。因为以后就没有机会再改变它了。
2)对指针来说,可以指定指针的本身为const,也可以指定指针所指向的数为const。或二者同时为const。
3)在一个函数的声明中,const可以修饰形参,表明它是一个输入参数。在函数内不能改变其值。
4)对于类的成员函数,若指定其为const类型。则表明其是一个常量函数。不能修改类的成员变量。
5)对于类的成员函数,有时候必须指定其返回值为const类型。以使得其返回值不为“左值”。
- 注意sizeof不是函数而是运算符,所以在计算变量所占用空间大小时,括号是可以省略的,但在计算类型大小时括号则不能省略,比如int i = 0; 则sizeof int是错误的。
- 有1,2,…,n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数。
#include <stdio.h> int main() { int a[] = {10, 6, 9, 5, 2, 8, 4, 7, 1, 3}; int i, tmp; int len = sizeof(a) / sizeof(a[0]); for(i = 0; i < len;) { tmp = a[a[i] - 1]; a[a[i] - 1] = a[i]; a[i] = tmp; if(a[i] == i + 1) i++; } for(i = 0; i < len; ++i) printf("%d ", a[i]); printf("\n"); return 0; }
- 易误解:如果
int a[5]
, 那么a与&a是等价的,因为两者地址相同。
解答:一定要注意a与&a是不一样的,虽然两者地址相同,但意义不一样,&a是整个数组对象的首地址,而a是数组首地址,也就是a[0]的地址,a的类型是int[5],a[0]的类型是int,因此&a+1相当于a的地址值加上sizeof(int) * 5,也就是a[5],下一个对象的地址,已经越界了,而a+1相当于a的地址加上sizeof(int),即a[1]的地址。 - 如何将一个小数分解成整数部分和小数部分?
要记得利用头文件中的库函数modf,下面是函数原型(记住一些实用的库函数,避免自己重写):double modf(double num, double *i); // 将num分解为整数部分*i和小数部分(返回值决定)
- 可作为函数重载判断依据的有:参数个数、参数类型、const修饰符;
不可以作为重载判断依据的有:返回类型。 - 程序输出题:
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int *p = &(a + 1)[3]; printf("%d\n", *p);
输出:5
说明:因为a+1指向a的第二个元素,[3]表示再向后移动3个元素。 - 程序输出题:
char str1[] = "abc"; char str2[] = "abc"; const char str3[] = "abc"; const char str4[] = "abc"; const char *str5 = "abc"; const char *str6 = "abc"; char *str7 = "abc"; char *str8 = "abc"; cout << (str1 == str2) << endl; cout << (str3 == str4) << endl; cout << (str5 == str6) << endl; cout << (str7 == str8) << endl;
输出:0 0 1 1
说明:输出str1~str8的地址为:0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x23aa48
0x23aa40
0x23aa38
0x23aa30输出str1~str8内容“abc”的存储地址为:
0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x100403030
0x100403030
0x100403030
0x100403030可以发现str1~str4中的内容是存在栈上,地址各不相同,而str5~str8的内容都是存储在常量区,所以地址都相同。
注意:
char *str = "abc"; printf("%p\n", str1); cout << &str1 << endl;
上面打印的是字符串 “abc”的地址,下面打印的是 str1 变量的地址。
- C的结构体和C++结构体的区别
(1)C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数。所以C的结构体是没有构造函数、析构函数、和this指针的。
(2)C的结构体对内部成员变量的访问权限只能是public,而C++允许public,protected,private三种。
(3)C语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。以上都是表面的区别,实际区别就是面向过程和面向对象编程思路的区别:
C的结构体只是把数据变量给包裹起来了,并不涉及算法。
而C++是把数据变量及对这些数据变量的相关算法给封装起来,并且给对这些数据和类不同的访问权限。
C语言中是没有类的概念的,但是C语言可以通过结构体内创建函数指针实现面向对象思想。 - 如何在类中定义常量成员并为其初始化?
解答:只能在初始化列表里对const成员初始化,像下面这样:class CBook { public: const double m_price; CBook() :m_price(8.8) { } };
下面的做法是错误的:
class CBook { public: const double m_price; CBook() { m_price = 8.8; } };
而下面的做法虽未报错,但有个warning,也不推荐:
class CBook { public: const double m_price = 8.8; // 注意这里若没有const则编译出错 CBook() { } };
- 在定义类的成员函数时使用mutable关键字的作用是什么?
解答:当需要在const方法中修改对象的数据成员时,可以在数据成员前使用mutable关键字,防止出现编译出错。例子如下:class CBook { public: mutable double m_price; // 如果不加就会出错 CBook(double price) :m_price(price) { } double getPrice() const; // 定义const方法 }; double CBook::getPrice() const { m_price = 9.8; return m_price; }
- 构造函数、拷贝构造函数、析构函数的调用点和顺序问题,如下面这个例子输出是什么?
class CBook { public: CBook() { cout << "constructor is called.\n"; } ~CBook() { cout << "destructor is called.\n"; } }; void invoke(CBook book) { // 对象作为函数参数,如果这里加了个&就不是了,因为加了&后是引用方式传递,形参和实参指向同一块地 // 址,就不需要创建临时对象,也就不需要调用拷贝构造函数了 cout << "invoke is called.\n"; } int main() { CBook c; invoke(c); }
解答:注意拷贝构造函数在对象作为函数参数传递时被调用,注意是对象实例而不是对象引用。因此该题输出如下:
constructor is called. invoke is called. destructor is called. // 在invoke函数调用结束时还要释放拷贝构造函数创建的临时对象,因此这里还调用了个析构函数 destructor is called.
引申:拷贝构造函数在哪些情况下被调用?
(1)函数的参数为类对象且参数采用值传递方式;
(2)将类对象做为函数的返回值。 - C++中的explicit关键字有何作用?
解答:禁止将构造函数作为转换函数,即禁止构造函数自动进行隐式类型转换。
例如CBook中只有一个参数m_price,在构建对象时可以使用CBook c = 9.8这样的隐式转换,使用explicit防止这种转换发生。 - 在C++中,如果确定了某一个构造函数的创建过程,在该构造函数中如果调用了其它重载的构造函数,它将不会执行其它构造函数的初始化列表部分代码,而是执行函数体代码,此时已经退化成普通函数了。例子说明如下:
class CBook { public: double m_price; CBook() { CBook(8.8); } CBook(double price) : m_price(price) { } }; int main() { CBook c; cout << c.m_price << endl; // 此时并不会输出理想中的8.8 }
- 静态数据成员只能在全局区域进行初始化,而不能在类体中进行(构造函数中初始化也不行),且静态数据成员不涉及对象,因此不受类访问限定符的限制。
例子说明如下:class CBook { public: static double m_price; }; double CBook::m_price = 8.8; // 只能在这初始化,不能在CBook的构造函数或直接初始化
- C++中可以重载的运算符:new/delete、new[]/delete[]、++等。
不可以重载的运算符:、.、::、?:、sizeof、typeid、.、**、不能改变运算符的优先级。引申:重载++和–时是怎么区分前缀++和后缀++的?
例如当编译器看到++a(先自增)时,它就调用operator++(a);
但当编译器看到a++时,它就调用operator++(a, int)。即编译器通过调用不同的函数区别这两种形式。 - C++的多态性分为静态多态和动态多态。
静态多态性:编译期间确定具体执行哪一项操作,主要是通过函数重载和运算符重载来实现的;
动态多态性:运行时确定具体执行哪一项操作,主要是通过虚函数来实现的。 - 虚函数原理考点,例如下面程序的输出是什么?
class A { public: virtual void funa(); virtual void funb(); void func(); static void fund(); static int si; private: int i; char c; };
问:sizeof(A) = ?
解答:
关于类占用的内存空间,有以下几点需要注意:
(1)如果类中含有虚函数,则编译器需要为类构建虚函数表,类中需要存储一个指针指向这个虚函数表的首地址,注意不管有几个虚函数,都只建立一张表,所有的虚函数地址都存在这张表里,类中只需要一个指针指向虚函数表首地址即可。
(2)类中的静态成员是被类所有实例所共享的,它不计入sizeof计算的空间
(3)类中的普通函数或静态普通函数都存储在栈中,不计入sizeof计算的空间
(4)类成员采用字节对齐的方式分配空间答案:12(32位系统)或16(64位系统)
- 虚继承的作用是什么?
在多继承中,子类可能同时拥有多个父类,如果这些父类还有相同的父类(祖先类),那么在子类中就会有多份祖先类。例如,类B和类C都继承与类A,如果类D派生于B和C,那么类D中就会有两份A。为了防止在多继承中子类存在重复的父类情况,可以在父类继承时使用虚函数,即在类B和类C继承类A时使用virtual关键字,例如:
class B : virtual public A
class C : virtual public A
注:因为多继承会带来很多复杂问题,因此要慎用。
C/C++求职宝典21个重点笔记(常考笔试面试点)
时间: 2024-10-05 23:12:34
C/C++求职宝典21个重点笔记(常考笔试面试点)的相关文章
深入理解计算机系统9个重点笔记
引言 深入理解计算机系统,对我来说是部大块头.说实话,我没有从头到尾完完整整的全部看完,而是选择性的看了一些我自认为重要的或感兴趣的章节,也从中获益良多,看清楚了计算机系统的一些本质东西或原理性的内容,这对每个想要深入学习编程的程序员来说都是至关重要的.只有很好的理解了系统到底是如何运行我们代码的,我们才能针对系统的特点写出高质量.高效率的代码来.这本书我以后还需要多研究几遍,今天就先总结下书中我已学到的几点知识. 重点笔记 编写高效的程序需要下面几类活动: 选择一组合适的算法和数据结构.这是很
C++编程思想重点笔记(下)
上篇请看:C++编程思想重点笔记(上) 宏的好处与坏处 宏的好处:#与##的使用 三个有用的特征:字符串定义.字符串串联和标志粘贴. 字符串定义的完成是用#指示,它容许设一个标识符并把它转化为字符串,然而字符串串联发生在当两个相邻的字符串没有分隔符时,在这种情况下字符串组合在一起.在写调试代码时,这两个特征是非常有效的. #define DEBUG(X) cout<<#X " = " << X << endl 上面的这个定义可以打印任何变量的值. 我
2016年7月21日学习笔记
2016年7月21日学习笔记 Linux安装以后出现的文件目录的作用: 文件系统的类型 LINUX有四种基本文件系统类型:普通文件.目录文件.连接文件和特殊文件,可用file命令来识别. 普通文件:如文本文件.C语言元代码.SHELL脚本.二进制的可执行文件等,可用cat.less.more.vi.emacs来察看内容,用mv来改名. 目录文件:包括文件名.子目录名及其指针.它是LINUX储存文件名的唯一地方,可用ls列出目录文件. 连接文件:是指向同一索引节点的那些目录条目.用ls来查看是,连
JavaScript 重点笔记
JavaScript 重点笔记 ## 数组 // 必须掌握 - arr.length:获取数组元素的长度 - arr.splice(起始位置,长度):从数组中添加或删除元素. - arr.indexOf():获取指定元素在数组中的位置,不存在返回-1 - arr.sort([函数:排序规则]):排序(默认采用字符串顺序排序,数字排序则需要通过自定义函数实现) - arr.join(str):将arr以指定字符连接成字符串 // 次重点 - arr.push():在数组末尾推入指定元素 - arr
C#笔试面试宝典值得收藏1
技术类面试.笔试题汇总 注:标明*的问题属于选择性掌握的内容,能掌握更好,没掌握也没关系. 下面的参考解答只是帮助大家理解,不用背,面试题.笔试题千变万化,不要梦想着把题覆盖了,下面的题是供大家查漏补缺用的,真正的把这些题搞懂了,才能“以不变应万变”.回答问题的时候能联系做过项目的例子是最好的,有的问题后面我已经补充联系到项目中的对应的案例了. 1.简述 private. protected. public. internal 修饰符的访问权限. private : 私有成员, 在类的内部才可以
听力笔记(短对话常考题型)
一起来看看短对话常考的题型,和解题技巧吧~!!! 地点判断题 第一步,预读选项中的各类地点,theatre(影院):booking office(售票处):railway station(火车站):restaurant(饭店): 第二步,这类题目可以毫无悬念的预判问题为—— Where did the conversation most probably take place? 第三步,抓听的时候注意抓听这个地点发生的动作,和与这一地点相关的一些信息词.例如,假如是theatre,就有可能会出现
2014年软考程序员-常考知识点复习笔记【第四章】
51CTO学院,在软考备考季特别整理了"2014年软考程序员-常考知识点复习笔记[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考程序员-常考知识点复习笔记[汇总篇] 4.串 串一章需要攻破的主要堡垒有: 1. 串的基本概念,串与线性表的关系(串是其元素均为字符型数据的特殊线性表),空串与空格串的区别,串相等的条件; 2. 串的基本操作,以及这些基本函数的使用,包括:取子串,串连接,串替换,求串长等等.运用串的
2014年软考程序员-常考知识点复习笔记【第五章】
51CTO学院,在软考备考季特别整理了"2014年软考程序员-常考知识点复习笔记[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考程序员-常考知识点复习笔记[汇总篇] 内部排序 考查你对书本上的各种排序算法及其思想以及其优缺点和性能指标(时间复杂度)能否了如指掌. 排序方法分类有:插入.选择.交换.归并.计数等五种排序方法. (1)插入排序中又可分为:直接插入.折半插入.2路插入(?).希尔排序.这几种插入排序
2014年软考程序员-常考知识点复习笔记【第九章】
51CTO学院,在软考备考季特别整理了"2014年软考程序员-常考知识点复习笔记[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考程序员-常考知识点复习笔记[汇总篇] B树.B-树.B+树.B*树.红黑树和trie树 (1)B树:即二叉搜索树. 1.所有非叶子结点至多拥有两个儿子(Left和Right); 2.所有结点各存储一个关键字; 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树