【C语言】—— 自定义类型(结构体、枚举、联合)(2)

简介: 【C语言】—— 自定义类型(结构体、枚举、联合)(2)

三、修改默认对齐数

对齐数也是可以被修改的,利用到#pragma 这个预处理指令;

未修改前的结构体大小:

#include <stdio.h>
struct S1
{
  char c1;
  int i;
  char c2;
};
int main()
{
  printf("%d\n", sizeof(struct S1));
  return 0;
}

1ecd1b2606ed46e9956a89f231c9802c.png

修改后的:

#include <stdio.h>
#pragma pack(1)//设置默认对齐数为1
struct S1
{
  char c1;
  int i;
  char c2;
};
int main()
{
  printf("S1所占字节数:%d\n", sizeof(struct S1));
  return 0;
}
#pragma pack()//取消设置的默认对齐数,还原为默认

1ecd1b2606ed46e9956a89f231c9802c.png

四、结构体的传参

#include <stdio.h>
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;
}

上面两个代码print1传的是结构体,print2传的是结构体的地址 ,我们要首选print2这种传参方式;


原因:


       函数传参的时候,参数是需要压栈,(这里可以去查看我之前的博客,函数栈帧的创建和销毁https://blog.csdn.net/sjsjnsjnn/article/details/122811828?spm=1001.2014.3001.5502)会有时间和空间上的系统开销。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降

五、结构体成员的访问

1. 结构变量的成员是通过点操作符(.)访问的:结构体变量.成员变量

2. 结构体指针访问指向变量的成员,结构体指针->成员变量名

#include <stdio.h>
struct Stu
{
  char name[10];//学生的姓名
  int age;//学生的年龄
  char sex[10];//学生的性别
  char id[15];//学生的学号
};
int main()
{
  struct Stu stu = { "zhangsan",20,"male","10001" };
  struct Stu* p = &stu;
  //点操作符访问成员
  printf("name=%s age=%d sex=%s id=%s\n", stu.name, stu.age, stu.sex, stu.id);
  //指针访问成员
  printf("name=%s age=%d sex=%s id=%s\n", p->name, p->age, p->sex, p->id);
    //通过解引用相当于得到了stu,所有用点操作符
  printf("name=%s age=%d sex=%s id=%s\n", (*p).name, (*p).age, (*p).sex, (*p).id);
  return 0;
}

1ecd1b2606ed46e9956a89f231c9802c.png

六、总结

       对于结构体这一章节,比较重要的是内存对齐的规则和结构体传参,掌握了这些基本的用法,相信对于结构体的使用,不是很困难。

目录
相关文章
|
8天前
|
存储 C语言
C语言程序设计核心详解 第九章 结构体与链表概要详解
本文档详细介绍了C语言中的结构体与链表。首先,讲解了结构体的定义、初始化及使用方法,并演示了如何通过不同方式定义结构体变量。接着,介绍了指向结构体的指针及其应用,包括结构体变量和结构体数组的指针操作。随后,概述了链表的概念与定义,解释了链表的基本操作如动态分配、插入和删除。最后,简述了共用体类型及其变量定义与引用方法。通过本文档,读者可以全面了解结构体与链表的基础知识及实际应用技巧。
|
13天前
|
C语言
c语言中的结构体
本文档详细介绍了C语言中结构体的使用方法,包括结构体的基本定义、变量声明与赋值、数组与指针的应用,以及结构体嵌套、与`typedef`结合使用等内容。通过示例代码展示了如何操作结构体成员,并解释了内存对齐的概念。
|
19天前
|
C语言
C语言结构体赋值的四种方式
本文总结了C语言结构体的四种赋值方式,并通过示例代码和编译运行结果展示了每种方式的特点和效果。
27 6
|
29天前
|
编译器 程序员 Linux
【C语言篇】结构体和位段详细介绍
跟结构相⽐,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。
|
29天前
|
存储 编译器 C语言
【C语言篇】自定义类型:联合体和枚举详细介绍
像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。
|
1月前
|
存储 C语言
C语言------结构体和共用体
这篇文章是关于C语言中结构体和共用体的实训,通过示例代码演示了结构体的定义、赋值、使用,以及如何使用结构体变量进行数据的组织和操作,包括输入、排序、求平均分和查找学生信息等功能。
C语言------结构体和共用体
|
5天前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
|
8天前
|
存储 C语言
C语言程序设计核心详解 第十章:位运算和c语言文件操作详解_文件操作函数
本文详细介绍了C语言中的位运算和文件操作。位运算包括按位与、或、异或、取反、左移和右移等六种运算符及其复合赋值运算符,每种运算符的功能和应用场景都有具体说明。文件操作部分则涵盖了文件的概念、分类、文件类型指针、文件的打开与关闭、读写操作及当前读写位置的调整等内容,提供了丰富的示例帮助理解。通过对本文的学习,读者可以全面掌握C语言中的位运算和文件处理技术。
|
8天前
|
存储 C语言
C语言程序设计核心详解 第七章 函数和预编译命令
本章介绍C语言中的函数定义与使用,以及预编译命令。主要内容包括函数的定义格式、调用方式和示例分析。C程序结构分为`main()`单框架或多子函数框架。函数不能嵌套定义但可互相调用。变量具有类型、作用范围和存储类别三种属性,其中作用范围分为局部和全局。预编译命令包括文件包含和宏定义,宏定义分为无参和带参两种形式。此外,还介绍了变量的存储类别及其特点。通过实例详细解析了函数调用过程及宏定义的应用。
|
13天前
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。