C learning_15 结构体类型的声明、结构体初始化、结构体成员访问、结构体传参

简介: C learning_15 结构体类型的声明、结构体初始化、结构体成员访问、结构体传参

结构体类型的声明


结构的基础知识


       结构是一种复合数据类型,它允许将不同类型的数据组合在一起形成一个新的自定义类型。结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。


数组:一组相同类型的元素集合

结构体:一组奴役的相同类型元素的集合


结构的声明


struct tag

{

       member-list;//成员列表

}variable-list;//变量列表

//描述一个学生 - 声明一个结构体类型
struct Stu
{
  //成员变量,是用来描述结构体对象的相关属性的
  char name[20];
  int age;
  char sex[3];//汉字占两个字节
};


结构成员的类型


结构的成员可以是标量、数组、指针,甚至是其他结构体。


结构体初始化


结构体变量的定义和初始化

//描述一个学生 - 声明一个结构体类型
struct Stu
{
  //成员变量,是用来描述结构体对象的相关属性的
  char name[20];
  int age;
  char sex[3];//汉字占两个字节
}p1;//全局变量 - 声明类型的同时定义变量p1
int main()
{
  struct Stu p2;//局部变量 - //定义结构体变量p2
  //初始化:定义变量的同时赋初值
  struct Stu p3 = { "zhangsan",20,"男" };
}

  这段代码定义了一个名为 `Stu` 的结构体类型,它有三个成员变量:`name`、`age` 和 `sex`,用于描述一个学生对象的相关属性。


       接着,定义了一个全局变量 `p1`,它是 `Stu` 类型的变量,这里在声明结构体类型的同时定义了变量 `p1`。

       `main` 函数中,定义了一个局部变量 `p2`,它也是 `Stu` 类型的变量。

       在定义变量的同时,可以使用结构体初始化语法来为结构体的成员变量赋初值。例如,`p3` 变量的初始化语法为 `{ "zhangsan",20,"男" }`,它依次初始化了 `name`、`age` 和 `sex` 三个成员变量的初始值。


结构体的嵌套初始化

struct Point
{
  int x;
  int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//初始化:定义变量的同时赋初值。
struct Point p3 = { 1,2 };
struct Stu        //类型声明
{
  char name[15];//名字
  int age;      //年龄
};
struct Stu s = { "zhangsan", 20 };//初始化
struct Node
{
  int data;
  struct Point p;
  struct Node* next;
}n1 = { 10, {4,5}, NULL }; //结构体嵌套初始化
struct Node n2 = { 20, {5, 6}, NULL };//结构体嵌套初始化
//不按照顺序初始化
struct Node n3 = { .next = NULL,.data = 18,.p.x = 1,.p.y = 2 };


结构体成员访问


#include<stdio.h>
struct Stu
{
    char name[20];
    int age;
};
void print(struct Stu* ps)
{
    //使用.操作符访问
    printf("name = %s   age = %d\n", (*ps).name, (*ps).age);
    //使用->操作符访问
    //使用结构体指针访问指向对象的成员
    printf("name = %s   age = %d\n", ps->name, ps->age);
}
int main()
{
    struct Stu s = { "zhangsan", 20 };
    print(&s);//结构体地址传参
    return 0;
}

 这段代码定义了一个结构体 `Stu`,包含了字符串类型的姓名和整型的年龄。接下来定义了一个名为 `print` 的函数,它的参数是一个指向结构体 `Stu` 的指针 `ps`。


       在函数中,首先使用 `.` 操作符访问结构体指针 `ps` 指向的对象的成员变量 `name` 和 `age`,并使用 `printf` 函数输出这两个变量的值。其中要使用 `(*ps)` 操作符来访问指针所指向的结构体变量的成员。


       接下来,使用 `->` 操作符访问结构体指针 `ps` 指向的对象的成员变量 `name` 和 `age`,并使用 `printf` 函数输出这两个变量的值。由于 `ps` 已经是一个指向结构体 `Stu` 的指针,因此可以直接使用 `ps->name` 和 `ps->age` 来访问结构体中的成员变量。


       在 `main` 函数中,定义了一个结构体变量 `s`,并初始化了它的姓名和年龄。接着调用 `print` 函数,并将指向 `s` 的地址作为参数传递给它。最后返回 0。


结构体传参


struct S
{
 int data[1000];
 int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{
 printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
 printf("%d\n", ps->num);
}
int main()
{
 print1(s);  //传结构体
 print2(&s); //传地址
 return 0;
}


 这段代码定义了一个结构体 `S`,其中包含一个长度为1000的整型数组和一个表示数组元素个数的整型变量 `num`。接下来定义了两个函数 `print1` 和 `print2`,用于输出结构体变量 `s` 中的成员变量 `num`。


