C_10_结构体

news/2024/9/15 17:44:06/ 标签: c语言, 开发语言

结构体

结构体中 只要遇到 字符串的 就用 strcpy 进行操作不用 = 因为等号是进行的浅拷贝 只是将地址进行复制而不是复制对象本身

1 作用

> 结构体是一种构造类型的数据结构,是一种或多种基本类型或构造类型的数据的集合

2 定义结构体

语法1

struct 结构体名
{
// 定义变量
};

语法2:

定义结构体时顺带创建一个结构体变量

struct 结构体名
{// 定义变量
}结构体变量名;

语法3:

给结构体起别名

typedef struct 结构体名称
{
// 定义成员变量
// 可以定义无数个成员变量
}别名;

语法4:

struct{// 定义成员变量// 可以定义无数个成员变量
} 结构体变量名;

3 创建结构体变量

语法1:

struct 结构体名称 结构体变量 = {1,2,3,....};
struct 结构体名称 结构体变量;

语法2:

> 别名 结构体变量 = {值1,值2,值3,....};
> 别名 结构体变量;

注意:

# 结构体对象清0
#				memset(&结构体变量名,0,sizeof(struct 结构体名称));结构体初始化 必须按照成员顺序和成员自身类型

4 结构体变量使用其中成员变量

存值结构体变量.成员变量名 = 值;注意:字符串的成员变量需要使用strcpy实现深拷贝
取值结构体变量.成员变量名

5 计算结构体大小

> 对齐方式,默认按照最大的进行对齐数组,结构体将被拆分为存储的数据的大小

示例:

struct Stu
{short x;      // 4int a;        // 4char c;       // 4char str[50]; // 47 / 4 = 11 .. 3 = 12 * 4 = 48
};

6 强制对其

作用

		默认的结构体的对齐方式是由其中最大的成员进行对齐的使用强制对齐就会使用强制的大小进行对齐

语法

#pragma pack (value)时的指定对齐值value为1 2 4 8

示例

#include <stdio.h>
#pragma pack(2)
struct Test
{int x;   // 4int *p;  // 8char c;  // 2short s; // 2
};
int main(int argc, char const *argv[])
{printf("%d\n", sizeof(struct Test));return 0;
}

特殊结构体

匿名结构体

特点

> 只能创建一个结构体变量

语法:

struct {成员变量;}结构体变量名;

示例

#include <stdio.h>
#include <string.h>
struct
{int age;char color[30];
}ql;
int main(int argc, char const *argv[])
{ql.age = 8000;strcpy(ql.color,"黑");printf("年龄:%d\t颜色:%s\n",ql.age,ql.color);return 0;
}

整体赋值

> 结构体变量名1 = 结构体变量名2;
> 将结构体变量2的成员的值逐一赋值给结构体变量1的成员

memcpy****函数

作用:拷贝内存中的内容

语法

void *memcpy(void *dest, const void *src, size_t n);参数:dest:目标地址src:资源地址n:长度

结构体定义结构体变量

概念: 结构体A中的成员变量是结构体B的变量

示例:

#include <stdio.h>
typedef struct dog
{char name[50];char sex[10];int age;
} Dog;
typedef struct person
{char name[50];char sex[10];int age;// 结构体中定义结构体变量Dog dog;
} Person;
int main(int argc, char const *argv[])
{Dog dog = {"旺财", "公", 3};// 将上面定义的结构体变量dog全赋值给p1中的成员变量dogPerson p1 = {"来福", "男", 18, dog};dog.age = 13;printf("p1的姓名:%s\n", p1.name);printf("p1的性别:%s\n", p1.sex);printf("p1的年龄:%d\n", p1.age);printf("p1 dog的姓名:%s\n", p1.dog.name);printf("p1 dog的性别:%s\n", p1.dog.sex);printf("p1 dog的年龄:%d\n", p1.dog.age);printf("dog的姓名:%s\n", dog.name);printf("dog的性别:%s\n", dog.sex);printf("dog的年龄:%d\n", dog.age);Person p2 = {"常威", "男", 28, {"黑豹", "母", 4}};printf("p2的姓名:%s\n", p2.name);printf("p2的性别:%s\n", p2.sex);printf("p2的年龄:%d\n", p2.age);printf("p2 dog的姓名:%s\n", p2.dog.name);printf("p2 dog的性别:%s\n", p2.dog.sex);printf("p2 dog的年龄:%d\n", p2.dog.age);return 0;
}

