C语言自定义类型:结构体 枚举 联合

结构体

struct stu
{char name[20];int age;
}s1,s2;   //s1,s2是全局变量int main()
{struct stu s3; //s3是局部变量return 0;
}

匿名结构体类型 只能用一次


struct 
{char name[20];int age;
}s1;  

以下两种写法相同


//1
typedef struct node
{int data;struct node* next;
}*linklist;//2
struct node
{int data;struct node* next;
};
typedef struct node* linklist;

定义及初始化

struct point
{int x;int y;
}p1 = { 2,3 };struct score
{int s;char ch;
};struct stu
{char name[20];int age;struct score s;
};int main()
{struct point p2 = { 3,4 };struct stu s1 = { "manba",24 , {100,'q'} };printf("%c", s1.s.ch); //q
}

结构体内存对齐
往年面试笔试题常考

对齐规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处。

  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

    对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。

VS中默认的值为8
gcc上没有默认对齐数,对齐数就是自身大小
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

  1. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

因此,结构体中会有内存浪费


struct s1
{char c1; //1int i;  //4char c2; //1
};struct s2
{char c1;char c2;int i;};int main(){struct s1 s1;struct s2 s2;printf("%d ", sizeof(struct s1));  //12printf("%d ", sizeof(struct s2));  //8printf("%d ", offsetof(struct s1, c1));  //0printf("%d ", offsetof(struct s1, i)); //4printf("%d ", offsetof(struct s1, c2)); //8printf("%d ", offsetof(struct s2, c1)); //0printf("%d ", offsetof(struct s2, c2)); //1printf("%d ", offsetof(struct s2, i)); //4return 0;
}

//修改默认对齐数

#pragma pack(4) //默认对齐数改成4
#pragma pack()  //恢复默认对齐数

结构体传参

struct s
{int data[1000];int num;
};
void print1(struct s ss)
{int i = 0;for (i = 0; i < 3; i++){printf("%d ", ss.data[i]);}printf("%d", ss.num);
}
void print2(const struct s* ps)
{int i = 0;for (i = 0; i < 3; i++){printf("%d ", ps->data[i]);}printf("%d ", ps->num);}
int main()
{struct	s s = { {1,2,3},100 };print1(s);  //传值调用print2(&s); //传址调用  更推荐使用 函数传参的时候,参数需要压栈,有时间和空间上的开销return 0;
}

位段不跨平台
因此可移植的程序应该避免使用

struct a
{//先开辟4byte 32bitint a : 2;  //a占两个比特位int b : 5;  //b占5个int c : 10;//再开辟 4byteint d : 30;
}; //47bit
//共开辟 8byte(字节)
int main()
{printf("%d ", sizeof(struct a)); // 8 即64bitreturn 0;
}

枚举 就是一一列举

enum day
{Mon = 1,  //枚举常量,后续不能修改  都用逗号隔开Tues,Wed,Thur,Fri,Sat,Sun
};int main()
{enum day d = Fri;printf("%d\n", Mon); //1printf("%d\n", Tues); //2printf("%d\n", Wed); //3return 0;
}

为什么用枚举而不用#define?
举例:https://gitee.com/wu-jiale26/c-language-leetcode/blob/master/C%E8%AF%AD%E8%A8%80%E9%9D%99%E6%80%81%E9%80%9A%E8%AE%AF%E5%BD%95/test.c

提高代码的可读性和可维护性。
便于调试
与#define定义的标识符比较 , 具有类型检查 ,更加严谨
防止命名污染(封装)
一次可定义多个常量

联合(共用体): 特殊的自定义类型 这些成共用一块空间


