C语言基础知识——结构体和共用体

news2025/2/25 16:21:12

1. 结构体

1.1 初识结构体

  C语言的结构体是一种自定义的 数据类型,它允许你将不同类型的数据组合在一起,形成一个新的数据类型,以便更方便地管理和操作这些数据。结构体可以包含多个成员(也称为字段或属性),每个成员可以是不同的数据类型,例如整数、浮点数、字符、数组或其他结构体。

  简单声明一个结构体如下:结构体名称是你给这个结构体类型取的标识符,可以根据需要自行命名。

struct 结构体名称 {

    数据类型 成员1;
    数据类型 成员2;
    // 其他成员定义...
};

1.2 结构体类型和结构体变量简介

  结构体类型:结构体类型是用户自定义的数据类型,用于表示一组相关的数据,这些数据可以是不同的类型。(也就是结构体的定义)
  结构体变量:也就是结构体类型变量,它是根据结构体类型创建的具体实例,用于存储实际的数据。

struct Student {
    char name[50];
    int age;
    float gpa;
};

  这里就是创建了一个名为Student的结构体类型。

struct Student student1;
struct Student student2;

  这里就是创建了个名为student1student2的两个结构体变量。

1.3 结构体的声明方式(包括类型和变量的声明)

第一种声明方式:

struct point{
  int x;
  int y;
};

struct point pl;
struct point p2;

  结构体类型的名字叫point,结构体变量的名字p1和p2。在这里声明结构体变量的时候必须加上struct ,struct point这两个合起来才代表point这种结构类型。

第二种声明方式:

struct {
  int x;
  int y;
} pl,p2;

  这里没有定义结构体类型的名字,结构体变量的名字p1和p2。这里已经声明了两个结构体变量了,不需要再单独声明了。

第三种声明方式:

struct point{
  int x;
  int y;
} pl,p2;

  结构体类型的名字叫point,结构体变量的名字p1和p2。这里已经声明了两个结构体变量了,不需要再单独声明了。

第四种声明方式:(自定义数据类型)
  在C语言中,typedef是一个用于创建自定义数据类型别名的关键字。具体使用如下:

typedef struct point{
  int x;
  int y;
} p;
//或者
typedef struct {
  int x;
  int y;
} p;
//声明结构体变量
p p1;
p p2;

  上面两种声明中,一种的结构体类型名是point,另一种是无名结构体类型,最后新的结构体类型名都变成了p;这里和上面的不同的是p是新的结构体类型名字,而不是结构体变量名;声明结构体变量还是要通过p p1;这样声明,这样使用typedef的好处是声明结构体变量时,不用再加上struct了。

1.4 结构体的初始化

// 定义结构体类型
typedef struct {
  int x;
  int y;
  int z;
} p;

常用方法1:
  对结构体成员进行初始化,这里的初始化的顺序必须与结构体成员定义的顺序一致。

p p1 = {1,2,3};

常用方法2:
  通过成员名来指定结构体成员的初始化。

// 定义结构体类型
struct Person {
    char name[50];
    int age;
    float height;
    float gpa;
};
 struct Person person1 = {
        .name = "John Doe",
        .age = 25,
        .height = 175.5,
        .gpa = 85.5
    };
    
 struct Person person1 = {
        .name = "John Doe",
        .age = 25,
        .height = 175.5,  //这里没有初始化gpa,其值会默认为0
    };

  上面初始化的过程中,通过.的操作来取结构体成员进行相应的初始化,如果初始化的个数少于原本结构体的成员个数,那么系统会把未初始化的成员赋值为0。

1.5 结构体指针

  概念:结构体指针是指针变量用于存储和操作结构体类型的地址。通过结构体指针,你可以访问结构体的成员,动态创建结构体实例,以及在函数中传递结构体的引用,避免复制结构体数据。

//声明一个结构体
struct Person {
    char name[50];
    int age;
    float height;
};

//创建一个结构体变量
 struct Person person1;
 
 // 声明指向结构体的指针,并将其指向结构体实例
 struct Person *p  = &person1;

  通过指针访问结构体中的成员:

p->age = 25;       //通过指针访问结构体中的成员,注意person1没有person1->age,因为person1不是指针,没有->操作
person1.age = 25;  //通过结构体变量访问结构体中的成员

   这里的(*p)就代表结构体变量。

(*p).age = 25;      
person1.age = 25; 

举一个简单实例:

#include <stdio.h>
struct Person {
    char name[50];
    int age;
    float height;
};
int main() {
    // 创建结构体实例
    struct Person person1 = {"John Doe", 25, 175.5};
    // 声明指向结构体的指针,并将其指向结构体实例
    struct Person *personPtr = &person1;
    // 通过指针访问结构体成员
    printf("Name: %s\n", personPtr->name);
    printf("Age: %d\n", personPtr->age);
    printf("Height: %.2f\n", personPtr->height);
    return 0;
}