       在 `main` 函数中,定义了结构体变量 `s`,并初始化了它的数据和元素个数。接着调用了 `print1` 函数和 `print2` 函数,分别传递了结构体变量 `s` 和它的地址 `&s` 作为参数。最后返回 0。


       `print1` 函数使用了结构体传参的方式,将整个结构体变量 `s` 拷贝到函数的栈空间中。这种方式的好处是在函数执行时,对结构体的修改不会影响到原结构体变量的值,因此更加安全。但是缺点是在函数调用时需要进行结构体的拷贝,函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。


       `print2` 函数使用了结构体指针的方式,将结构体变量 `s` 的地址作为参数传递给了函数。这种方式的好处是在函数执行时,如果需要修改结构体的值,可以直接通过指针来访问结构体的成员变量,不需要进行结构体的拷贝操作,同时由于指针变量的空间大小是4/8个字节,对系统的开销较小。


结论: 结构体传参的时候,要传结构体的地址。

相关文章
|
自然语言处理 安全 C++
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
【C++ 格式化输出 】C++20 现代C++格式化:拥抱std--format简化你的代码
10899 4
|
存储 SQL 负载均衡
列式存储引擎分析比对
列式存储具有高压缩率、利于列裁剪、以及高CPU计算效率(Cache Friendly)等特点,是分析型业务场景所选择的主流数据存储方案。 本文介绍了工业界一些常见的面向OLAP或HTAP场景数据库的列存存储引擎设计思路,并进行了总结和对比。
4184 3
|
存储 算法 NoSQL
6 种常见分布式唯一ID生成策略及它们的优缺点对比
全局唯一的 ID 几乎是所有系统都会遇到的刚需。这个 id 在搜索, 存储数据, 加快检索速度 等等很多方面都有着重要的意义
6 种常见分布式唯一ID生成策略及它们的优缺点对比
|
6月前
|
数据可视化 BI
利用可视化方法优化年终述职:职场人如何让汇报效率提升200%?
本教程教你用可视化思维打造高效述职报告:通过四大模块(成果全景、KPI仪表盘、能力雷达、未来规划)和五步法(数据整理、工具选择、设计原则、结构优化、演讲技巧),结合看板工具实操,将零散工作转化为直观图表,让成果清晰可见、价值精准传达,提升专业形象与汇报说服力。
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
795 8
|
存储 Kubernetes Perl
pv和pvc的区别、关系,如何设置使用的步骤
PV(Persistent Volume)和 PVC(Persistent Volume Claim)是 Kubernetes 中用于管理持久化存储的两个关键概念。 PV 是集群中的一个持久化存储资源,它是由集群管理员预先创建和配置的。PV 可以是物理存储设备、存储阵列、网络存储等。PV 有自己的生命周期,并且可以被多个 Pod 共享。 PVC 是 Pod 对 PV 的请求,它用于声明 Pod 对存储的需求。PVC 描述了 Pod 所需的存储容量、访问模式等属性。当创建 PVC 时,Kubernetes 会尝试将其与可用的 PV 进行匹配和绑定。一旦 PVC 成功绑定到 PV,Pod 就可
1891 0
|
数据采集 数据挖掘 数据处理
Pandas实践:南京地铁数据处理分析
Pandas实践:南京地铁数据处理分析
493 2
|
Java Maven 数据库
Annotation Processing Tool自动生成代码
本文介绍了一种利用Java注解处理器(Annotation Processor)自动生成协议接收与发送类接口的方法,显著提升开发效率。注解处理器能在编译阶段扫描并处理特定注解,生成所需Java代码。文中详细展示了如何通过自定义`HttpProto`注解及对应的处理器`ProtoServiceProcessor`,实现在保存协议类后自动生成客户端请求工具和服务端控制器代码。此外,还提供了具体实现步骤、依赖配置及常见问题解决方案,如处理“服务配置文件不正确”错误和Gradle项目的配置方法。此技术特别适用于需要频繁处理协议或数据交互的应用场景。
267 1
|
搜索推荐 数据挖掘 大数据
数据具有无限性、易复制性、非均质性、易腐性和原始性五大特征
数据具有无限性、易复制性、非均质性、易腐性和原始性五大特征
1605 1
|
Linux C语言
C语言 多进程编程(七)信号量
本文档详细介绍了进程间通信中的信号量机制。首先解释了资源竞争、临界资源和临界区的概念,并重点阐述了信号量如何解决这些问题。信号量作为一种协调共享资源访问的机制,包括互斥和同步两方面。文档还详细描述了无名信号量的初始化、等待、释放及销毁等操作,并提供了相应的 C 语言示例代码。此外,还介绍了如何创建信号量集合、初始化信号量以及信号量的操作方法。最后,通过实际示例展示了信号量在进程互斥和同步中的应用,包括如何使用信号量避免资源竞争,并实现了父子进程间的同步输出。附带的 `sem.h` 和 `sem.c` 文件提供了信号量操作的具体实现。