81-90

注:以下问题的部分解析并非全部是自己原创,只是为了便于以后复习,直接粘贴总结的答案,主要来源是七月在线中的解析部分。https://www.julyedu.com/question/selectAnalyze/kp_id/4/cate/C

1、 下列函数定义中,有语法错误的是( )

A void fun(int x, int*y){ x *= *y;}
B void fun(int x,int *y){ *x *= *y;}
C void fun(int *x,int y){ * x += y;}
D int * fun(int *x,int y){ return x +=y;}

解释:选B

选项A,函数中语句相当于x = x * (*y),其中y是一个指向整型变量的指针,*y对应一个整型变量,将该变量与x相乘的结果赋值给x。选项B,x是一个整型变量,*x是非法的。
选项C,和选项A类似,将y值加到了x所指向的整型变量。
选项D,函数返回值是一个指向整型变量的地址,x是本身是指向整型变量的指针,返回值为x向后偏移y个长度的地址。

2、 以下程序输出结果是( )

class A
{
public:
virtual void func(int val = 1)
{
std::cout << “A->” << val << std::endl;
}

virtual void test()
{
	func();
}

};

class B:public A
{
public:
void func(int val = 0)
{
std::cout << “B->” << val << std::endl;
}
};

int main(int argc,char* argv[])
{
B*p = new B;
p->test();
return 0;
}
A A->0
B B->1
C A->1
D B->0

解释:选B

上述代码最终调用的是子类的func()函数,但使用的是基类函数func()中的默认值。
这是因为默认值是在编译期间使用的,并且认为子类和基类中的func()函数是相同的,当编译器发现在函数调用时某个参数缺失了,就会用默认参数值替换,所以上述val值在编译期间被替换为1,在运行的时候调用的是子类的func()函数,基类的fun()函数被隐藏了。
注意:基类默认值覆盖子类默认值。

3、 有一个单向链表队列中有一个A、B两个相邻元素,有一个指针p指向元素A,现将一个指针r指向的S元素要插入到A和B之间,该进行操作( )

A p->next=p->next->next
B r->next=p;p->next=r->next
C r->next=p->next;p->next=r
D r=p->next;p->next=r->next
E r->next=p;p->next=r
F p=p->next->next

解释:选C

在这里插入图片描述

4、考虑以下二分查找的代码:

#include< stdio.h >
int bsearch(int array[], int n, int v)
{
int left, right, middle;
left = 0, right = n-1;
while(left <= right)
{
middle = left + (right - left)/2;
if (array[middle] > v)
right = middle;
else if (array[middle] < v)
left = middle;
else
return middle;
}
return -1;
}
对于输入array为:{2, 6, 8, 10, 13, 25, 36, 45, 53, 76, 88, 100, 127},n = 13, v = 127时,运行bsearch函数,while循环调用的次数为( )
A 1
B 2
C 3
D 4
E 5
F 无法退出

解释:选F

由于在执行if(array[middle] < v)成功后,将left赋值为middle,若此时left和right仅相差1,则middle仍然会等于left,从而导致折半查找代码无法退出。而查找127恰恰发生了这种死机的情况。事实上,上述代码如果正常运行,应该把left = middle换成left = middle + 1,形成如下的正确代码。(此外,right = middle其实也可以换成right = middle-1)。

5、 有一个类B继承子类,他们数据成员如下:

class A{

private:
const int a;
};
class B : public A{

private:
int a;
public:
const int b;
A c;
static const char* d;
A& e;
};
则这些成员变量一定要通过A或者B的构造函数初始化列表来初始化的是( )
A b c
B b c e
C b c d e
D c e

解释:选B

以下三种情况下需要使用初始化成员列表:
1、常量,const成员,不能被改变,定义的同时必须初始化
2、引用成员在定义的同时必须初始化
3、没有默认构造函数供系统自动调用:
当某个类B中含有另一个类A的对象时,需要再B类中对A类对象进行构造,若A类没有默认构造函数,那么需要再B类的构造函数初始化列表中对B类对象初始化;另外子类需要对父类成员进行初始化,当父类没有默认构造函数时,需要再子类的构造函数初始化列表中调用父类的狗仔函数实现初始化。

6、 以下函数中,和其他函数不属于一类的是( )

A strcpy
B strncpy
C snprintf
D strcat
E strtok
F strncat

解释:选C

