零基础玩转C语言—结构体【初阶】

简介: 零基础玩转C语言—结构体【初阶】

【前言】:本章来介绍结构体的部分知识,并不会深入讲解,只是初阶部分,看得懂结构体的逻辑,并且会简单的运用,后期进阶部分还会深入讲解,希望对大家有所帮助

一、结构体的声明

1.1结构的基本知识

结构是一些值的集合,这些值称为成员变量,结构的每一个成员可以是不同类型的变量

这就让我们想起来数组:一组相同类型元素的集合

1.2结构的声明

struct tag             //结构体关键字+名字(根据实际情况自己命名)

{

member-list;        //成员变量的列表(一个或多个)

}variable-list        //变量列表

为什么要出现结构体呢?

当前学习过的类型都是内置类型,eg:char,int,short,double...但是如果我们想要用一个类型来创建一个复杂对象,比如人:继续要名字+性别+年龄+电话+地址+...这时C语言就引进了结构体这个类型来创建复杂对象(对于一个变量,我们首先得有一个类型来创建这个变量,然后再把值存入变量中去)

假如我们要创建学生的变量:

学生类型——>  学生的变量——>   学生的属性信息

代码实现:

#include<stdio.h>
struct Stu
{
  //学生的相关的属性
  char name[20];
  int age;
  char sex[5];
  char tele[12];
}s3,s4;           //这里的s3,s4是变量名
struct Stu s5;     //这样创建全局变量也是可以的
int main()
{
  struct Stu s1;  //注意这里类型是struct Stu(struct是不可以省略的)
  struct Stu s2;
  return 0;
}

上面一个创建了s1,s2,s3,s4,s5五个变量,但是s1,s2是局部变量s3,s4,s5是全局变量

如果我们想要简化变量的类型重命名

typedef struct Stu
{
  //学生的相关的属性
  char name[20];
  int age;
  char sex[5];
  char tele[12];
}Stu;    //Stu是重命名产生的新的类型
int main()
{
  Stu s5;
  return 0;
}

typedef是类型重定义,就是把类型的名字重命名

【注意】上一个代码中s3,s4是变量名,而这个代码中Stu是重命名产生的新类型

1.3结构体成员的类型

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

代码演示:我们可以看到结构体成员还是比较丰富的

struct B
{
  char c;
  int i;
};
struct S
{
  char c;
  int num;
  int arr[10];
  double* pd;
  struct B sb;
  struct B* pb;
};
int main()
{
  return 0;
}

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

定义:

全局变量的创建有两种:

(1)直接在结构体声明分号之前的加上变量名;

(2)在结构体声明结束后,跟局部变量创建一样些,但是不写在main函数中

初始化:

(1)按照顺序初始化:跟数组一样用{ },中间根据成员顺序输入进行初始化

(2)指定成员初始化:这样就得加上成员的名称eg:.num=1000,其他没有初始化的部分默认为0

代码演示如下:

struct B
{
  char c;
  int i;
};
struct S
{
  char c;
  int num;
  int arr[10];
  double* pd;
  struct B sb;
  struct B* pb;
}s1;  //s1是全局变量(第一种)
struct S s2;//s2是全局变量(第二种)
int main()
{
  double d = 3.14;
    //按照顺序初始化
  struct S s3 = { 'q',100,{1,2,3},&d,{'a',1},NULL };//局部变量
    //指定成员来初始化
    struct S s4={.num=1000,.arr={1,2,3,4,5}};
  return 0;
}

二、结构体成员的访问

·结构体变量.成员名

·结构体指针->成员名


代码演示:【写一个函数给s存放数据】


#include<string.h>
struct S
{
  char name[20];
  int age;
};
void set_s(struct S* ps) 
{
  (*ps).age = 18;
  strcpy((*ps).name, "zhangsan");//字符串拷贝
  //(*ps).name = "zhangsan";这是错误的,因为name是数组名,数组名是地址常量
}
int main()
{
  struct S s = { 0 };
  //写一个函数给s种存放数据
  set_s(&s);
  return 0;
}