union un
{int a;char c;
};struct st
{int a;char c;
};int main()
{union un u;printf("%d\n", sizeof(u)); //4 printf("%p\n", &(u));  //012FF960printf("%p\n", &(u.a)); //012FF960printf("%p\n", &(u.c)); //012FF960u.a = 0x11223344; //内存中 44 33 22 11u.c = 0x00;  // 00 33 22 11}

两种方法判断当前计算机的大小端储存


//
int checksys()
{int a = 1; //00 00 00 01//低->高 小端 01 00 00 00//00 00 00 01 大端return *(char*)&a;
}
int checksys2()
{union  //匿名类型{char c;int i;}u;u.i = 1;return u.c;
}
int main()
{int ret = checksys();ret = checksys2();if (ret == 1){printf("小端\n");}elseprintf("大端\n");}

联合体对齐数


union un
{char arr[5]; //5  对齐数是1int i; //4  对齐数是4
};
int main()
{printf("%d", sizeof(union un)); //8}
union un
{short arr[7]; //14  对齐数是2int i; //4  对齐数是4
};
int main()
{printf("%d", sizeof(union un)); //16}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/17263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编程文档模板

项目名称 { XXX编程文档} 1. 模块A 提示&#xff1a;开发人员根据“编程计划”编写软件的代码&#xff0c;并随时记录编程技术、问题与对策、心得体会等等&#xff0c;产生《编程文档》&#xff08;类似于编程日记&#xff09;。 程序名称功能描述开发者记录编程技术、问题…

day16--集合进阶(Set、Map集合)

day16——集合进阶&#xff08;Set、Map集合&#xff09; 一、Set系列集合 1.1 认识Set集合的特点 Set集合是属于Collection体系下的另一个分支&#xff0c;它的特点如下图所示 下面我们用代码简单演示一下&#xff0c;每一种Set集合的特点。 //Set<Integer> set ne…

【构建基础:打造你的第一个深度神经网络】

文章目录 前言深度神经网络的基础你的第一个神经网络分析代码结论 前言 深度学习已经成为了当代技术进步的先锋&#xff0c;它的成功依赖于深度神经网络&#xff08;DNN&#xff09;的强大能力。对于初学者来说&#xff0c;理解并构建一个基础的深度神经网络是学习之旅的重要一…

数组-两个升序数组中位数

一、题目描述 二、解题思路 (一).基本思想&#xff1a; 如果列表总长度allsize( arr1.size()arr2.size() ) 为奇数时&#xff0c;中位数位置应该在两个列表排序后的第 allsize/2 位置处&#xff0c;如果allsize为偶数&#xff0c;中位数应该取 (allsize/2)-1 和 allsize/2 的…

利用java写的java.util.concurrent.Delayed 类 配合线程实现延迟队列处理方案

直接分享代码 package com.xxx.init.delayJob;import lombok.Data;import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit;/*** User:Json* Date: 2024/5/15* java 内置的延迟队列* 服务器重启后&#xff0c;数据全部消失&#xff0c;怕宕机* 他是无界队…

Scala的简单学习二

一集合 1.1 Java集合 1.在scala创建Java集合需要导入java.util包 2.不能使用scala中遍历迭代器的方法遍历Java集合 3.使用下标索引遍历Java集合 4.list集合中&#xff0c;add是添加元素(可以指定下表索引插入)&#xff0c;get是通过下标索引获取元素&#xff0c;size是获取…

【Python】 如何在Python中设置环境变量?

基本原理 在Python中&#xff0c;环境变量是一种存储系统或应用程序配置信息的方式&#xff0c;它们可以被操作系统或应用程序访问。环境变量通常用于配置应用程序的行为&#xff0c;例如指定数据库的连接字符串、API密钥、文件路径等。 Python提供了几种方法来设置和访问环境…

心电信号降噪方法(滤波器/移动平均/小波等,MATLAB环境)

对于一个正常的、完整的心动周期&#xff0c;对应的心电图波形如下图所示&#xff0c;各个波形都对应着心脏兴奋活动的生理过程&#xff0c;包含P波&#xff0c;PR段&#xff0c;QRS波群&#xff0c;ST段&#xff0c;T波&#xff0c;U波。 &#xff08;1&#xff09;P波心电图中…

OpenBMC相关的网站

openbmc官方网站 https://github.com/openbmchttps://github.com/openbmc Dashboard [Jenkins]https://jenkins.openbmc.org/ https://gerrit.openbmc.org/Gerrit Code Reviewhttps://gerrit.openbmc.org/ Searchhttps://grok.openbmc.org/ openbmc参考网站 https://www.c…

R实验 正交试验设计与一元线性回归分析

实验目的&#xff1a; 掌握正交试验设计记号的意义&#xff1b;掌握正交试验设计的直观分析和方差分析&#xff1b;掌握一元线性回归模型的相关概念&#xff1b;掌握最小二乘法的思想&#xff1b;掌握一元线性回归方程的显著性检验和预测。 实验内容&#xff1a; &#xff11;…

C++ day1 作业练习

整理思维导图 定义自己的命名空间my_sapce&#xff0c;在my_sapce中定义string类型的变量s1&#xff0c;再定义一个函数完成对字符串的逆置。 #include <iostream> #include <cstring>using namespace std; namespace my_space {string s1; }void show() {cout<…

NASA数据集——严格校准的臭氧(O3)、甲醛(HCHO)、二氧化碳(CO2)和甲烷(CH4)混合比,以及包括三维风在内的气象数据

Alpha Jet Atmopsheric eXperiment Meteorological Measurement System (MMS) Data 阿尔法喷气式大气实验气象测量系统&#xff08;MMS&#xff09;数据 简介 Alpha Jet Atmospheric eXperiment (AJAX) 是美国国家航空航天局艾姆斯研究中心与 H211, L.L.C. 公司的合作项目&a…

C#面:当一个线程进入一个对象的方法后,其它线程是否可以进入该对象的方法?

一个线程在访问一个对象的一个synchronized方法时&#xff1a; 另一个线程可以同时访问这个对象的非同步方法。另一个线程不可以同时访问这个对象的普通同步方法。另一个线程可以同时访问这个对象的静态同步方法 &#xff0c;即static synchronized修饰的方法 。另一个线程不可…

win10 cmake vs2019 qt opencv contrib 下载 编译 提供编译好的全套文件下载

本文意在提供 win10系统下 使用 cmake-gui 配置 opencv源码 再使用vs2019编译的全套过程 为什么是win10系统? 主要提供给使用pc端的人使用,例如工厂员工 或 上课教学 还可以是什么系统? 当然这一切也可以在arm上操作 例如一块stm32及其配套的硬件 装在无人机上 图像中就…

【Python】 去除空白字符的艺术:Python中的字符串修剪技巧

基本原理 在Python编程中&#xff0c;经常会遇到需要去除字符串两端空白字符&#xff08;也称为“修剪”&#xff09;的情况。空白字符包括空格、制表符、换行符等。Python提供了多种方法来处理字符串中的空白字符&#xff0c;其中最常见的是使用字符串的strip()方法。 strip…

SpringSecurity6从入门到实战之引言和基本概念

SpringSecurity6从入门到实战之引言和基本概念 前言 在当今数字化时代&#xff0c;随着网络应用的日益普及&#xff0c;保护用户数据和系统安全变得至关重要。作为Java开发社区的中坚力量&#xff0c;Spring框架提供了一整套解决方案来构建企业级应用程序。然而&#xff0c;随…

APM2.8飞控

ArduPilotMega 主控可应用于 固定翼、直升机、多旋翼、地面车辆 APM2.8飞控供电有两种 1.电流计供电&#xff0c; 2.带BEC&#xff08;稳压功能&#xff09;的电调供电 ArduPilotMega 内部的硬件结构图&#xff1a; 调试时&#xff0c;不要使用向导&#xff0c;由于向导功能不…

Linux中的SCP:有你,一切都不遥远

引言 在Linux系统中&#xff0c;文件传输是一个常见的任务。SCP&#xff08;Secure Copy Protocol&#xff09;命令提供了一种安全的方式来在本地和远程计算机之间复制文件。本文将详细介绍SCP命令的使用方法&#xff0c;并提供一些实用的示例以及故障排除指南。 SCP命令简介…

vue组件通讯$parent和$children获取单签组件的⽗组件和当前组件的⼦组件的例子

在 Vue 中&#xff0c;$parent 和 $children 是实例属性&#xff0c;允许你访问组件的父组件和子组件。但是&#xff0c;请注意&#xff0c;这些属性主要用于在开发过程中进行调试和临时访问&#xff0c;并不推荐在正常的组件通信中使用&#xff0c;因为它们破坏了组件的封装性…

React Native 之 Linking(链接)(十五)

URL Scheme是什么 URL Scheme是一种机制&#xff0c;主要用于在移动应用程序中打开另一个应用程序或执行特定操作。 定义与原理&#xff1a; URL Scheme允许应用程序通过特定的URL格式与其他应用程序进行交互。 它通过在应用程序中注册一个自定义的URL Scheme&#xff0c;并在…