自定义类型详解(1)

文章介绍了C语言中自定义类型如结构体、联合体和枚举的声明和使用。强调了结构体的声明方式,包括匿名结构体和自引用结构体,并展示了结构体变量的定义、初始化以及内存对齐的规则。文章还讨论了如何通过调整#pragmapack来影响内存对齐,以及结构体作为函数参数时的传递效率问题,建议大结构体应传递地址而非直接传递。
摘要由CSDN通过智能技术生成

允许自己创造的一些类型

自定义类型:结构体,联合体,枚举

结构体的声明

结构是一些值得集合,这些值称为成员变量,结构的每个成员可以是不同的类型变量

//定义变量类型
#include<stdio.h>
struct Stu
{
	//成员变量
	char name[20];
	int age;
	float weight;
}s4,s5,s6;//全局变量
int main()
{
	struct Stu s1;//局部变量
	struct Stu s2;
	struct Stu s3;
}

特殊的声明

声明结构的时候,可以不完全声明

匿名结构体类型

struct 
{
    int a; 
    char b;
    float c;
}x;
struct
{
    int a;
    char b;
    float c;
}a[20],*p;

上面的结构在声明时,省略了结签(tag)

但是,编译器会将其认为是非法的。因为会将其当成两个不同的类型

结构的自引用

数据结构,描述的是,数据在内存中的存储结构结构

【包括线性数据结构和树形的数据结构】

自引用的创建的正确方式:

​
typedef struct 
{
int data;
char c;
}s;


typedef struct Node
{
int data;
Node* next;
}Node;
​

结构体变量的定义和初始化

struct Stu
{
int x; 
int y;
}p1;
struct Stu p2;
//声明变量的同时定义变量p1
//定义结构体的变量p2

//初始化:定义变量的同时赋初值
struct Stu p3={x,y}
struct Stu //类型声明

#include<stdio.h>
struct S
{
int a;
char c;
}s1;

struct S s3
{
float f;
struct S s;
};

int main()
{
struct S s2={100,'q'};
struct S s3={.c='r',.a=2000};
struct B sb={3.14,{200,'w'}};
print("%f %d %c\n",sb.f,sb.s.c,sb.s.c);
}

struct B sb={3.14,{200,'w'}};//结构体的嵌套的初始化

结构体内存对齐
结构体的对齐规则:1.在结构体中每个地址都跟0地址有一个偏移量, 第一个成员在与结构体变量偏移量为0的地址处 2.从第二个成员开始,以后每个成员都要对齐到某个对齐数的整数倍处,这个对其数是:成员自身大小和默认对齐数的较小值(vs环境下默认对齐数是8,gcc环境下没有默认对齐数,没有默认对齐数时,对其数的大小就是成员自身的大小)3.当成员全部存放进去后,结构体总大小必须是,所有成员的对齐数中最大对齐数的整数倍。如果不够,则浪费空间对齐 4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

简单来说:结构体的内存对齐是拿空间换时间的做法,可以节省时间。

那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到: 让占用空间小的成员尽量集中在一起。

//例如:
struct S1
{
 char c1;
 int i;
 char c2;
};
struct S2
{
 char c1;
 char c2;
 int i;
};//S1和S2类型的成员一模一样,但是S1和S2所占空间的大小有了一些区别

默认修改对其数
 #pragma 这个预处理指令,这里再次使用,可以改变默认对齐数。

​

#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
 char c1;
 int i;
 char c2;
};


#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{
 char c1;
 int i;
 char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{
    //输出的结果是什么?
    printf("%d\n", sizeof(struct S1));
    printf("%d\n", sizeof(struct S2));

​


结构体传参

struct S
{
 int data[1000];
 int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{
 printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
 printf("%d\n", ps->num);
}
int main()
{
 print1(s);  //传结构体
 print2(&s); //传地址
 return 0;
}

结构体传参的时候呢,是有系统压栈开销的。如果这个结构体比较大,压栈时所需要的空间,开销就比较大。如果我们传结构体地址,一个地址无非就4个或8个字节,占的空间是比较小的。在相同的效果下,穿地址比传结构体更好一些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值