1.
如果一个类中声明了纯虚函数,其派生类中没有对该函数定义,那该函数在派生类中仍为纯虚函数,凡是包含纯虚函数的类都是抽象类。
通常重载函数调用的依据是函数名、参数类型、参数个数。
类的静态成员是属于类的而不是属于哪个对象的,因此可以说是所有对象所共有的。
内联函数是在编译时将目标代码插入的。
2.假设下面函数foo会被多线程调用,那么让i、j、k三个变量哪些因为线程间共享访问需要加锁保护(i、j)
int i=0;
void foo() {
static int j=0;
int k=0;
i++;j++;k++;
}
分析:多线程调用时要进行保护时,主要是针对全局变量和静态变量的,函数内的局部变量不会受到影响。
这里i是全局变量,j是局部静态变量,所以要进行保护。
每个线程都有一个栈,保存自己的局部变量;多线程需要程序员考虑全局变量和静态变量的保护。
可重入函数要求不能使用无保护的全局变量,所以i需要加锁,k为局部变量不用,j前加了static,static其中一个作用就是:延长变量的生存期,使其具有全局变量的作用,所以j也需要加锁。
3.
1) malloc 函数: void *malloc(unsigned int size)
在内存的动态分配区域中分配一个长度为size的连续空间,如果分配成功,则返回所分配内存空间的首地址,否则返回NULL,申请的内存不会进行初始化。
2)calloc 函数: void *calloc(unsigned int num, unsigned int size)
按照所给的数据个数和数据类型所占字节数,分配一个num * size 连续的空间。
calloc申请内存空间后,会自动初始化内存空间为 0,但是malloc不会进行初始化,其内存空间存储的是一些随机数据。
3)realloc 函数: void *realloc(void *ptr, unsigned int size)
动态分配一个长度为size的内存空间,并把内存空间的首地址赋值给ptr,把ptr内存空间调整为size。
申请的内存空间不会进行初始化。
4)new是动态分配内存的运算符,自动计算需要分配的空间,在分配类类型的内存空间时,同时调用类的构造函数,对内存空间进行初始化,即完成类的初始化工作。动态分配内置类型是否自动初始化取决于变量定义的位置,在函数体外定义的变量都初始化为0,在函数体内定义的内置类型变量都不进行初始化。
4. 两个指针变量之间的运算
只有指向同一数组的两个指针变量之间才能进行运算,否则运算毫无意义。
1) 两指针变量相减:
两指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。实际上是两个指针值(地址)相减之差再除以该数组元素的长度(字节数)。例如pf1和pf2是指向同一浮点数组的两个指针变量,设pf1的值为2010H,pf2的值为2000H,而浮点数组每个元素占4个字节,所以pf1-pf2的结果为(2000H-2010H)/4=4,表示pf1和 pf2之间相差4个元素。
注意:两个指针变量不能进行加法运算。例如,pf1+pf2是什么意思呢?毫无实际意义。
2) 两指针变量进行关系运算
指向同一数组的两指针变量进行关系运算可表示它们所指数组元素之间的关系。例如:pf1==pf2 表示pf1和pf2指向同一数组元素;pf1>pf2 表示pf1处于高地址位置;pf1<pf2 表示pf2处于低地址位置。
指针变量还可以与0比较。设p为指针变量,则p==0表明p是空指针,它不指向任何变量;p!=0表示p不是空指针。
空指针是由对指针变量赋予0值而得到的。例如:#define NULL 0 int *p = NULL;
对指针变量赋0值和不赋值是不同的。指针变量未赋值时,值是随机的,是垃圾值,不能使用的,否则将造成意外错误。而指针变量赋0值后,则可以使用,只是它不指向具体的变量而已。
5.分析下列代码如何修改程序提供编译?C
template <classT>
struct sum {
static void foo(T op1, Top2) {
cout<<op1 <<op2;
}
};sum::foo(1,3);
A 编译通过 B应该去掉static关键字 C 调用应该如下sum<int> :: foo(1,3) D调用应该如下 sum::<int> foo(1,3)
分析:这道题的考点是类模板的static成员。首先说说模板实例化,即类模板需要指定确定的类型,例如本题中sum<int> a或者sum<string> a等。static成员函数可以由类名或者对象直接调用。在本题中,以下两种形式均可:
sum<int> a;
a.foo(1,3);
或者
sum<int>::foo(1,3);
分析二:
template<classT>struct sum{
static void foo(T op1 , T op2){
cout << op1 <<op2;
}
};
sum<int>::foo(1,3);
6.分析下列程序,运行结果是at
#include<stdio.h>
main() {
char*a[]={"work","at","alibaba"};
char **pa=a;
pa++;
printf("%s",*pa);
}
分析:a -> work
a+1 -> at
a+2 -> alibaba
char* *pa=a; pa是一个指向a的指针
pa++ 指向a的下一个即a+1
补充:
#include<iostream>
using namespacestd;
int main() {
char*a[]={"work","at","alibaba"};
char **pa=a;
cout<<a<<""<<*a<<" "<<pa<<""<<*pa<<endl;
pa++;
cout<<*pa<<endl;
}
7. 如果只是论一个汉字占用的字节数,那么UTF-8 占用3个字节, UTF-16 占用2个字节。但是如果存储文本的话,需要在文本使用EF BB BF 三个字节表示使用UTF-8 编码,使用FE FF 表示使用 UTF-16 编码。
UTF-16 固定表示两个字节表示一个字符,不管是字母还是汉字;UTF-8使用1-3个字节表示一个字符
0xxxxxxx 一个字节兼容ASCII,能表示127个字符 110xxxxx 10xxxxxx.如果是这样的格式,则把两个字节当一个字符 1110xxxx 10xxxxxx 10xxxxxx 如果是这种格式则是三个字节当一个字符
所以,UTF-8的空间是根据保存的内容不同而不同。如果保存的汉字多,使用 UTF-16 占用字符数双倍的空间,使用 UTF-8 占用字符数三倍的空间;如果保存的英文字母多,使用 UTF-16 使用字符数双倍的空间,使用 UTF-8 使用字符数相同的空间。
8.C++面向对象编程语言中,以下不正确的是:
A 接口中可以用虚方法
B 一个类可以实现多个接口
C 接口不能被实例化
D 接口中可以包含已经实现的方法
分析: 这道题正确答案AD,首先所谓的接口是指只包含纯虚函数的抽象类,和普通的抽象类含不一样。所以A不对,必须是纯虚函数。然后B是正确的没有问题。然后是C,刚才说接口是特殊的抽象类,抽象类的唯一左右就是创建派生类,不能定义抽象类的对象,所以C是正确的。对于D,接口即只包含纯虚函数的抽象类,所以D是不对的.
本道题A,纯虚函数是虚函数的一种,所以A应该也是正确的。
C++中没有接口的概念,用抽象类表示接口,抽象类可以包含实现的虚方法。
分析二:这题有点问题。c++没有接口的概念,用抽象类来表示接口,抽象类可以包含实现的虚方法。
接口:接口是一个概念。它在C++中用抽象类来实现。
抽象类和接口的区别:
抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的。
虚方法当然可以是实现。
所以这题不是很严谨
编程角度,接口只是包含纯虚函数的抽象类,并不是说只能包含纯虚函数。AD是没问题的。
但是如果约定好只包含纯虚函数,那D就错了,A还有待商榷