2023-10-30 C++的一些笔试题

1、在C语言中,位移操作符(>>和<<)的优先级比逻辑或操作符(|)的优先级高。因此,根据运算符优先级,宏展开后的代码将先执行位移操作,然后再执行逻辑或操作。

#include<stdio.h>
#define SHORT_TRANS(A) A = (A >> 8 | A << 8)
int main(void){
    short a=0x1f2a;
    SHORT_TRANS(a);
    printf("%x", a); // 2alf
}

2、

#include<iostream>
using namespace std;
class a{
public:
virtual void func1();
void func2();
static void func3();
static int i;
private:
int j;
char c;
};
int main(void) {
cout << sizeof(a) << endl;
}

在32位系统中,上述程序的输出结果为 12。

这是因为在32位系统中,指针的大小为4字节。对于类a,它包含以下成员:

virtual void func1():虚函数指针,占用4字节。
void func2():非静态成员函数,不占用对象的存储空间。
static void func3():静态成员函数,不占用对象的存储空间。
static int i:静态成员变量,不占用对象的存储空间。
int j:非静态成员变量,占用4字节。
char c:非静态成员变量,占用1字节。
在32位系统中,类的对象默认进行4字节对齐(以最大数据成员的大小为对齐单位)。因此,a类的对象在内存中的布局如下:
| 虚函数指针 (4字节) | int j (4字节) | char c (1字节) |
由于对齐的需要,虚函数指针和int j都占用4字节的存储空间。char c占用1字节的存储空间。

因此,类a的大小为12字节,这就是在32位系统下输出结果为12的原因。

在64位系统下,上述程序的输出结果为 16。

在64位系统中,指针的大小为8字节。对于类 a,它包含以下成员:

virtual void func1():虚函数指针,占用8字节。
void func2():非静态成员函数,不占用对象的存储空间。
static void func3():静态成员函数,不占用对象的存储空间。
static int i:静态成员变量,不占用对象的存储空间。
int j:非静态成员变量,占用4字节。
char c:非静态成员变量,占用1字节。
在64位系统中,类的对象默认进行8字节对齐(以最大数据成员的大小为对齐单位)。因此,a类的对象在内存中的布局如下:

| 虚函数指针 (8字节) | int j (4字节) | char c (1字节) | 填充 (3字节) |
由于对齐的需要,虚函数指针占用8字节的存储空间,int j占用4字节的存储空间,char c占用1字节的存储空间。为了满足8字节对齐要求,编译器在最后添加了3字节的填充。

因此,在64位系统下,类 a 的大小为16字节,这就是输出结果为16的原因。

3、

#include<iostream>
using namespace std;
#pragma pack(push, 4)
struct MyStruct
{
    int x;
    char y;
    short z;
};
#pragma pack(pop)

int main(void){
    cout << sizeof(MyStruct);
}

4、

#include<iostream>
int main(void){
    int num[5] = {1,2,3,4,5};
    std::cout << *((int*)(&num+1)-1); // 5
}

这段代码存在问题,涉及到指针算术和指针类型转换的不正确使用。

在这段代码中,你声明了一个包含5个整数的数组num,并将其初始化为 {1, 2, 3, 4, 5}。

然后,你使用指针运算和类型转换来打印数组中最后一个元素的值。具体来说,你对数组num执行了以下操作:

&num:获取数组num的地址,得到的是指向整个数组的指针。
(&num + 1):对指针进行加法运算,指向数组num之后的内存位置,即越过整个数组。
((int*)(&num + 1)):将指针转换为int类型,这是不正确的操作。这个转换会导致指针类型不匹配,违反了类型安全性。
((int)(&num + 1) - 1):对指针进行减法运算,然后通过解引用操作符
获取减法运算结果指向的内存地址的值。
尽管这段代码可能在某些特定的编译器和平台上产生预期的结果(即输出5),但它依赖于指针算术和未定义的行为,因此是不可靠的。

这段代码的问题在于对指向数组的指针进行算术运算,越过了数组的边界。在C++中,指针算术的合法操作范围仅限于指向同一数组中的元素之间的运算。指针加法或减法的结果必须在数组的有效范围内。在这个例子中,指针算术操作超出了数组的范围,从而导致未定义行为。

5、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值