C语言笔记22 •结构体•

C语言结构体

1.结构体类型的声明

struct Stu
{
  char name[ 20 ]; // 名字
  int age; // 年龄
   char sex[ 5 ]; // 性别
   char id[ 20 ]; // 学号
};

2.结构体变量的创建和初始化

#include <stdio.h>

// 定义一个结构体类型 Point
struct Point {
    int x;
    int y;
};

int main() {
    // 创建并初始化结构体变量的几种方式
    
    // 1. 分别初始化每个成员
    struct Point p1;
    p1.x = 10;
    p1.y = 20;

    // 2. 声明的同时初始化
    struct Point p2 = {30, 40};

    // 3. 使用C99提供的指定成员初始化
    struct Point p3 = {.y = 50, .x = 60};

    // 打印结构体变量的值
    printf("Point p1: x = %d, y = %d\n", p1.x, p1.y);
    printf("Point p2: x = %d, y = %d\n", p2.x, p2.y);
    printf("Point p3: x = %d, y = %d\n", p3.x, p3.y);

    return 0;
}
#include <stdio.h>

struct Stu {
    char name[20];  // 名字
    int age;        // 年龄
    char sex[5];    // 性别
    char id[20];    // 学号
};

int main() {
    // 按照结构体成员的顺序初始化
    struct Stu s = { "张三", 20, "男", "20230818001" };

    // 打印结构体s的成员
    printf("name: %s\n", s.name);
    printf("age : %d\n", s.age);
    printf("sex : %s\n", s.sex);
    printf("id : %s\n", s.id);

    // 按照指定的成员初始化
    struct Stu s2 = { 
        .age = 18, 
        .name = "lisi", 
        .id = "20230818002", 
        .sex = "女" 
    };

    // 打印结构体s2的成员
    printf("name: %s\n", s2.name);
    printf("age : %d\n", s2.age);
    printf("sex : %s\n", s2.sex);
    printf("id : %s\n", s2.id);

    return 0;
}
//匿名结构体
struct
{
  char name[ 20 ]; // 名字
  int age; // 年龄
   char sex[ 5 ]; // 性别
   char id[ 20 ]; // 学号
}p;
//像这样的匿名结构体是不能多次使用,只能使用一次
struct
{
  char name[ 20 ]; // 名字
  int age; // 年龄
   char sex[ 5 ]; // 性别
   char id[ 20 ]; // 学号
}*pa;  pa是匿名结构体指针变量
pa=&p;   
//这样是不合法 因为一个是结构体变量 p,另一个是结构体指针变量 pa。匿名结构体的这两个定义是独立的, 编译器会把上⾯的两个声明当成完全不同的两个类型,所以是⾮法的

3.结构体的⾃引⽤

struct Node
{
    int data;
    struct Node * next ;
};
如下图

4.结构体内存对齐

学习结构体的内存对齐,其实也是计结构体的⼤⼩

结构体的对齐规则:

1. 结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
2. 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
    对⻬数 = 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值。
    - VS 中默认的值为 8
    - Linux中 gcc 没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩
3. 结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤      的)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。
举例:
//假设对齐数 默认的值为 8
// #pragma 这个预处理指令,可以改变编译器的默认对⻬数。
// # pragma pack(1) // 设置默认对⻬数为 1
//# pragma pack() // 取消设置的对⻬数,还原为默认
struct data
{
  int a;
  char b;
  short c;
  short d;
}AA_t;
解释:
(1)a是整形占4个字节:4   8  按照对齐规则2,对齐数4和8的最小值就是 4,又因为a是第一个成员变量,就从偏移量为0开始。
(2)b是字符占1个字节:1   8   对齐数就是 1,此时b要从偏移量为多少处开始呢,就是找1的整数倍数,从a往下数就是4,4是1的整数倍数,因为b是字符占1个字节,只占一个就行。
(3)c是短整形short占2个字节:2   8   对齐数就是 2,此时c要从偏移量为多少处开始呢,就是找2的整数倍数,从b往下数就是5,5不是2的整数倍数,接着往下数也就是6了,因为c是短整形占2个字节,占两个就行。
(3)d是短整形short占2个字节:2   8   对齐数就是 2,此时d要从偏移量为多少处开始呢,就是找2的整数倍数,从c往下数就是8,8是2的整数倍数,因为d是短整形占2个字节,占两个就行。
此时此刻a、b、c、d已经占了 10个字节了,按照 对齐规则3结构体总⼤⼩为最⼤对⻬数的整数倍。a、b、c、d中最大对齐数是4,那么 结构体总⼤⼩为4的整数倍。显然10不是4的整数倍,就往下找到偏移量为11处 占了12个字节,也正好为4的整数倍。 所以结构体总⼤⼩为:12
struct data1
{
  int a;
  char b;
  short c;
  short d;
  struct data e;
}AA;

