在 C++ 等高级语言中, 除了 int 和 float 等基本类型外, 通常还可以自定义结 构体类型。在本题当中, 你需要模拟一种类似 C++ 的高级语言的结构体定义方式, 并 计算出相应的内存占用等信息。
在这种语言中, 基本类型共有 4 种: byte,short,int,long,分别占据 1, 2, 4, 8 字节的空间。 定义一个结构体类型时, 需要给出类型名和成员,其中每个成员需要按顺序给出类 型和名称。类型可以为基本类型, 也可以为先前定义过的结构体类型。注意, 定义结构 体类型时不会定义具体元素,即不占用内存。 定义一个元素时,需要给出元素的类型和名称。元素将按照以下规则占据内存: . 元素内的所有成员将按照定义时给出的顺序在内存中排布, 对于类型为结构体的 成员同理。 . 为了保证内存访问的效率, 元素的地址占用需要满足对齐规则,即任何类型的大 小和该类型元素在内存中的起始地址均应对齐到该类型对齐要求的整数倍。具体 而言:
struct d {
short a;
int b;
short c;
};
d e;
该代码定义了结构体类型 d 与元素 e。元素 e 包含三个成员 e.a, e.b, e.c,分 别占据第 0 ∼ 1 ,4 ∼ 7 ,8 ∼ 9 字节的地址。由于类型 d 需要对齐到 4 字节, 因此 e 占 据了第 0 ∼ 11 字节的地址,大小为 12 字节。 你需要处理 n 次操作,每次操作为以下四种之一:
第 1 行: 一个正整数 n,表示操作的数量。
接下来若干行,依次描述每个操作,每行第一个正整数 op 表示操作类型:
• 若 op = 1,首先输入一个字符串 s 与一个正整数 k,表示类型名与成员数量, 接 下来 k 行每行输入两个字符串 ti ,ni ,依次表示每个成员的类型与名称。
• 若 op = 2,输入两个字符串 t ,n,表示该元素的类型与名称。
• 若 op = 3,输入一个字符串 s,表示所访问的元素。
• 若 op = 4,输入一个非负整数 addr,表示所访问的地址。
输出 n 行,依次表示每个操作的输出结果,输出要求如题目描述中所述。
结构体类型 a 中, int 类型的成员 aa 占据第 0 ∼ 3 字节地址, short 类型的成员 ab 占据第 4 ∼ 5 字节地址。又由于其对齐要求为 4 字节, 可得其大小为 8 字节。由此 可同理计算出结构体类型 b 的大小为 16 字节,对齐要求为 8 字节。
5 1 a 2 short aa int ab 1 b 2 a ba long bb 2 b x 3 x.ba.ab 4 10
8 4 16 8 0 4 x.bb
10 1 a 4 int aa short ab long ac byte ad 1 b 4 a ba int bb short bc a bd 2 b x 2 a y 3 x.bd.ab 3 x.ba 3 y.ac 4 42 4 20 4 100
24 8 56 8 0 56 36 0 64 x.bd.ac ERR ERR
对于全部数据,满足 1 ≤ n ≤ 100 ,1 ≤ k ≤ 100 ,0 ≤ addr ≤ 10^18。
所有定义的结构体类型名、成员名称和定义的元素名称均由不超过 10 个字符的小 写字母组成,且都不是 byte,short,int,long(即不与基本类型重名)。
所有定义的结构体类型名和元素名称互不相同, 同一结构体内成员名称互不相同。 但不同的结构体可能有相同的成员名称, 某结构体内的成员名称也可能与定义的结构体 或元素名称相同。
保证所有操作均符合题目所述的规范和要求, 即结构体的定义不会包含不存在的类 型、不会访问不存在的元素或成员等。
保证任意结构体大小及定义的元素占据的最高内存地址均不超过 10^18。
特殊性质 A:没有操作 1;
特殊性质 B:只有一个操作 1;
特殊性质 C:所有操作 1 中给出的成员类型均为基本类型;
特殊性质 D:基本类型只有 long。
对于结构体类型的对齐要求和大小,形式化的定义方式如下: • 设该结构体内有 k 个成员,其大小分别为 s1 , ..., sk ,对齐要求分别为 a1 , ..., ak; • 则该结构体的对齐要求为 a = max{a1 , ..., ak }; • 再设这些成员排布时的地址偏移量分别为 o1 , ..., ok ,则:
CSP