计算结构体大小

成员变量是结构体其占据的大小也是参与计算对齐单行大小的依据

#include <stdio.h>
typedef struct Data1
{char c; // 1int a;  // 4 8long b; //   8
} D1;       // 16
typedef struct Data2
{char c;  //  1int i;   //  4short s; //  2     16D1 d1;   // 16
} D2;
// 16+16 = 32
int main(int argc, char const *argv[])
{printf("%d\n", sizeof(D2));return 0;
}

结构体指针

概念

指向结构体变量的指针。

语法:

> 结构体名称 *指针变量名;

操作成员变量

指针变量名->成员变量名指针变量名->成员变量名 = 值;注意:字符数组型需要使用strcpy

示例

#include <stdio.h>
typedef struct stu
{char name[50]; // 48char sex[10];  // 12int age;       // 4
} Stu;
void chang01(Stu s)
{s.age = 29;
}
void chang02(Stu *s)
{s->age = 29;
}
int main(int argc, char const *argv[])
{Stu s01 = {"张三", "男", 18};Stu *p = &s01;printf("%s\n", p->name);p->age = 19;printf("%d\n", p->age);printf("%d\n", s01.age);// chang01(s01);//全赋值chang02(&s01); // 传递的是地址printf("%d\n", s01.age);return 0;
}

指针作为结构体成员

示例1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct stu
{char *name;char *sex;int age;
} Stu;
int main(int argc, char const *argv[])
{char str01[] = "Tom";char str02[] = "man";// Stu s = {str01,str02,19};// printf("s name = %s\n",s.name);// s.name[0] = 't';// printf("str01 = %s\n",str01);// printf("s name = %s\n",s.name);// 成员变量位指针变量如何实现深拷贝Stu s02;s02.name = calloc(50, 1);strcpy(s02.name, str01);s02.sex = calloc(10, 1);strcpy(s02.sex, str02);s02.age = 18;printf("s02 name = %s\n", s02.name);s02.name[0] = 't';printf("str01 = %s\n", str01);printf("s name = %s\n", s02.name);free(s02.name);free(s02.sex);return 0;
}

示例2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct stu
{char *name;char *sex;int age;
} Stu;
int main(int argc, char const *argv[])
{Stu *s01 = (Stu *)malloc(sizeof(Stu));s01->name = (char *)malloc(50);s01->sex = (char *)malloc(10);memset(s01, 0, sizeof(Stu));memset(s01->name, 0, 50);memset(s01->sex, 0, 10);strcpy(s01->name, "张三");strcpy(s01->sex, "男");s01->age = 20;printf("姓名:%s\t性别:%s\t年龄:%d\n", s01->name, s01->sex, s01->age);// 如果成员变量是指针,并且是动态开辟内存// 此时如果直接释放该结构体变量会导致内存泄漏// 所以应该先释放里面的成员变量的动态内存,在释放结构体变量的动态内存free(s01->name);free(s01->sex);free(s01);return 0;
}

示例3

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{char *name;char *sex;int age;
} Dog;
typedef struct person
{char *name;char *sex;int age;Dog *dog;
} Person;
int main(int argc, char const *argv[])
{Dog *d = (Dog *)calloc(1, sizeof(Dog)); // int d = 1;d->name = (char *)calloc(50, 1);d->sex = (char *)calloc(10, 1);Person *p = (Person *)calloc(1, sizeof(Person));p->name = (char *)calloc(50, 1);p->sex = (char *)calloc(10, 1);p->dog = d; // p->dog = dPerson *p2 = (Person *)calloc(1, sizeof(Person));p2->name = (char *)calloc(50, 1);p2->sex = (char *)calloc(10, 1);p2->dog = d;free(d->name);free(d->sex);free(d);free(p->name);free(p->sex);free(p);free(p2->name);free(p2->sex);free(p2);return 0;
}