运行结果如下:
在这里插入图片描述

1.6 结构体嵌套

  结构体嵌套是指在一个结构体中包含另一个结构体作为其成员。这种嵌套的结构体允许将多个相关的数据组合在一起,形成更复杂的数据结构。举例如下:

struct point{
  int x;
  int y;
};
struct rectangle{    
  struct point p1;   //p1是一个结构体变量
  struct point p2;   //p2是一个结构体变量
};
//初始化一个rectangle实例
struct rectangle r1 = {
   {3,1}{4,2}};
//访问成员变量,按照顺序进行
r1.p1.x = 3;

//初始化一个结构体数组
struct rectangle r2[2] = {
   {{3,1}{4,2}},
   {{5,3}{6,4}},
};

//访问成员变量,按照顺序进行
r2[1].p1.x = 3;

2. 共用体

  共用体(Union)是一种特殊的数据类型,允许在相同的内存空间中存储不同类型的数据。共用体的内存空间大小等于其最大成员的大小,因为共用体中的所有成员共用同一块内存
  共用体的一个典型应用是在需要在不同数据类型之间进行转换或共享相同内存的情况下。注意,由于共用体的不同成员共用同一块内存,只能同时存储其中一个成员的值。举例如下:

#include <stdio.h>
#include <string.h>
// 定义共用体
union Data {
    int intValue;            //int类型变量
    char ch[sizeof(int)];    //字符数组 在x86的32位或者64位里面,sizeof(int) = 4
};

int main() {
    union Data data;         //声明共用体变量
    data.intValue = 1234;    //给变量成员赋值
    printf("Value as integer: %d\n", data.intValue);
    for(int i = 0; i < sizeof(int); i++){
     	printf("%02hhX\r\n",data.ch[i]);  //观察数组中存放的数据(因为共用了一块内存地址)
 }
    return 0;
}

  **这里1234的16进制表示是04D2,所以数组四个元素应该是00,00,04,D2的组合,**但是大多数计算机都采用小端存储,即低位字节(即较低地址)保存在内存中的低地址,高位字节(即较高地址)保存在内存中的高地址。04是高字节所以要存在高地址上,就在D2后面。
在printf语句中:
  02: 表示输出的十六进制数占据两个字符宽度,如果不足两位,则在前面填充0;
  hh: 表示参数 ch[i] 是一个 char 类型,将其按无符号字符类型输出。
  X: 表示以大写字母的十六进制形式输出。
   上面程序运行的结果如下:

在这里插入图片描述

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

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

相关文章

使命、愿景、价值观到底有什么区别

以前的企业都是在发展到一定成熟阶段&#xff0c;才开始考虑这三个问题。但今天人们越来越多的意识到&#xff0c;哪怕在企业发展的初期&#xff0c;对于创业企业来说&#xff0c;确定公司的使命、愿景和核心价值观也是非常重要的。 明确的使命、愿景和核心价值观对于企业的好…

搭建k8s集群!!!

注意 k8s集群第一次搭建的话是麻烦且又繁琐的,大家不要着急,静下心来,一步一步搭建即可 linux网关及虚拟机下载不会弄的问题请详细看 linux的搭建及网关配置 这篇文章【也在此专栏】 环境规划 硬件环境 cpu 至少2核 内存 至少3G 硬盘 至少40G 软件环境 操作…

从录取成绩的角度来看,浙大MPA面试的客观公正性是有一定依据的

时间即将来到八月份&#xff01;不知道目前考生们今年的备考情况怎么样了&#xff0c;度过比较煎熬的三伏天&#xff0c;距离考研冲刺的时间越来越近&#xff01; 提前批面试申请对于不同的项目以及不同的考生意义都不一样。比如真正的学霸人物对于提面的申请与不申请一般差别不…

自建HTTP代理池的四大优势

对于爬虫技术人员来说&#xff0c;使用http代理ip可以解决网页访问受限的问题。有人会直接购买成品的HTTP代理池&#xff0c;也有很多人会自己搭建http代理ip进行使用&#xff0c;自建HTTP代理池具有许多特点&#xff0c;为爬虫技术人员提供了有别于使用第三方代理服务的优势。…

【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

Unity 引擎做残影效果——2、屏幕后处理方式

Unity实现残影效果 大家好&#xff0c;我是阿赵。 这里继续介绍Unity里面做残影的方法。之前介绍了BakeMesh的方法做残影&#xff0c;这一期介绍的是用屏幕后处理的方法做残影。 一、原理 之前的BakeMesh方法&#xff0c;是真的生成了很多个网格模型在场景里面。如果用后处理做…

Linux学习之周期性计划任务cron和crontab