这里要注意两个点:

(1)在name(数组成员)中存放数据的时候,我们不能像age一样直接存放

因为name是数组名,数组名是地址常量,就相当于我们是把张三放到了一个门牌号上,并没有放入房间里,所以我们就用strcpy函数来存放数据

(2)在传参的时候不能直接传个过去,而要把s的地址(&s)传进去:

实参传给形参的时候,实参只是实参的一份临时拷贝,对形参的修改不会影响实参

上面是用结构体变量.成员名这个方法来存放数据的


其实也可以这样:指针直接指向成员名更好理解一点


1. ps->age=18;
2. strcpy(ps->name,"zhangsan");

下面再来【写一个函数打印s中的数据】:这里传参直接传结构体变量s就可以,只是打印不用带回main函数,其实这里传地址也可以,这其实也是更好的选择

struct S
{
  char name[20];
  int age;
};
void print_s(struct S t)
{
  printf("%s %d\n", t.name, t.age);
}
void set_s(struct S* ps)
{
  ps->age = 18;
  strcpy(ps->name, "zhangsan");//字符串拷贝
}
int main()
{
  struct S s = { 0 };
  /*写一个函数给s种存放数据*/
  set_s(&s);
  //写一个函数打印s中的数据
  print_s(s);
  return 0;
}

【总结】:结构体传参的时候,要传结构体的地址

(1)当传参时传的是变量时,我们能做的事就很少,因为形参只是实参是一份临时拷贝,对形参进行操作并不改变实参;但是直接传地址过去,我们能干的就很多

(2)当我们传变量的时候,拷贝一份实参也是需要空间的

而直接传地址,直接对原参数进行操作,不需要多余的空间,大大提高了效率

这次结构体的内容就到此啦,有什么问题欢迎评论区或者私信交流,觉得笔者写的还可以,或者自己有些许收获的,麻烦铁汁们动动小手,给俺来个一键三连,万分感谢 !


目录
相关文章
|
1月前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
142 14
|
1月前
|
存储 编译器 C语言
【C语言】结构体详解 -《探索C语言的 “小宇宙” 》
结构体通过`struct`关键字定义。定义结构体时,需要指定结构体的名称以及结构体内部的成员变量。
173 10
|
2月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
169 13
|
2月前
|
存储 数据建模 程序员
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
|
2月前
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
76 11
|
2月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
62 4
|
3月前
|
存储 C语言
如何在 C 语言中实现结构体的深拷贝
在C语言中实现结构体的深拷贝,需要手动分配内存并逐个复制成员变量,确保新结构体与原结构体完全独立,避免浅拷贝导致的数据共享问题。具体方法包括使用 `malloc` 分配内存和 `memcpy` 或手动赋值。
96 10
|
3月前
|
存储 大数据 编译器
C语言:结构体对齐规则
C语言中,结构体对齐规则是指编译器为了提高数据访问效率,会根据成员变量的类型对结构体中的成员进行内存对齐。通常遵循编译器默认的对齐方式或使用特定的对齐指令来优化结构体布局,以减少内存浪费并提升性能。
|
3月前
|
编译器 C语言
共用体和结构体在 C 语言中的优先级是怎样的
在C语言中,共用体(union)和结构体(struct)的优先级相同,它们都是用户自定义的数据类型,用于组合不同类型的数据。但是,共用体中的所有成员共享同一段内存,而结构体中的成员各自占用独立的内存空间。
|
3月前
|
存储 C语言
C语言:结构体与共用体的区别
C语言中,结构体(struct)和共用体(union)都用于组合不同类型的数据,但使用方式不同。结构体为每个成员分配独立的内存空间,而共用体的所有成员共享同一段内存,节省空间但需谨慎使用。