①% ——取模运算符,求两个数相除的余数;
②重复多次 fclose 一个打开过一次的 FILE *fp 指针会有什么结果?(A)(编译和体系结构)
A)导致文件描述符结构中指针指向的内存被重复释放,进而导致一些不可预期的异常
B)不会出现异常,释放一个已经释放的指针,系统会自动忽略
C)无法编译通过
③什么函数不能声明为虚函数?
静态成员函数、构造函数
④一个32位的机器,该机器的指针是多少字节? 4
同理,如果是64位的机器,一个字节是八位,则指针需要64/8=8个字节来存储。
⑤下列程序的输出结果为
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "1";
}
A(A &a)
{
cout << "2";
}
virtual ~A()
{
cout << "3";
}
};
class B: public A
{
public:
B()
{
cout << "4";
}
B(B &b)
{
cout << "5";
}
~B()
{
cout << "6";
}
};
int main()
{
A *pa = new B();
delete pa;
return 0;
}
1 4 6 3
考察的是对继承体系中的构造和析构函数调用顺序的理解。
在调用new B()的时候,因为B继承A,所以会首先调用其父类的构造函数,输出1
然后调用自己的构造函数,输出4
在析构的时候顺序是反过来的,先调用自己的析构函数,输出6
然后调用父类的析构函数,输出3
⑥表达式 strlen("std\n007\1\\") 的值是 10 × (应该是9)
⑦有如下C++代码:
struct A{
void foo(){printf("foo");}
virtual void bar(){printf("bar");}
A(){bar();}
};
struct B:A{
void foo(){printf("b_foo");}
void bar(){printf("b_bar");}
};
A *p = new B;
p->foo();
p->bar();
输出结果:barfoob_bar
A * p = new B; // A 的指针指向 B 的对象。
当执行 new B 时,调用 B 的无参构造函数,由于 B 继承 A,所以先调用 A 的构造函数,在 A 的构造函数中调用了虚函数 bar(),这时调用的是 A 的 bar()。
如果在构造函数或析构函数中调用虚函数,则运行的是为构造函数或析构函数本人类型定义的版本,因为在构造子类的时候,首先回去调用父类的默认构造函数,此时子类还是未初始化的,所以不可能调用子类函数;
p->foo(); // 因为 foo() 不是虚函数,所以执行的是 A 的 foo();
p->bar(); // 因为 bar() 是虚函数,所以执行的是 B 的 bar()。
⑧以下叙述中正确的是(B)
A)即使不进行强制类型转换,在进行指针赋值运算时,指针变量的基类型也可以不同
B)如果企图通过一个空指针来访问一个存储单元,将会得到一个出错信息
C)设变量p是一个指针变量,则语句p=0;是非法的,应该使用p=NULL;
D)指针变量之间不能用关系运算符进行比较
⑨ 在上下文及头文件均正常的情况下,以下代码打印的结果是(假设运行在 64 位计算机上):
struct st_t {
int status;
short *pdata;
char errstr[32];
};
st_t st[16];
char *p = (char *)(st[2].errstr + 32);
printf("%d", (p - (char *)(st)));
144
这个是题目的地址分配
32位环境 4字节对齐 指针占4字节
64位环境 8字节对齐 指针占8字节
int status;虽然int只占用4个 由于后面的指针八个字节放不下 填补不了空位 所以对其要八个字节
short *pdata; 这个指针会占用8个字节
char errstr[32]; 占用32个字节
所以一共占用 8+8+32=48个字节
char *p=(char *)(st[2].esstr+32),p实际指向了st[3]
则p-(char *)(st)),即为&st[3]-&st[0],占用空间为3个结构体的大小,即3*48=144