C语言中的结构体,指针,联合体的使用

embedded/2024/11/25 14:47:06/

目录

  • 1. 概述
  • 2. 定义和初始化
  • 3. 成员的使用
  • 4. 结构体数组
  • 5. 结构体套结构体
  • 6. 结构体赋值
  • 7. 结构体和指针
  • 8. 结构体作为函数参数
  • 9. 共用体(联合体)
  • 10. typedef就是取别名
  • 总结

1. 概述

数组:连续的相同数据类型的集合
结构体:不同数据类型的集合

2. 定义和初始化

  • 先声明结构体类型再定义变量名
  • 在声明类型的同时定义变量
  • 直接定义结果体类型变量(无类型名)
  1. 定义结构体类型,再使用该类型定义变量
struct stu {char name[20];int age;
};
struct stu s1 = { "lily", 20 };
  1. 定义结构体类型同时定义变量
struct stu2 {char name[20];int age;
} s2 = { "lily", 20 };
  1. 定义结构体变量,不定义类型
struct{char name[20];int age;
} s3 = { "lily", 20 };

3. 成员的使用

  1. 结构体.成员
  2. 结构体->成员
# include<stdio.h>
struct stu {char name[20];int age;
};int main() {struct stu s1 = { "lily", 20 };// 1. 通过点运算符访问s1变量的成员printf("名字是:%s\n", s1.name);// 修改strcpy(s1.name, "Jorry");printf("名字是:%s\n", s1.name);// 2. 通过->运算符访问结构体指针变量p的成员printf("(&s1)->name = %s, (&s1)-> age = %d\n", (&s1)->name, (&s1)->age);return 0;
}

4. 结构体数组

# include<stdio.h>
struct stu {char name[20];int age;
};int main() {struct stu s1[5] = { {"lily", 24 },{"lidaly", 205 },{"lidaly", 203 },{"lilsady", 230 },{"lily2", 22 } };for (int i = 0; i < 5; i++) {printf("输出%d个:---------\n", i);printf("名字是:%s, 年龄: %d\n", s1[i].name, s1[i].age);printf("名字是:%s, 年龄: %d\n", (*(s1+i)).name, s1[i].age);printf("名字是:%s, 年龄: %d\n", (s1 + i)->name, s1[i].age);}printf("-----------");return 0;
}

5. 结构体套结构体

# include<stdio.h>
struct stu {char name[20];int age;
};
struct teacher {int age;struct stu s;
};
int main() {// 这样子写也可以// struct teacher t[2] = { 40, "张三", 18, 42, "李四", 28};struct teacher t[2] = {{40, {"张三", 18}},{42, {"李四", 28}}};int i = 0;for (i = 0; i < 2; i++) {printf("老师[%d]的年龄: %d,学生名字:%s, 学生年龄: %d\n", i, t[i].age, t[i].s.name, t[i].s.age);}return 0;
}

6. 结构体赋值

// 有警告
#define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
#include <string.h>
#include <stdlib.h>
struct stu {char name[20];int age;
};
int main() {struct stu s;strcpy(s.name, "rose");s.age = 18;printf("名字是:%s, 年龄: %d\n", s.name, s.age);// 结构体赋值struct stu s2 = s;// 和拷贝一样memcpy(&s2, &s1, sizeof(s1))printf("名字是:%s, 年龄: %d\n", s2.name, s2.age);// 这是两个变量,可以输出地址查看printf("s的地址: %d, s2的地址: %d", &s, &s2);return 0;
}

7. 结构体和指针

  1. 普通结构体指针
  2. 指向堆区空间的结构体指针
  3. 结构体中套指针
