结构体的定义以及初始化,结构体成员的两种访问方式,结构体传参

本文详细介绍了C语言中的结构体,包括其类型声明、初始化方法、成员访问操作符以及在函数参数中的应用,强调了结构体在处理不同类型数据组合上的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第8章,C语言之结构体


目录

前言

一、结构体类型声明

二、结构体的初始化

三、结构体的成员访问

四、结构体传参

总结


前言

C语言的是一个面向过程编程的思想,就不能像其他面向对象编程思想那样方便。面向对象重要的就是对象,对象里面包含着各种不同类型的变量以及方法。而在C语言中,从之前学过的知识点来看,就只有数组可以包含很多数据,但是数组的数据类型必须一致。那C语言有没有可以像面向对象中的对象那样,一个对象同时包含不同类型的数据呢?肯定是有的,那就是今天要学习的结构体。


一、结构体类型声明

其实结构体就是一些值的集合,这些值在结构体中被称为成员变量,并且这些成员变量的类型可以不同。不像数组那样,限制了数组的元素的类型必须要一致。

 //结构体声明
 struct tag
 {
     member - list;
 }variable - list;

 tag:结构体的标签,就是结构体的名称。
 member - list:结构体中的成员变量列表,每个变量可以是不同数据类型。
 variable - list:结构体变量名列表,就是用结构体数据类型定义的变量

我们来声明一个学生的结构体:

struct Stu
{
    char name[20];
    int age;
    char sex[5];
};

这是一个学生的结构体,结构体的成员包括学生的姓名、年龄、性别三个主要的信息,如果还有其他的一些信息也可以往结构体中添加。这些都被称为结构体的成员变量。

结构体的成员变量可以是标量、数组、指针以及其他类型的结构体。

二、结构体的初始化

我们既然了解了结构体的声明,我们声明之后,该如何初始化呢?那下面就继续学习结构体的初始化相关的知识点。

    //声明结构体
    struct Stu
    {
        char name[20];
        int age;
        char sex[5];
    }s1;   //s1表示声明结构体的同时定义一个结构体变量

    //定义结构体变量
    struct Stu s2;  //定义一个结构体变量s,不初始化。
    struct Stu s3 = { "zhangsan", 18, "男" }; //定义一个结构体变量s3,并且初始化

    //声明一个结构体,结构体的成员的类型是另一个结构体类型
    struct Person
    {
        int num;
        struct Stu s;
    }p1 = { 15,{"zhangsan" ,25, "男"}};  //声明结构体的同时定义一个结构体变量p1并且初始化

    //定义结构体变量,结构体嵌套初始化
    struct Person p2 = { 100,"lisi",18,"女" }; //这里的struct Stu s成员初始化时可以加{},也可以不用加
    

结构体定义变量的方式有很多种,根据自己喜欢的方式去定义变量。

三、结构体的成员访问

我们学习了结构体变量的定义以及初始化,那我们如何通过结构体变量去访问结构体内的成员呢?

在C语言中,访问结构体成员的方式有两种,一是,通过'.'操作符进行访问,二是通过'->'操作符访问。这个两个操作符也在前面的章节学习过。C语言的所有操作符系列,操作符给操作数找对象-优快云博客

这两个操作符使用的对象不同,一个是使用在结构体变量上,一个是使用在结构体指针变量上。

1、使用‘.’操作符访问结构体成员

struct Stu
{
    char name[20];
    int age;
    char sex[5];
};

struct Stu s1 = { "zhangsan", 18, "男" };

printf("姓名:%s\t年龄:%d\t性别:%s\n",s1.name,s1.age,s1.sex);

2、使用‘->’操作符访问结构体成员

  struct Stu
  {
      char name[20];
      int age;
      char sex[5];
  };

  struct Stu s1 = { "lisi", 20, "男"};
  struct Stu* s = &s1;
  printf("姓名:%s\t年龄:%d\t性别:%s\n", s->name, s->age, s->sex);

四、结构体传参

结构体的基本知识点已经学得差不多了,现在就学习一下结果作为函数参数时如何使用。

struct Stu
{
    char name[20];
    int age;
    char sex[5];
};

void printStruct1(struct Stu s)
{
    printf("姓名:%s\t年龄:%d\t性别:%s\n", s.name, s.age, s.sex);
}

void printStruct2(struct Stu *s)
{
    printf("姓名:%s\t年龄:%d\t性别:%s\n", s->name, s->age, s->sex);
}

int main()
{
    struct Stu s1 = { "wangwu", 16, "男" };
    printStruct1(s1);
    printStruct2(&s1);
    return 0;
}

代码中的printStruct1和printStruct2函数都是打印结构体成员的值,唯一的差别就是函数的形参不一样,一个是传值,一个是传址,那这两个有什么区别呢?

传值调用:把实参的值全部拷贝一份给形参,内存中这时就会有两份一样的数据。

传址调用:把实参的地址传给形参,内存中这时会开辟一个指针变量,指向实参的地址。

函数传参的时候,参数需要压栈,如果一个结构体很大,传值调用时,参数压栈的系统开销比较大,而且也比较占内存,所以会导致系统性能下降。传址调用时,参数压栈只会压栈一个地址,而且内存占用也比较少,因为不管结构体多大,形参都只会在内存中开辟8字节大小的指针来存放实参的地址。

所以在这里建议铁子们,在对结构体传参的时候,尽量使用传址调用。

在这里给铁子们补充一个小小的知识点,结构体可以结合typedef关键字,这样结合使用的时候更加方便。

int main()
{

typedef struct Person
{
    char name[20];
    int age;
}person;


person p1 = { "tom",20 };

printf("%s\t%d\n",p1.name,p1.age);

return 0;
}

typedef关键字的作用就是对数据类型进行重命名。typedef关键字加在结构体前面表示对这个结构体类型重新命名为person,如果后面需要定义这个结构体变量时,就是直接使用person去定义就行了。这样是不是就很方便了。


总结

结构体这章节就结束了,后面会写一篇自定义数据类型的内容,敬请期待。本章学习了结构体如何定义以及初始化,如果是结构体变量和结构体指针变量,我们通过哪两种方式去访问,是不是通过.和->两个操作符去访问。最后一个点就是结构体有不同的方式可以作为函数参数,那哪种方式更好呢。

铁子们一起加油哇~

谢谢铁子们

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值