[C语言]结构体

简介: 结构体基础:结构是一些值的集合,这些值被称作是成员之间的变量。结构体 每个成员可以是不同类型变量。 好,那我就先举个代码例子,让大家更容易去了解什么是结构体:

结构体基础:

结构是一些值的集合,这些值被称作是成员之间的变量。结构体 每个成员可以是不同类型变量。

好,那我就先举个代码例子,让大家更容易去了解什么是结构体:

#include<stdio.h>
//描述一个学生
typedef struct student
{
    char name[20];//学生名字
    char sex[5];//学生性别
    char id[20];//学生学号
    short int age;//学生年龄
}student;//注意:对结构体类型进行重命名
int main(void)
{
    student mation =  { "小明", "男", "123456789", 18 };//typedef命名的新名字student
  printf("%s\n", mation.name); 
  printf("%s\n", mation.sex);
  printf("%s\n", mation.id);
  printf("%d\n", mation.age);
    return 0;
}

struct —   结构体的关键字。

student — 结构体的标签,可以随意的替换看你指向的对象是谁了。

struct student —— 叫做结构体类型。

大括号 { } 里面的内容被称作是:成员变量, 注意大括号后面必须要有分号,可以加成员列表,分号前面内容,可以是全局的结构体变量(一般都不会去使用),在代码中我们要尽可能的去少的使用全局变量。

在函数中 mation —— 结构体类型的变量,当然这里我直接 student mation;是可以的,因为我用了typedef关键字,当然这个是可以随意定义结构体标签新的名字,不过我喜欢直接去定义结构体标签。

结构体类型的变量(mation)需要存放结构体类型的成员变量,所以我们可以要给上一个大括号直接去接收这些结构体变量,到了这一步,我们的结构体类型的初始化已经🆗了。注意:结构体类型的成员变量的数据类型使用不要弄错了以及主函数当中的打印的占位符记得要和全局变量一一对应才行。

最后,就是打印了。这里说下xxx.xxx在这个解释下什么意思:xxx.这个是结构体标签,通过这个后面的xxx是结构体当中类型的成员变量,也就是找到那个成员。

以上我讲的这一步骤,是定义:结构体的类型。那么在这里细心的朋友已经发现了,代码中结构体类型前面还加了一个typedef,那在这里我跟大家说下:typedef把结构体类型给重新的起了一个名字,在主函数中大家就可以知道。而,分号前我也写了注释。


typedef作用:

想了想,还是把typedef单独拿出来说一说吧


C 语言提供了 typedef 关键字,你可以使用它来为类型取一个新的名字。


typedef struct Books      ==        Book book              就像这样.


看到这里可能有些人会感觉和#deifne怎么感觉一样,那在这里我说下:


#define 是 C 指令,用于为各种数据类型定义别名,与 typedef 类似,但是它们有以下几点不同:


typedef 仅限于为类型定义符号名称,#define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。


typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。


结构体的作用:

结构体和其他类型基础数据类型一样,例如 int 类型,char 类型 只不过结构体可以做成你想要的数据类型。以方便日后的使用。 


在实际项目中,结构体是大量存在的。研发人员常使用结构体来封装一些属性来组成新的类型。  


结构体在函数中的作用不是简便,其最主要的作用就是封装。封装的好处就是可以再次利用。让使用者不必关心这个是什么,只要根据定义使用就可以了。


结构体的大小与内存对齐:

结构体的大小不是结构体元素单纯相加就行的,因为我们现在主流的计算机使用的都是 32Bit 字长的 CPU,对这类型的 CPU 取 4 个字节的数要比取一个字节要高效,也更方便。所以在结构体中每个成员的首地址都是4的整数倍的话,取数据元素是就会相对更高效,这就是内存对齐的由来。


结构体成员的类型

结构体成员的类型,可以是变量,数组,指针,甚至是其它的结构体,这里就不每个去列举了。


结构体成员

结构体变量的访问成员,是通过操作符(.)访问的。

结构体(套娃‘doge’)

在结构体成员类型中我说了下,但有些小伙伴可能会有点不清楚,在这里我把代码给大家,注意:   在上面结构体我使用了红色字体所标注的.

#include<stdio.h>
//学生家地址
struct address
{
  char T [20];
};
//描述一个学生
typedef struct student  //typedef —— 可以使用它来为类型取一个新的名字
{
  char name[20];    //学生名字
  char sex[5];    //学生性别
  char id[20];    //学生学号
  short int age;    //学生年龄
  struct address S;
}student;       //注意:对结构体类型进行重命名
int main(void)
{
  // struct student mation;// mation —— 结构体类型的变量
  student mation = { "法外狂徒张三", "man", "10086", 18, {"康达小区三懂一单元"} };
  printf("%s\n", mation.name);
  printf("%s\n", mation.sex);
  printf("%s\n", mation.id);
  printf("%d\n", mation.age);
  printf("%s\n", mation.S.T);//注意,由于我们是把一个结构体类型放在另一个结构体,所以这里需要找两次。
  return 0;
}