结构体 struct data1在struct data的基础之上把struct data嵌套在 struct data1里,所以按照对齐规则4,就是嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,struct data的最大对齐数是4,那偏移量就从12处开始,struct data大小为12个字节就到偏移量23处,此时此刻a、b、c、d、e所占字节为24,struct data1结构体大小为所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍,struct data1结构体的最⼤对⻬数为4,24是4的倍数,所以struct data1结构体大小为24

5.为什么结构体存在内存对⻬

(1)平台原因 (移植原因)
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定 类型的数据,否则抛出硬件异常。
(2)性能原因:
数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬。原因在于,为了访问未对⻬的内存,处理器需要 作两次内存访问;⽽对⻬的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对⻬成8的倍数,那么就可以 ⽤⼀个内存操作来读或者写值了。否则,我们可能需要执⾏两次内存访问,因为对象可能被分放在两个8字节内存块中。
总体来说:结构体的内存对⻬是拿空间来换取时间的做法,就如上面的例子,对齐需要1次访问就可以访问b,节约时间成本,但是浪费了3个字节空间。
所以在设计结构体的时候,既要满⾜对⻬,⼜要节省空间,解决方法就是:
让占⽤空间⼩的成员尽量集中在⼀起
//举例:
  struct S1
{
    char c1;
    int i;
    char c2;
};
struct S2
  {
      char c1;
      char c2;
      int i;
};
//   S2 比   S1 结构体 所占空间就要小。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pikachu-Unsafe Filedownload

任意点击一个图片进行下载&#xff0c;发现下载的url。 http://127.0.0.1/pikachu/vul/unsafedownload/execdownload.php?filenamekb.png 构造payload&#xff1a; 即可下载 当前页面的源码&#xff0c;可以进行路径穿越来下载一些重要的配置文件来获取信息。 http://127.0.…

【PostgreSQL001】比较开发生产2个数据库结构方法

1.一直以来想写下基于PostgreSQL的系列文章&#xff0c;作为较火的数据ETL工具&#xff0c;也是日常项目开发中常用的一款工具&#xff0c;最近刚好挤时间梳理、总结下这块儿的知识体系。 2.熟悉、梳理、总结下PostgreSQL数据库相关知识体系。 3.欢迎批评指正&#xff0c;欢迎关…

【Mac】MWeb Pro(好用的markdown编辑器) v4.5.9中文版安装教程

软件介绍 MWeb Pro for Mac是一款Mac上的Markdown编辑器软件&#xff0c;它支持实时预览&#xff0c;语法高亮&#xff0c;自动保存和备份等功能&#xff0c;并且有多种主题和样式可供选择。此外&#xff0c;MWeb还支持多种导出格式&#xff0c;包括HTML、PDF、Word、ePub等&a…

虚拟机启动Operating System not found找不到操作系统

错误信息 PEX-E51 No SHCP or proxyDHCP offers were received. PXE-M0F: Exiting Intel PXE ROM. Operating System not found解决方法1 到服务里面检查跟vmware相关的服务是否已经全部启动 如果服务怎么都无法启动&#xff0c;最简单的办法还是重装vmware 解决方法2 &#…

数据插值之朗格朗日插值(一)

目录 一、引言 二、代码实现 2.1 Lagrange插值求插值多项式&#xff1a; 代码解析&#xff1a; 1.vpa解释 2.ploy&#xff08;x&#xff09;解释: 3.conv&#xff08;&#xff09;解释 4.poly2sym()解释 2.2 Lagrange插值求新样本值和误差估计&#xff1a; 代码解析&…

容器化:ES和Kibana

1 缘起 最近在学习使用ES&#xff0c; 为了找一个功能强大的可视化工具&#xff0c;之前使用了ES-Head&#xff0c;可以满足学习需求。 闲暇时间又折腾了另一个工具Kibana&#xff0c; 分享如下。 Kibana优点&#xff1a; 用户友好性&#xff1a;Kibana提供直观易用的用户界面…

项目思考-编辑器

1、文本生成编辑器 2、图片合成编辑器&#xff08;未完待续&#xff09; 3、文字和图像版本的技术要点&#xff0c;区别&#xff08;未完待续&#xff09; 4、编辑器的人员配置考虑&#xff0c;技术难点分析&#xff08;未完待续&#xff09; 1、文本生成编辑器

【Python】 掌握 Flask 请求数据获取的艺术

基本原理 在Web开发中&#xff0c;Flask是一个用Python编写的轻量级Web应用框架。它被广泛用于快速开发简单的Web应用。当用户通过浏览器或其他客户端向服务器发送请求时&#xff0c;Flask需要能够接收和解析这些请求中的数据。这些数据可以是GET请求的查询字符串、POST请求的…

收集 VSCode 常用快捷键

