基础考查的面试、笔试题
来源:互联网 发布:二阶低通滤波器算法 编辑:程序博客网 时间:2024/05/08 11:14
引用必须被初始化,指针则不必
存在空指针,但不存在空引用 因为引用相对安全
引用被赋值后不能修改为其它实例的引用,指针被赋值后可以指向其它指针。
2. 堆栈溢出一般是由什么原因引起的?
没做内存释放,递归调用层次过深。
————————————————————详细了解一下调用堆栈的知识。
3. 什么函数不能声明为虚函数?
必须是类的成员函数,像静态函数这些不可以。
构造函数不能声明为虚函数。
——————————————原因————————————————
话说这个问题还引起了同事之间的争议,章老师对编码理解确实相当之深。
我比较认同的原因如下:
虚函数是保存是虚函数表里的,构造函数调用时虚函数表还没有建好,那么没办法进行函数调用。
使用角度,构造函数为虚完全没有必要。虚函数是实现C++多态的一种机制,子类的指针可以赋值给父类指针,父类指针可以通过虚函数调用子类的函数处理逻辑。而构造函数是对象构造的时候调用(且只有在这时候需要调用),只有明确类型时才能调用的到,不会需要通过父类指针去调用。
————————————————————————————————
4. 关于字符串常量的问题
————————————————————详细了解一下
5. 关于一维数组,二维数组指针偏移的问题
从二维数组的角度来看,a代表二维数组的首地址,当然也可以看成二维数组第0行的首地址。
相同于一维数组的表示方法:a+0同样代表第0行的首地址, a+1代表第一行的首地址,a+2代表第2行的首地址,剩下的可以依此类推。
既然把a[0]、a[1]、a[2]看成一维数组名,可以认为它们分别代表它们所对应的数组的首地址,也就是说,a[0] 代表第0行中第0列元素的地址,即&a[0][0];a[1]是第一行中第0列元素的地址,即&a[1][0];根据地址运算规则,a[0]+1即代表第0行第一列元素的地址,即&a[0][1]。
另外,在二维数组中,还可以用指针的形式来表示各元素的地址。
在一维数组中a[0]与*(a+0)等价,a[1]与*(a+1)等价,因此我们在二维数组中可以这样来表示,即a[i]+j就与*(a+i)+j等价,它表示数组元素a[i][j]的地址。
因此,二维数组元素a[i][j]可表示成*(a[i]+j)或*(*(a+i)+j),它们都与a[i][j]等价,或者还可以写成(*(a+i))[j]。
a代表二维数组的首地址,当然也可以看成二维数组第0行的首地址
a+0同样代表第0行的首地址
*(a+0)代表第0行第0列的地址
*a代表第0行第0列的地址
&a代表二维数组的首地址
a[0]代表第0行中第0列元素的地址
&a[0]代表第0行的地址
&a[0][0]代表第0行中第0列元素的地址
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
结果为:2,5 注意&a是数组指针和数组首位指针意义不同,&a+1意为指向数组末尾。
6.
unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
请问
p1+5=______; 0x801000 + sizeof(char)
p2+5=______; 0x810000 + sizeof(long)
7. 做笔试时,需要注意:一定要严谨,指针空值判断,越界处理,const参数等等一定都要想到。
8.写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。另外,当你写下面的代码时会发生什么事?least = MIN(*p++, b);
#define MIN(A,B) ((A) <= (B) ? (A) : (B))//一定要注意加入所有括号,尤其最外围的括号。===千万不能加分号!!
9. 请说出static和const关键字尽可能多的作用
static关键字至少有下列n个作用:
(1) 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2) 在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3) 在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(4) 在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(5) 在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
const关键字至少有下列n个作用:
(1) 欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了(2) 对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3) 在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4) 对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5) 对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。
10. 编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh”
正确解答1:
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) - steps;
char tmp[MAX_LEN];
strcpy ( tmp, pStr + n );
strcpy ( tmp + steps, pStr);
*( tmp + strlen ( pStr ) ) = '\0';
strcpy( pStr, tmp );
}
正确解答2:
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) - steps;
char tmp[MAX_LEN];
memcpy( tmp, pStr + n, steps );
memcpy(pStr + steps, pStr, n );
memcpy(pStr, tmp, steps );
}
11. 关于位域
网上看了一些资料,发现这里有很多理解上的误区,参考的笔试题答案都是错的。
————————下面主要来自网上资料,原文误区的地方已修改———————————
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。
例如在存放一个开关量时,只有0和1 两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。
一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:
struct 位域结构名
{ 位域列表 };
其中位域列表的形式为: 类型说明符 位域名:位域长度
例如:
struct bs
{
int a:8;
int b:2;
int c:6;
};
二、位域有如下特性:
1. 由于位域长度不能大于其对应类型所占空间的位数,如:int 位域长度不能超过32
struct bs
{
int a:32;
int b:33;//编译错误
}
2. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。可以是空域,空域表示当前存储单元后面填0,下个位域从下一存储单元开始放置。
例如:
struct k
{
int a:1;
int :0;//空域,当前存储单元后面的31位填0——————结构体最开始放置空域是无效的
int :2;//这2位不用
int b:3;
int c:2;
};//该结构体占空间为8字节
三、位域对齐规则:
1. 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2. 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3. 如果相邻的位域字段的类型不同,则路过当前存储单元,从新类型的存储单元开始分配。
理解了吗?试着做下面几个例子。
#pragma pack(1)
struct s4{
char a:4;//char存储单元为1字节
short b:4;//跳过char的1字节,从第2个字节开始分配
short c:4;//继续向当前short的2字节存储单元分配
long d;//跳过short的两字节,从第3个字节开始分配,分配4字节
};
输出S4 sizeof:7
#pragma pack(2)
struct s4{
char a:4;
short b:4;
char c:4;
long d;
};
输出S4 sizeof:8
12. Extern C的含义
以前只知道extern "C"是指定包含的块中为C语言编写的代码,但深究其意义发现其作用如下:
extern "C"指定其包含的变量、函数为C语言的方式编译、链接。为什么要指定呢?不指定怎么样?
要做指定的最主要原因在于:C和C++编译上的区别
C++支持函数重载,C并不支持,所以C++函数被编译后在符号库中的名字与C不同。
————————————————————————————
如:void add(int a, int b);
C语言编译后,符号库中名字为_add;而C++编译后,符号库中的名字为_add_int_int(编译器不同会稍有区别)。
————————————————————————————
在C++中引用示例中的C库,如果未加extern "C"修饰的话,链接时认为头文件对应的是标准C++库。于是在符号库中找_add_int_int接口,显然在原C库中的符号为_add,因为符号找不到链接出错。
在头文件中对接口加入extern "C"修饰后,编译器就知道接口是定义在C库中,链接时查找_add符号,链接正常。
- 基础考查的面试、笔试题
- 一道考查对象模型的C++笔试题
- 面试题目——多态性的考查
- ios面试 笔试基础题
- 一道二进制的考查题
- 一些基础的Oracle DBA笔试题和面试题目
- 一些基础的Oracle DBA笔试题和面试题目
- 面试的笔试题!
- 面试的笔试题
- JAVA基础面试及笔试题
- 笔试面试基础
- 【面试笔试】程序设计基础
- 考查与或运算的题
- 关于C/C++一些面试/笔试题的反思(超基础的知识点)
- 最近做的一些比较基础的笔试面试题目
- JAVA笔试、面试基础题目
- 找工作笔试面试那些事儿(8)---常问的CC++基础题
- 找工作笔试面试那些事儿(8)---常问的CC++基础题
- ILDasm和ILAsm简单使用
- Java 8 的重要新特性以及 Java 9、10 的发展规划
- 需求1
- sed的用法
- 分享维基的:图片文件数据结构,非常详细。
- 基础考查的面试、笔试题
- thinkPHP框架
- java中相对路径与绝对路径问题
- linux下安装sublime
- DirectShow 配置环境
- 20120326——“TNS-12541: TNS:无监听器”&ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
- 退出vim 出现乱码
- C++ primer:继承与多态
- VC 为程序创建快捷方式的详细讲解