结构体传参和传值

1.传参

注意,在print函数当中记得定义结构体关键字。

#include<stdio.h>
//描述一个学生
typedef struct student  //typedef —— 可以使用它来为类型取一个新的名字
{
  char name[20];    //学生名字
  char sex[5];    //学生性别
  char id[20];    //学生学号
  short int age;    //学生年龄
}student;       //注意:对结构体类型进行重命名
void print(student tmp)
{
  printf("%s\n", tmp.name);
  printf("%s\n", tmp.sex);
  printf("%s\n", tmp.id);
  printf("%d\n", tmp.age);
}
int main(void)
{
  // struct student mation;// mation —— 结构体类型的变量
  student mation = { "法外狂徒张三", "man", "10086", 18 };
  //实现传参
  print(mation);
  return 0;
}

2.传址

注意:print2函数中打印的,-> (操作符)。在这里tmp2指针箭头指向对象的内容。

#include<stdio.h>
//描述一个学生
typedef struct student  //typedef —— 可以使用它来为类型取一个新的名字
{
  char name[20];    //学生名字
  char sex[5];    //学生性别
  char id[20];    //学生学号
  short int age;    //学生年龄
}student;       //注意:对结构体类型进行重命名
void print2(student *tmp)
{
  printf("%s\n", tmp->name);
  printf("%s\n", tmp->sex);
  printf("%s\n", tmp->id);
  printf("%d\n", tmp->age);
}
int main(void)
{
  // struct student mation;// mation —— 结构体类型的变量
  student mation = { "法外狂徒张三", "man", "10086", 18 };
  //实现传址
  print2(&mation);
  return 0;
}

各位,这两个函数如果要选择一个的话,选择第2个。因为:

传参:如果当我们用实参传递给形参的话,其实就是一份临时拷贝。这样的话就要把所有的数据内存空间给再copy一份下去。放在其它的内存上,在这里我取名为tmp。就很简单就是例如,是200个字节那么你传的参数就也要两百个字节,这就会导致空间的一个浪费就会非常严重滴,同时你copy过去还需要一定的时间。

传址:这里我传过去的仅仅是地址(&),一个地址就是4字节(32位)8个字节(64位),注意这里是int类型的数据类型所以是4个字节以及32个比特位,用三十二位的二进制来进行表达。

如果要选择一种,我们尽可能的去选择传址,因为效率更高些,而且还可以省出一定内存空间,尤其是对大型项目的看法,两种我们就可以去选择传址。


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


目录
相关文章
|
24天前
|
存储 C语言
如何在 C 语言中实现结构体的深拷贝
在C语言中实现结构体的深拷贝,需要手动分配内存并逐个复制成员变量,确保新结构体与原结构体完全独立,避免浅拷贝导致的数据共享问题。具体方法包括使用 `malloc` 分配内存和 `memcpy` 或手动赋值。
30 10
|
23天前
|
存储 大数据 编译器
C语言:结构体对齐规则
C语言中,结构体对齐规则是指编译器为了提高数据访问效率,会根据成员变量的类型对结构体中的成员进行内存对齐。通常遵循编译器默认的对齐方式或使用特定的对齐指令来优化结构体布局,以减少内存浪费并提升性能。
|
28天前
|
编译器 C语言
共用体和结构体在 C 语言中的优先级是怎样的
在C语言中,共用体(union)和结构体(struct)的优先级相同,它们都是用户自定义的数据类型,用于组合不同类型的数据。但是,共用体中的所有成员共享同一段内存,而结构体中的成员各自占用独立的内存空间。
|
28天前
|
存储 C语言
C语言:结构体与共用体的区别
C语言中,结构体(struct)和共用体(union)都用于组合不同类型的数据,但使用方式不同。结构体为每个成员分配独立的内存空间,而共用体的所有成员共享同一段内存,节省空间但需谨慎使用。
|
1月前
|
编译器 C语言 C++
C语言结构体
C语言结构体
25 5
|
1月前
|
C语言
C语言结构体链式结构之有头单链表
文章提供了一个C语言实现的有头单链表的完整代码,包括创建链表、插入、删除和打印等基本操作。
22 1
|
1月前
|
C语言
初识C语言6——结构体
初识C语言6——结构体
18 3
|
1月前
|
存储 编译器 C语言
【C语言】探索结构体基础知识:简明概要
【C语言】探索结构体基础知识:简明概要
|
1月前
|
编译器 Linux C语言
C语言 之 结构体超详细总结
C语言 之 结构体超详细总结
19 0
|
1月前
|
存储 编译器 Linux
深入C语言:探索结构体的奥秘
深入C语言:探索结构体的奥秘