列表

详情


NC231658. Antinomy学内存对齐

描述

众所周知,在C语言中,不同的结构体的元素定义顺序,会影响一个该结构体类型变量在内存中占用的空间。

Antinomy表示要学习结构体的内存对齐,那就要紧跟时代步伐,至少也从位机学起,而不像某些野鸡考研书一样,从小霸王游戏机之类的位机中学起。

结构体概念:

结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。  在C语言中,结构体指的是一种数据结构,是C语言中聚合数据类型的一类。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员,且这些成员可以为不同的类型,成员一般用名字访问。

声明一个结构体类型的一般形式为:

struct 结构体名 {   成员列表 };

Antinomy学习使用的是Microsoft c + + 32 位和64位编译器,Antinomy本次学习的结构体的涉及的数据类型,及其单个变量所占的字节个数:


内存对齐的部分规则:

  1. 每个数据成员存储的起始位置是对齐数()的整数倍的地址处
  2. 结构体总大小(也就是sizeof的结果),必须是该结构体成员中最大的对齐模数的整数倍。若不满足,会根据需要自动填充空缺的字节。

举例1(一个该类型变量占用内存12字节):

struct STUDENT {     char name;     int age;     char addr; };

举例2(一个该类型变量占用内存8字节):

struct STUDENT {     char name;     char addr;     int age; };

Antinomy在学习过程中,需要一些例子,来证明“不同的结构体的元素定义顺序,会影响一个该结构体类型变量在内存中占用的空间”这个结论,于是他需要你来根据输入的未经过优化排序的结构体定义代码,优化后,输出一个优化过内存占用的结构体定义代码

输入描述

输入最多行字符串,这n行字符串完整定义一个结构体

第一行输入两个字符串和一个字符(三者之间由一个空格隔开,前后无多余空格),第一个字符串包含6个字符恒为struct,第二个字符串为结构体名称变量,最后一个字符恒为

其中定义成员的每一行,输入两个字符串变量和一个字符题目数据类型表格--成员类型,成员名称,该行最后恒定输入一个标志该行成员定义结束的字符(Type,TypeName之间由一个空格隔开,该行前后以及分号之前无多余空格)

最后一行输入一个标结构体定义结束、仅包含两个符号的字符串恒为(前后无多余空格)

输出描述

输入最多行字符串,定义一个优化内存过排布的结构体(多组答案输出其中一个即可)

输出格式同输入格式

示例1

输入:

struct STUDENT {
char name;
int age;
char addr;
};

输出:

struct STUDENT {
char name;
char addr;
int age;
};

示例2

输入:

struct STUDENT {
int age;
char addr;
short no;
bool ag;
long pre;
float digit;
double d1;
long long l1;
long double ld1;
char name;
};

输出:

struct STUDENT {
char name;
char addr;
bool ag;
short no;
int age;
long pre;
float digit;
double d1;
long long l1;
long double ld1;
};

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 261ms, 内存消耗: 8052K, 提交时间: 2023-02-08 19:28:54

#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

vector<string> v1, v2, v4;

int main()
{
    string a;
    getline(cin, a);
    cout << a << endl;
    
    while (getline(cin, a))
    {
        if (a[0] == 'c' || a[0] == 'b') v1.push_back(a);
        else if (a[0] == 's') v2.push_back(a);
        else v4.push_back(a);
    }
    for (auto s : v1) cout << s << endl;
    for (auto s : v2) cout << s << endl;
    for (auto s : v4) cout << s << endl;
    puts("};");
}

C++ 解法, 执行用时: 348ms, 内存消耗: 9112K, 提交时间: 2021-12-22 21:01:20

#include<bits/stdc++.h>
using namespace std;
struct node
{
	string s;
	int a;
}b[100005];
int cnt;
string s,str,st;
bool cmp(node x,node y)
{
	return x.a<y.a;
}
int main()
{
	cnt=1;
	getline(cin,st);
	while(getline(cin,b[cnt].s))
	{
		str=b[cnt].s;
		if(str=="};") break;
		if(str[0]=='c')
		b[cnt].a=1;
		else if(str[0]=='b')
		b[cnt].a=2;
		else if(str[0]=='s')
		b[cnt].a=3;
		else
		b[cnt].a=4;
		cnt++;
	}
	sort(b+1,b+cnt,cmp);
	cout<<st;
	for(int i=0;i<cnt;i++)
	cout<<b[i].s<<endl;
	cout<<"};";
	return 0;
}

C 解法, 执行用时: 15ms, 内存消耗: 5396K, 提交时间: 2022-11-24 10:45:05

#include <stdio.h>
#include<string.h>
int main()
{
    int i, j, n, t, z;
    char a[100010][34];
    for (i = 0;; i++)
    {
        gets(a[i]);
        if (a[i][0]=='}')break;
    }
    n=i;
    puts(a[0]);
    for (i = 1; i <= n; i++)
        if (a[i][0] == 'c' || a[i][0] == 'b')
            puts(a[i]);
    for (i = 1; i <= n; i++)
        if (a[i][0] == 's')
            puts(a[i]);
    for (i = 1; i <= n; i++)
        if (a[i][0] != 'c' && a[i][0] != 'b'&&a[i][0]!='s')
            puts(a[i]);
}

Python3 解法, 执行用时: 910ms, 内存消耗: 15316K, 提交时间: 2023-01-03 10:37:58

# 4bytes

print(input())

def sizes(x:str):
    if x.startswith('char') or x.startswith('bool'):
        return 1
    elif x.startswith('short'):
        return 2
    else:
        return 4

types = input()

lis = []

while types != '};':
    lis.append(types)
    types = input()
    
lis.sort(key=lambda x:sizes(x))

[print(i) for i in lis]

print('};')

上一题