char * strcpy(char* dest, const char * src)是把src指向的字符串复制到以dest指向的地址空间中;
char * strncpy(char* dest,char*src,size_t n)把src所指向的字符串中前n个字节复制到dest所指的数组;
int snprintf(char *str, size_t size, const char *format, …)是按照format格式化成字符串,然后将其复制到str中;
char *strcat(char *dest,char *src)是把src所指字符串添加到dest结尾处;
char *strtok(char s[], const char *delim)是将字符串s按照delim制定的分隔符分解为一组字符串;
char *strncat(char *dest,char *src,int n)把src所指字符串的前n个字符添加到dest结尾处。
其中,只有snprintf是属于stdio.h,而其他都是字符串处理函数,属于string.h,因此,标准输入输出的函数snprintf和其他不是一类。

7、 以下函数中,和其它函数不属于一类的是( )

A fread
B gets
C getchar
D pread
E getline
F scanf

解释:选D

本题的选项都是Linux和UNIX中和输入输出有关的函数。fread是从一个文件流中读数据。gets是从stdin所指的流中取1行字符。getchar从标准输入里读取下一个字符。getline从输入流中读取字符,直到遇到终结符结束。scanf从标准输入流stdio中读内容。
pread简单来说就是在指定偏移offset位置开始读取count个字节。D选项中pread是系统调用,其他选项的都是库函数。

8、 有一个类A,其数据成员如下:

class A{

private:
int a;
public:
const int b;
float* &c;
static const char* d;
static double* e;
}
则构造函数中,成员变量一定要通过初始化列表来初始化的是( )
A a b c
B b c
C b c d e
D b c d
E b
F c

解释:选B

对于初始化列表来说,类的非静态数据成员都可以在这里初始化,类的静态数据成员都不能在这里初始化,因此,排除变量d和变量e。由于常量无法修改,因此常量必须在初始化列表中初始化,const int b为此类型;引用类型也必须初始化,float* &c为此类型,因此正确答案为选项B。
静态常量数据成员可以在类内初始化(即类内声明的同时初始化),也可以在类外,即类的实现文件中初始化,不能在构造函数中初始化,也不能在构造函数的初始化列表中初始化;
静态非常量数据成员只能在类外,即类的实现文件中初始化,也不能在构造函数中初始化,不能在构造函数的初始化列表中初始化;
非静态的常量数据成员不能在类内初始化,也不能在构造函数中初始化,而只能且必须在构造函数的初始化列表中初始化;
非静态的非常量数据成员不能在类内初始化,不能再类外初始化,可以在构造函数中初始化,也可以在构造函数的初始化列表中初始化。
(转自https://blog.csdn.net/jiayi_yao/article/details/50998765 )

9、 以下函数中,和其他函数不属于一类的是( )

A read
B pread
C write
D pwrite
E fseek
F lseek

解释:选F

fseek用于将文件读写指针移动到指定位置。lseek用于在指定的文件描述符中将文件指针定位到相应的位置,并返回该位置。lseek函数适用于操作系统级的POSIX文件描述符。read和pread两个函数功能相同,都返回读到的字节数,但是调用pread相当于顺序调用了lseek和read,另外,pread不修改文件读写指针。write和pwrite函数都返回已写的字节数,调用pwrite相当于顺序调用了lseek 和write,同样的,pwrite也不修改文件的读写指针。(这道题没有很理解)

10、 在32位操作系统gcc编译器环境下,下面的程序的运行结果是( )

class A
{
public:
int b;
char c;
virtual void print()
{
cout<< “this is father’s function!”<< endl;
}
};

class B : A
{
public:
virtual void print()
{
cout << “this is children’s function!”<< endl;
}
};
int main(void)
{
cout<< sizeof(A)<< " "<< sizeof(A)<< endl;

return 0;  

}
A 12 12
B 8 8
C 9 9
D 12 16

解释:选A

类所占内存大小受三个因素影响:(1)非静态成员变量总和;(2)编译器为了CPU读写,作出的数据对齐处理;(3)为了支持虚函数产生的额外负担。类A中int占4个字节;对齐后char占4个字节;指向虚函数地址数组的指针占4个字节。因此A的大小为12字节。基类中存在虚函数时,派生类会继承基类的虚函数,派生类中不再增加虚函数的存储空间,因此B的大小也是12字节。
事实上,为了支持虚函数,编译器为带虚函数的类维护一个隐藏的指针成员,它是一个指向虚函数地址的链表(或类似结构,取决于编译器实现)。虚函数表中存储了所有虚函数的地址,由于虚函数表的首地址只用一个指针指向,因此,无论类包含了几个虚函数,使用sizeof获取类对象,在当前指针使用4字节的系统结构下,多占用空间都是4。

发布了31 篇原创文章 · 获赞 4 · 访问量 2451

猜你喜欢

转载自blog.csdn.net/weixin_44412429/article/details/95306450
今日推荐