数组存储结构体变量

示例1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{char name[50];char sex[10];int age;
} Dog;
int main(int argc, char const *argv[])
{Dog d01 = {"旺财01", "公", 2};Dog d02 = {"旺财02", "公", 2};Dog d03 = {"旺财03", "公", 2};Dog ds[] = {d01, d02, d03};int len = sizeof(ds) / sizeof(ds[0]);for (int i = 0; i < len; i++){
printf("姓名:%s\t性别:%s\t年
龄:%d\n",ds[i].name,ds[i].sex,ds[i].age);}return 0;
}

示例2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{char name[50];char sex[10];int age;
} Dog;
int main(int argc, char const *argv[])
{Dog d01 = {"旺财01", "公", 2};Dog d02 = {"旺财02", "公", 2};Dog d03 = {"旺财03", "公", 2};Dog *ds[] = {&d01, &d02, &d03};int len = sizeof(ds) / sizeof(ds[0]);for (int i = 0; i < len; i++){printf("姓名:%s\t性别:%s\t年龄:%d\n", ds[i]->name, ds[i] - > sex, ds[i]->age);}return 0;
}

示例3

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{char name[50];char sex[10];int age;
} Dog;
int main(int argc, char const *argv[])
{Dog *d01 = (Dog *)calloc(1, sizeof(Dog));strcpy(d01->name, "旺财01");strcpy(d01->sex, "公");d01->age = 2;Dog *d02 = (Dog *)calloc(1, sizeof(Dog));strcpy(d02->name, "旺财02");strcpy(d02->sex, "公");d02->age = 2;Dog *d03 = (Dog *)calloc(1, sizeof(Dog));strcpy(d03->name, "旺财03");strcpy(d03->sex, "公");d03->age = 2;Dog *ds[] = {d01, d02, d03};Dog **dss = &ds;for (int i = 0; i < 3; i++){printf("姓名:%s\t性别:%s\t年龄:%d\n", dss[i]->name, dss[i] - > sex, dss[i]->age);free(dss[i]);}return 0;
}

示例4

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{char name[50];char sex[10];int age;
} Dog;
Dog **getDogs()
{static Dog *dogs[10] = {0};for (int i = 0; i < 10; i++){char name[30] = "旺财";sprintf(name, "旺财%d", i + 1);dogs[i] = (Dog *)calloc(1, sizeof(Dog));strcpy(dogs[i]->name, name);strcpy(dogs[i]->sex, "公");dogs[i]->age = 2;}return &dogs;
}
int main(int argc, char const *argv[])
{Dog **dogs = getDogs();for (int i = 0; i < 10; i++){printf("姓名:%s\n", dogs[i]->name);}return 0;
}

示例5

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{char name[50];char sex[10];int age;
} Dog;
Dog **getDogs()
{Dog **dogs = (Dog **)calloc(10, sizeof(Dog *));for (int i = 0; i < 10; i++){Dog *d = (Dog *)calloc(1, sizeof(Dog));char n[30] = {0};sprintf(n, "旺财%d", i + 1);strcpy(d->name, n);printf("d = %p\n", d);dogs[i] = d;}return dogs;
}
int main(int argc, char const *argv[])
{Dog **dogs = getDogs();for (int i = 0; i < 10; i++){printf("姓名:%s\n", dogs[i]->name);}for (int i = 0; i < 10; i++){free(dogs[i]);}free(dogs);return 0;
}

http://www.ppmy.cn/news/1519567.html

相关文章

【QNX+Android虚拟化方案】112 - 获取 88Q5152 Switch Port1、Port2 端口的主从模式 / 传输速率 / 链路状态

【QNX+Android虚拟化方案】112 - 获取 88Q5152 Switch Port1、Port2 端口的主从模式 / 传输速率 / 链路状态 1. 读取 P1、P2 端口 主从模式 / 传输速率2. 读取 P1、P2 端口 Link Status3. 读取 P1、P2 端口 Duplex 全双工/半双工模式4. 读取 P1、P2 链路信号SQI质量5. 完整代码…

图像处理领域的术语解析

公司主要做液晶屏点屏测试相关设备&#xff0c;在工作中有一些专业术语需要掌握&#xff0c;浏览网页&#xff0c;把一些需要的术语摘录如下&#xff1a; 1、像素 把鼠标放在一个图片上&#xff0c;这个时候会显示尺寸和大小&#xff0c;这里的尺寸就是像素。 2、灰度 灰度是…

使用Ansible stat模块检查目录是否存在

使用Ansible stat模块检查目录是否存在或者是否为一个目录还是文件 理论知识 在Ansible中&#xff0c;你可以使用stat模块来检查一个目录是否存在。stat模块可以用来获取文件或目录的状态信息&#xff0c;包括它是否存在。下面是一个简单的例子&#xff0c;说明如何使用stat模…

OpenCV4深度神经网络DNN实战教程

OpenCV4深度神经网络DNN实战教程 1-概述与环境配置2-卷积神经网络概述3-加载网络模型与设置3.1 所需的模型下载3.2 所使用的模型&#xff08;googlenet&#xff09;3.3 Net介绍3.4 代码输出网络结构信息3.5 计算后台设置3.6 所有代码 4-图像分类网络inception的使用5-读取分类标…

NLP从零开始------15.文本中阶序列处理之语言模型(3)

4. 注意力机制 4.1 注意力机制 循环神经网络的一个主要局限是不能很好地建模长距离依赖&#xff0c;即使像长短期记忆这样的变体也只是改善而不是完全解决了长距离依赖的问题。其根本原因在于&#xff0c;如果序列中的第i个词需要对第j个词(假设j>i)产生影响&#xff0c;需…

024、架构_资源_主机

摘要 在主机管理界面,可查看 GoldenDB 使用的主机信息,可对主机执行新增、编辑、删除操作。 主机列表 选择菜单[资源管理→主机管理],进入主机列表界面。 新增主机(单个、批量) 新增主机流程: 添加

Gradio学习——图像流输出

对于在后端实时获取的视频帧&#xff0c;经过图像处理函数处理后&#xff0c;需要不停的返回给前端。由于不是固定的视频&#xff0c;无法用gr.Video()方法&#xff0c;那利用gradio应该怎么处理&#xff1f;方法如下&#xff1a; import gradio as gr import time import cv2…

CS224W—07 Machine Learning with Heterogeneous Graphs

CS224W—07 Machine Learning with Heterogeneous Graphs 本节中&#xff0c;我们将学习如何在异构图中进行图神经网络学习。 Heterogeneous Graphs 图中的节点类型/边类型不同&#xff0c;就会形成一个异构图&#xff08;Heterogeneous Graph&#xff09;&#xff0c;例如下…

情侣日记2.0.0_多种姿势卡_增进情侣感情必备工具

一款专门为情侣互动、增进感情而开发的一款软件&#xff1b;乐趣激情的游戏互动让你和ta的感情快速升温、拉近彼此的距离&#xff1b;恋爱话术技巧、享受甜蜜热恋&#xff1b;真心话大冒险、激情骰子、情侣飞行棋&#xff0c;享受生活小情趣&#xff01; 链接&#xff1a;http…

TensorFlow创建回归神经网络及Optimizer优化器

一.TensorFlow创建神经层 如图所示&#xff0c;通过该神经网络识别动物猫或狗&#xff0c;共包括输入层&#xff08;Input Layer&#xff09;、隐藏层3层&#xff08;Hidden Layer&#xff09;和输出层&#xff08;Output Layer&#xff09;。其中每个隐藏层神经元都有一个激励…

开学季儿童护眼台灯怎么选择?盘点央视公布十大护眼灯!

随着年级的升高和学习内容的增加&#xff0c;学生的休闲娱乐时间逐渐减少&#xff0c;相反&#xff0c;他们在书桌前度过的时间却越来越多。近年来&#xff0c;由于电子产品的广泛使用&#xff0c;我国青少年的用眼负担显著增加。据权威机构预测&#xff0c;到2050年&#xff0…

windows下安装docker操作步骤

因为最近dockerb被封&#xff0c;下载资源太不方便了&#xff0c;所以还是自己本地安装上docker吧 下载的地址一定不要找错&#xff0c;是这里 https://docs.docker.com/desktop/install/windows-install/ 电脑--“控制面板”--“程序与功能”--开启windows功能 “Hyper-V”…

实战docker第一天——windows安装docker,测试,并解决被墙办法

Docker 是一个开源的容器化平台&#xff0c;它允许开发者将应用程序及其所有依赖项打包在一个名为“容器”的单独环境中&#xff0c;从而确保应用程序在任何环境下都能一致地运行。以下是 Docker 的一些核心概念及其意义&#xff1a; 容器化&#xff1a;Docker 通过将应用程序及…

vrrp协议,主备路由器的选举

当VRRP备份组中的所有备份路由器&#xff08;BACKUP&#xff09;具有相同的优先级时&#xff0c;选举新的主路由器&#xff08;MASTER&#xff09;的过程将基于以下规则&#xff1a; IP地址优先&#xff1a;如果备份路由器的优先级相同&#xff0c;那么具有最高IP地址的路由器…

鱼哥好书分享活动第30期:一本书看完教你学习如何做B端竞品分析?《有效竞品分享》

鱼哥好书分享活动第30期&#xff1a;一本书看完教你学习如何做B端竞品分析&#xff1f;《有效竞品分享》 01 明确目标&#xff1a;案例分享&#xff1a;案例背景&#xff1a; 02 选择竞品&#xff1a;2.1 竞品的分类2.2 如何找到B端的竞品&#xff1f;1.找售前/销售沟通。2.各个…

C#护照查验接口集成示例、护照文字识别、外国人身份认证

护照查验是对护照有效性、真实性和符合相关出入境要求的确认过程。护照作为跨国旅行的重要身份证明文件&#xff0c;其查验是国际旅行中的一个必要程序。护照查验接口&#xff0c;支持查验出入境管理局签发护照的真伪&#xff0c;接口集成&#xff0c;简单高效便捷。 C#护照查验…

闲置物品|基于SprinBoot+vue的校园闲置物品交易平台(源码+数据库+文档)

校园闲置物品交易平台 目录 基于SprinBootvue的校园闲置物品交易平台 一、前言 二、系统设计 三、系统功能设计 5.1系统功能实现 5.2管理员模块实现 5.3用户模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xf…

Vue59 github案例 vue-resource版本

代码 List.vue <template><div class"row"><!-- 展示用户列表 --><div v-show"info.users.length" class"card" v-for"user in info.users" :key"user.login"><a :href"user.html_url&qu…

uniapp 生成H5 返回上一页 事件不执行

uniapp 生成H5 返回上一页事件不执行 背景&#xff1a;想根据返回的页面判断是否再返回一页 解决办法&#xff1a;uniapp&#xff0c;H5是先执行方法再返回&#xff0c;所以给事件增加延迟调用&#xff0c;如下代码 // 监听返回 onBackPress(e) {let pages getCurrentPages(…

数据结构(6.4_3)最短路径问题_Dijkstra算法

BFS的局限性 Dijkstra算法 1、 2、 3、 4、 如何使用数组信息 Dijkstra算法的时间复杂度 对比&#xff1a;Prim算法的实现思想 用于负权值带权图