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、