crontab -e可以编辑周期性计划任务。在使用此命令编辑的时候&#xff0c;需要要注意每一行有六个字段&#xff0c;使用空格或者Tab键进行隔开&#xff1a; Min Hour Day Month Day_Week commandToExecute - - - - - | | | | | | | | | --…

optee支持哪些密码学算法

GP规范强制要求 GP规范定义可选实现的 optee os实现的 参考:optee_os-3.20.0/lib/libutee/include/tee_api_defines.h 206 /* Algorithm Identifiers */ 207 #define TEE_ALG_AES_ECB_NOPAD 0x10000010 208 #define TEE_ALG_AES_CBC_NOPAD

【面试题】位图

文章目录 位图如何添加数据如何删除数据代码实现给100亿个整数&#xff0c;如何找到只出现一次的数字代码实现给两个文件&#xff0c;分别有100亿个整数&#xff0c;但只有1g内存&#xff0c;如何找到文件的交集&#xff1f;1个文件有100亿个int&#xff0c;1G内存&#xff0c;…

如何使用ArcGIS Pro制作建筑立体效果

虽然ArcGIS Pro已经将二三维场景融合于一个软件之中&#xff0c;但是在某些使用场景下&#xff0c;我们只需要看到建筑的立体效果就行&#xff0c;不用实际的三维建筑效果&#xff0c;毕竟三维的效果对硬件的要求更高&#xff0c;地图的加载效率也没有二维好&#xff0c;所以这…

【雕爷学编程】Arduino动手做(181)---Maixduino AI开发板6

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

住宅小区门禁管理,居然还能这样做!

安全是我们生活中最重要的一环。而在现代社会&#xff0c;门禁监控系统成为了保障居民安全的重要措施之一。 门禁系统利用先进的人脸识别技术&#xff0c;为小区居民带来了更高效、更安全的出入管理体验&#xff0c;更为居民创造了便捷、智能的生活方式。 客户案例 东莞市某花…

Flask项目打包为exe(附带项目资源,静态文件)

1.在项目根目录创建my_app.spec文件&#xff0c;内容如下&#xff1a; # -*- mode: python ; coding: utf-8 -*-block_cipher Nonea Analysis([server.py], # flask入口pathex[],binaries[], datas[("E:/**/templates","/templates"),("E:/**/s…

SpringBoot3 整合Prometheus + Grafana

通过Prometheus Grafana对线上应用进行观测、监控、预警… 健康状况【组件状态、存活状态】Health运行指标【cpu、内存、垃圾回收、吞吐量、响应成功率…】Metrics… 1. SpringBoot Actuator 1. 基本使用 1. 场景引入 <dependency><groupId>org.springframew…

大数据之Hadoop(一)

目录 一、准备三台服务器 二、虚拟机间配置免密登录 三、安装JDK 四、关闭防火墙 五、关闭安全模块SELinux 六、修改时区和自动时间同步 一、准备三台服务器 我们先准备三台服务器&#xff0c;可以通过虚拟机的方式创建&#xff0c;也可以选择云服务器。 关于如何创建虚…

fatal error C1128: 节数超过对象文件格式限制: 请使用 /bigobj 进行编译

问题 默认情况下&#xff0c;对象文件最多可存放 65,536 (2^16) 个可寻址的节。 /bigobj将该地址容量增加至 4,294,967,296 (2^32)。大多数模块将从来不会生成包含数超过 65,536 的 .obj 文件。 但是&#xff0c;计算机生成的代码或大量使用模板库的代码可能需要可存放更多节的…

python爬虫(五)_urllib2:Get请求和Post请求

本篇将介绍urllib2的Get和Post方法&#xff0c;更多内容请参考:python学习指南 urllib2默认只支持HTTP/HTTPS的GET和POST方法 urllib.urlencode() urllib和urllib2都是接受URL请求的相关参数&#xff0c;但是提供了不同的功能。两个最显著的不同如下&#xff1a; urllib仅可以…

人工智能技术

目录 1.什么是人工智能 2.人工智能的由来 3.人工智能的代表作 4.人工智能给人类带来的福利 1.什么是人工智能 人工智能 (Artificial Intelligence, AI) 是一门研究计算机如何模拟、模仿以及执行人类智能活动的科学与技术领域。它涉及了构建智能代理体系&#xff0c;使其能够…

电脑怎么设置密码?简单4招,轻松给电脑上锁!

“新买了部电脑&#xff0c;最近在使用时保存了一些比较重要的文件&#xff0c;想给电脑设置个密码以防文件泄露。电脑怎么设置密码呢&#xff1f;求答案&#xff01;” 电脑对我们的生活越来越重要&#xff0c;我们会将很多重要的文件数据等都保存在电脑中。如果电脑没有设置密…

arcgis字段计算器

1、两字段叠加。要求待叠加的字段类型为文本或字符串类型。如下&#xff1a; 2、字符串部分提取。