快速复制行 Shift Alt ↑/↓ 都是往下复制行&#xff0c;区别是&#xff1a;按↓复制时光标会跟着向下移动&#xff0c;按↑复制时光标不移动。 向上/向下移动一行 Alt ↑/↓ 删除整行 Ctrl Shift KCtrl x 剪切快捷键在VSCode 可以直接删除一行 垂直编辑 Ctrl…

用于时间序列概率预测的蒙特卡洛模拟

大家好&#xff0c;蒙特卡洛模拟是一种广泛应用于各个领域的计算技术&#xff0c;它通过从概率分布中随机抽取大量样本&#xff0c;并对结果进行统计分析&#xff0c;从而模拟复杂系统的行为。这种技术具有很强的适用性&#xff0c;在金融建模、工程设计、物理模拟、运筹优化以…

HACL-Net:基于MRI的胎盘植入谱诊断的分层注意力和对比学习网络

文章目录 HACL-Net: Hierarchical Attention and Contrastive Learning Network for MRI-Based Placenta Accreta Spectrum Diagnosis摘要方法实验结果 HACL-Net: Hierarchical Attention and Contrastive Learning Network for MRI-Based Placenta Accreta Spectrum Diagnosis…

Linux驱动设备导论(1)

最近本人在学习Linux驱动&#xff0c;本系列教程是本人在一边学习&#xff0c;一边总结的系列教程&#xff0c;希望能够给很多刚学驱动小伙伴一些总结。 1.Linux设备分类 驱动针对的对象是存储器和外设&#xff0c;不是针对CPU&#xff0c;可以分为以下三大类&#xff1a; 1.…

01-Linux【准备篇】

一、学Linux的作用&#xff1f; 1.Linux下开发(部署)软件项目 2.Linux运维 二、Linux的强与弱 1.薄弱 个人桌面领域的应用 此领域是传统Linux应用薄弱的环节&#xff0c;近些年随着Ubuntu、fedora等优秀桌面环境的兴起&#xff0c;Linux在个人桌面领域的占有率在慢慢提高…

[国产大模型简单使用介绍] 开源与免费API

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 随着大模型技术蓬勃发展和开源社区越来越活跃,国内的大模型也如雨后春笋一般.这时,一些就会问了,有了llama3,Mistral还有Gemma等等,国外大厂接连发力,一些开源社区也会有一些不错的模型,国内怎么比?对一个人使用,oll…

Debezium+Kafka:Oracle 11g 数据实时同步至 DolphinDB 解决方案

随着越来越多用户使用 DolphinDB&#xff0c;各式各样的应用场景对 DolphinDB 的数据接入提出了不同的要求。部分用户需要将 Oracle 11g 的数据实时同步到 DolphinDB 中来&#xff0c;以满足在 DolphinDB 中实时使用数据的需求。本篇教程将介绍使用 Debezium 来实时捕获和发布 …

03_前端三大件CSS

文章目录 CSS用于页面元素美化1.CSS引入1.1style方式1.2写入head中&#xff0c;通过写style然后进行标签选择器加载样式1.3外部样式表 2.CSS样式选择器2.1 元素选择器2.2 id选择器2.3 class选择器 3.CSS布局相关3.1 CSS浮动背景&#xff1a;先设计一些盒子因此&#xff0c;引出…

【Go专家编程——内存管理——垃圾回收】

垃圾回收 所谓的垃圾就上不在需要的内存块&#xff0c;垃圾如果不清理&#xff0c;这些内存块就没有办法再次被分配使用。在不支持垃圾回收的编程语言中&#xff0c;这些垃圾内存就上泄露的内存。 1. 垃圾回收算法 常见的垃圾回收算法有3种 引用计数&#xff1a;对每个对象…

Vue学习笔记3——事件处理

事件处理 1、事件处理器&#xff08;1&#xff09;内联事件处理器&#xff08;2&#xff09;方法事件处理器 2、事件参数3、事件修饰符 1、事件处理器 我们可以使用v-on 指令(简写为)来监听DOM事件&#xff0c;并在事件触发时执行对应的JavaScript。 用法: v-on:click"me…

牛客NC334 字典序第K小【困难 10叉树 Java/Go/PHP/C++】,力扣 440. 字典序的第K小数字

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/670c2bda374241d7ae06ade60de33e8b https://leetcode.cn/problems/k-th-smallest-in-lexicographical-order/description/ 本答案核心 10叉树, 数学规律Java代码 import java.util.*;public class Solution {…

出题123

题目时限空间说明 无特殊均默认 1 s , 256 M B 1s,256MB 1s,256MB Problem a 最大化 在最大化目标值的基础上选择的操作越多越好&#xff0c;且输出操作应当按照顺序执行&#xff0c;即你的输出顺序就是你的执行顺序&#xff0c;当有多个执行顺序可以最大化目标值时&#xff0…