#define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
#include <string.h>
#include <stdlib.h>
struct stu {char name[20];int age;
};
struct stu2 {char* name;int age;
};
int main() {// 1. 普通结构体指针struct stu s = { "milk", 23 };struct stu* p = &s;printf("1. \n");printf("名字是:%s, 年龄: %d\n", p->name, p->age);printf("名字是:%s, 年龄: %d\n", (*p).name, (*p).age);// 2. 指向堆区空间的结构体指针struct stu* p2 = (struct stu *)malloc(sizeof(struct stu));strcpy(p2->name, "rose9");p2->age = 27;printf("2. \n");printf("名字是:%s, 年龄: %d\n", p2->name, p2->age);printf("名字是:%s, 年龄: %d\n", (*p2).name, (*p2).age);// 3. 结构体中套指针struct stu2* p3 = (struct stu2*)malloc(sizeof(struct stu2));p3->name = (char*)malloc(strlen("jack") + 1);strcpy(p3->name, "rose");p3->age = 29;printf("3. \n");printf("名字是:%s, 年龄: %d\n", p3->name, p3->age);printf("名字是:%s, 年龄: %d\n", (*p3).name, (*p3).age);if (p3->name != NULL) {free(p3->name);p3->name = NULL;}if (p3 != NULL) {free(p3);p3 = NULL;}return 0;
}

8. 结构体作为函数参数

  1. 作为普通变量做函数参数
  2. 指针变量做函数参数
#define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
#include <string.h>
#include <stdlib.h>
void foo(struct stu tmp) {printf("名字是:%s, 年龄: %d\n", tmp.name, tmp.age);strcpy(tmp.name, "milk");printf("名字是:%s, 年龄: %d\n", tmp.name, tmp.age);
}void foo2(struct stu* tmp) {printf("名字是:%s, 年龄: %d\n", tmp->name, tmp->age);strcpy(tmp->name, "rose");tmp->age = 27;printf("名字是:%s, 年龄: %d\n", tmp->name, tmp->age);
}int main() {struct stu s = { "lily", 20 };foo(s);printf("名字是:%s, 年龄: %d\n", s.name, s.age);foo2(&s);printf("名字是:%s, 年龄: %d\n", s.name, s.age);return 0;
}

输出结果:

名字是:lily, 年龄: 20
名字是:milk, 年龄: 20
名字是:lily, 年龄: 20
名字是:lily, 年龄: 20
名字是:rose, 年龄: 27
名字是:rose, 年龄: 27

9. 共用体(联合体)

联合union是一个能在同一个存储空间存储不同类型数据的类型
联合体所占的内存长度等于其最长成员的长度倍数,也有叫做共用体

# include<stdio.h>
#include <string.h>
#include <stdlib.h>
struct stu {char name[20];int age;
};
union test {unsigned char a;unsigned int b;unsigned short c;};
int main() {union test tmp;// 1. 共用体中元素地址是一样的printf("&(tmp.a) = %p, &(tmp.b) = %p, &(tmp.c) = %p\n", &(tmp.a), &(tmp.b), &(tmp.c));//2. 共用体变量大小是最大元素大小pritf("sizeof(tmp) = %d\n", sizeof(tmp));// 3. 给其中一个赋值,会影响其他元素tmp.b = 0x44332211;printf("tmp.a = %x, tmp.b = %x, tmp.c = %x\n", tmp.a, tmp.b, tmp.c);tmp.a = 0x00;printf("tmp.a = %x, tmp.b = %x, tmp.c = %x\n", tmp.a, tmp.b, tmp.c);return 0;
}

输出结果:

&(tmp.a) = 000000378D8FF574, &(tmp.b) = 000000378D8FF574, &(tmp.c) = 000000378D8FF574
sizeof(tmp) = 4
tmp.a = 11, tmp.b = 44332211, tmp.c = 2211
tmp.a = 0, tmp.b = 44332200, tmp.c = 2200

10. typedef就是取别名

#define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
#include <string.h>
#include <stdlib.h>
#define TRUE 1
typedef struct test {int a;char b;short c;
}TEST, *PTEST;
int main() {printf("TRUE = %d\n", TRUE);TEST t1;t1.a = 10;t1.b = 'b';t1.c = 40;PTEST p = &t1;printf("p->a = %d, p->b = %c, p->c = %d\n", p->a, p->b, p->c);return 0;
}

输出结果:

TRUE = 1
p->a = 10, p->b = b, p->c = 40
typedef struct test {int a;char b;short c;
}*PTEST;
//相当于
typedef struct test {int a;char b;short c;
}* PTEST;
//给struct test {
//	int a;
//	char b;
//	short c;
//}*起名为PTEST

总结

结构体在 C 语言中非常有用,它可以帮助你更有效地组织和管理复杂的数据结构,适用于很多实际的编程场景,如数据库编程、图形编程等领域。
这部分很基础,也很有意思,后面的话,我考虑使用结构体进行一些操作,发一些博客。
这边博客仅仅是基础的使用,后面会尽量细一些,丰富一些。


http://www.ppmy.cn/embedded/140407.html

相关文章

Java将PDF保存为图片

将 PDF 文件转换为图片是常见的需求之一&#xff0c;特别是在需要将 PDF 内容以图像形式展示或处理时。其中最常用的是 Apache PDFBox。 使用 Apache PDFBox Apache PDFBox 是一个开源的 Java 库&#xff0c;可以用来处理 PDF 文档。它提供了将 PDF 页面转换为图像的功能。 …

SSM--SpringMVC复习(一)

SpringMVC Spring MVC 是一个实现了MVC设计模式的请求驱动类型的轻量级Web框架&#xff0c; 本质上相当于 Servlet&#xff0c;以 DispatcherServlet 为核心&#xff0c;负责协调和组织不同组件以完成请求处理并返回响应。通过控制器&#xff08;C&#xff09;对模型数据&…

十五届蓝桥杯赛题-c/c++ 大学b组

握手问题 很简单&#xff0c;相互牵手即可&#xff0c;但是要注意&#xff0c;第一个人只能与其他49个人牵手&#xff0c;所以开头是加上49 #include <iostream> using namespace std; int main() {int cnt0;for(int i49;i>7;i--){cnti;//cout<<i<<&quo…

第十章 JavaScript的运用

10.1 JavaScript概述 1.JavaScript简介 JavaScript是一种基于对象&#xff08;Object&#xff09;和事件驱动&#xff08;Event Driven&#xff09;并具有安全性能的脚本语言&#xff0c;能够与HTML&#xff08;超文本标记语言&#xff09;、Java语言一起在Web页面中与Web客…

银河麒麟v10 x86架构二进制方式kubeadm+docker+cri-docker搭建k8s集群(证书有效期100年) —— 筑梦之路

环境说明 master&#xff1a;192.168.100.100 node: 192.168.100.101 kubeadm 1.31.2 &#xff08;自编译二进制文件&#xff0c;证书有效期100年&#xff09; 银河麒麟v10 sp2 x86架构 内核版本&#xff1a;5.4.x 编译安装 cgroup v2启用 docker版本&#xff1a;27.x …

Mac配置maven环境及在IDEA中配置Maven

Mac配置maven环境及在IDEA中配置Maven 1. 介绍 Maven是一款广泛用于Java等JVM语言项目的工具&#xff0c;它以项目对象模型&#xff08;POM&#xff09;为基础进行项目管理&#xff0c;通过POM文件来定义项目信息和依赖关系。同时&#xff0c;它也是构建自动化工具&#xff0…

Sparrow系列拓展篇:消息队列和互斥锁等IPC机制的设计

前言 笔者这几天利用空闲时间为Sparrow添加了消息队列和互斥锁&#xff0c;已经有十余天没有更过文章了&#xff0c;今天下笔想写一写博客&#xff0c;遂继续为Sparrow更新一篇拓展篇。 其实也没什么好讲的&#xff0c;信号量、消息队列、互斥锁这些IPC机制都大差不差&#x…

DVWA 在 Windows 环境下的部署指南

目录预览 一、靶场介绍二、前置准备1. 环境准备2.靶场下载 三、安装步骤1.配置Phpstudy2.配置数据库3.配置DVWA4.登入DVWA靶场 四、参考链接 一、靶场介绍 DVWA 一共包含了十个攻击模块&#xff0c;分别是&#xff1a; Brute Force&#xff08;暴力&#xff08;破解&#xff…