从零学习C语言---结构体

简介: 本章介绍C语言的结构体知识。主要内容包含:结构体声明、结构体成员访问、结构体传参。

1、结构体的声明

1.1、结构的基础知识

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

char、short、int、long、long、float、double是内置类型。

比如说,我们想要描述单一的成绩,身高我们直接用int类型就可以搞定了。

但是如果我想要描述人的特征,那这个就有点复杂,因为人包含:身高,性别,电话,名字等等信息。

书包含:书名,作者,定价,书号。

而针对此复杂对象的描述就需要用到结构体。

1.2、结构的声明

struct Peo
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
};

//或者下面的写法

struct Peo
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
}p1,p2;

//p1,p2是使用struct Peo结构体类型创建的2个变量/对象。
//并且p1,p2是全局变量。
//我们常说尽量不要创建全局变量,所以我们在使用struct Peo创建变量时,通常不这样创建。
//我们通常这样创建结构体变量(如下:)


int main()
{   
    struct Peo p1;   //结构体变量的创建
    return 0;
}

1.3、结构成员类型

结构的成员可以是变量,数组,指针,甚至是其它结构体。

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

有了结构体类型,那如何定义变量,其实很简单。

struct Point
{
    int x;
    int y;
}p1;        //全局变量p1 
struct Point p2;      //全局变量p2

int main()
{
    struct Point p3;              //局部变量p3;
    return 0;
}

初始化结构体变量:

#include <stdio.h>

struct Peo
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
};

int main()
{   
    struct Peo p1 = {"张三","12345678912","男",180};
    return 0;
}

那如果是嵌套结构体初始化呢?并且读取值呢?

如下代码:

#include <stdio.h>

struct Peo
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
};

struct St           //新的结构体
{
    struct Peo p;       //嵌套一个结构体变量
    int num;
    float f;
};


int main()
{   
    struct Peo p1 = {"张三","12345678912","男",180};
    struct St s = {
  
  {"里斯","98765432101","女",169},12,3.14f};    //嵌套结构体初始化。
    printf("%s %s %s %d\n", p1.name, p1.tele, p1.sex, p1.high);
    printf("%s %s %s %d %d %f\n", s.p.name,s.p.tele,s.p.sex,s.p.high ,s.num, s.f);
    return 0;
}

输出:

image.png

2、结构体成员的访问

2.1、使用. 操作符来访问结构体成员

此结构是:结构体对象.结构体成员变量,eg:结构体对象.结构体成员变量,eg:(*ps).name

2.2、使用->操作符来访问结构体成员变量

此结构是:结构体指针->结构体成员,eg:ps->name

#include <stdio.h>

struct Peo
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
};

void print(struct Peo* sp)
{
    printf("%s %s %s %d\n", sp->name, sp->tele, sp->sex, sp->high);
}

int main()
{   
    struct Peo p1 = {"张三","12345678912","男",180};
    print1(&p1);
    return 0;
}

3、结构体传参

结构体传参有两种方式:

  • 传结构体对象本身,这样可以使用结构体对象.结构体成员变量的方法进行成员变量读取。
  • 传结构体对象的地址,这样可以使用结构体指针->结构体成员的方法进行成员变量读取。

我们想一想那个方法好呢?

是方法二:传结构体对象的地址好。具体原因:如果我们使用方法一:传结构体本身的话,前面说过,直接传结构体本身,形参知识实参的一份临时拷贝,如果大概这个结构体对象存储的数据非常之庞大时,拿在使用传结构体本身的话,优惠为形参拷贝一份如此庞大的数据,拿着空间和时间上会得不偿失。所以说使用方法二:传结构体对象的地址最好。

函数传参的时候,参数时需要压栈的。

如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。

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

直接上代码:

#include <stdio.h>

struct Peo
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
};

void print1(struct Peo* sp)    
{
    printf("%s %s %s %d\n", sp->name, sp->tele, sp->sex, sp->high);
}

void print2(struct Peo pp)    //pp形参是p1实参的临时拷贝
{
    printf("%s %s %s %d\n", pp.name, pp.tele, pp.sex, pp.high);
}


int main()
{
    struct Peo p1 = { "张三","12345678912","男",180 };
    print1(&p1);     //传入结构体地址
    print2(p1);     //传入结构体本身
    return 0;
}

输出:

image.png

一道练习题(细看)

image.png

image.png

分析:这里的struct S a,*p = &a;,可以拆分为:

  • struct S a;
  • struct S* p = &a; //这里取地址取得是结构体对象a的地址。

而结构体对象a里面又包含了变量a和变量b。

然后下一步:a.a=99; 意识就是结构体对象a调用结构体变量a进行赋值为99。所以结构体变量a的值为99。

然后现在问题就是,想要打印结构体变量a的值。

A选项:就是题目中的形式,可以。

B选项:不行,p.a,这里的.的优先级是比`\`的优先级高的,所以*p.a就变成了,先p.a,在*解引用的过程。因为p指针对象,指针对象只能p->a的形式。所以B选项错误。

C选项:可以

D选项:(p).a,这里括号里面的优先级最高,\p解引用后就是结构体对象a了,然后转化为a.a和A选项一样,所以D选项也可以。

相关文章
TU^
|
5天前
|
编译器 Linux C语言
C语言之结构体
C语言中的结构体是一种用户自定义的数据类型,它允许将不同类型的数据组合在一起,形成一个新的数据类型。
TU^
17 0
|
5天前
|
存储 C语言
C语言的结构体
C语言的结构体
16 0
|
8天前
|
存储 C语言
C语言进阶⑮(自定义类型)(结构体+枚举+联合体)(结构体实现位段)(下)
C语言进阶⑮(自定义类型)(结构体+枚举+联合体)(结构体实现位段)
16 0
|
1天前
|
C语言
【初阶】C语言初识结构体
【初阶】C语言初识结构体
|
1天前
|
编译器 Linux C语言
C语言——结构体
C语言——结构体
8 2
|
4天前
|
存储 程序员 数据处理
C语言中的结构体:深入解析与应用
C语言中的结构体:深入解析与应用
|
4天前
|
存储 编译器 C语言
【C语言】自定义类型 -- -- 结构体、位段、枚举、联合体
【C语言】自定义类型 -- -- 结构体、位段、枚举、联合体
6 0
|
6天前
|
存储 C语言
C语言结构体深度剖析
C语言结构体深度剖析
|
6天前
|
编译器 C语言 C++
c语言:自定义类型——结构体
c语言:自定义类型——结构体
8 0
|
6天前
|
存储 开发框架 编译器
C语言进阶—自定义类型:结构体,枚举,联合
C语言进阶—自定义类型:结构体,枚举,联合