C语言之结构体

本文详细介绍了C语言中的结构体类型,包括如何声明结构、初始化结构变量、访问结构成员、使用结构指针以及结构体在函数中的应用。通过实例展示了结构体在组合复杂数据类型时的灵活性,并探讨了结构体数组、结构体中的结构以及typedef在定义自定义数据类型中的作用。
摘要由CSDN通过智能技术生成

[TOC]文章目录

目录

前言

结构体类型

声明结构类型

声明结构的形式

结构变量

结构的初始化

结构成员

结构运算

结构指针

结构体与函数

结构作为函数参数

结构体与指针

指向结构的指针

结构体数组

结构数组

结构中的结构

起别名typedef

自定义数据类型 typedef

Typedef


前言

本篇是有关C语言结构体的知识点总结。

结构体类型

在程序里面想表达一个数据就需要一个变量,而每个变量都需要有一个类型。如果想表达的数据比较复杂,它不是一个值,比如说一个日期有年月日三个值,时间有时分秒三个值,但我们希望用一个整体去表达这么多结合在一起的数据,这时我们就可以应用到  结构。一个结构就是一个复合的数据类型,里面可以有各种类型的成员,用一个变量来表达那么多的数据。

声明结构类型

#include<stdio.h>

int main(int argc,char const *argv[])
{
    struct date{
        int year;
        int day;
        int month;
    };   //这里的分号不能忘记!
    struct date today;
    today.year = 2022;
    today.day = 09;
    today.month = 23;

    printf("Today is %i-%i-%i.\n",today.year,today.month,today.day);
    return 0;
}

上面的结构类型声明在了函数里面。和本地变量一样,在函数内部声明的结构类型只能在函数内部使用。所以通常在函数外部声明结构类型,这样就可以被多个函数所使用了。如:

#include<stdio.h>

struct date{
    int year;
    int day;
    int month;
};  //声明结构类型。之后可以定义许多结构变量,每个结构变量都按照它声明的样子。

int main(int argc,char const *argv[])
{
    struct date today;   //定义这种结构类型的变量
    today.year = 2022;
    today.day = 23;
    today.month = 09;    

    printf("Today is %i-%i-%i.\n",today.year,today.month.today.day);
    return 0;
}

声明结构的形式

1)

struct point{

      int x;

      int y;

};

struct point p1,p2;  //p1和p2都是point里面有x和y的值

2)

struct{

      int x;

       int y;

}p1,p2;  //p1和p2都是一种无名结构,里面有x和y

3)

struct point{

       int x;

       int y;

}p1,p2;    //p1和p2都是point里面有x和y的值

对于第一和第三种形式,都声明了结构point,但是第二种形式没有声明point,只是定义了两个变量。

结构变量

在上面所举的例子中,结构变量是指:

struct date today;    /*today就是结构的变量。在声明时所声明的struct date结构中成员变量,可以 today.year = 2022;                        通过某些方式去访问它*/

today.day = 23;

today.month = 09;

因此我们认为today里面有year,day,month这三个int类型

结构的初始化

放在函数内部的变量叫做本地变量,本地变量是没有默认的初始值的,如果不给它初始值,它就会是一些乱七八糟的值。结构用大括号来赋初值。

#include<stdio.h>

struct date {
    int year;
    int day;
    int month;
};

int main(int argc,char const *argv[])
{
    struct date taday={2022,23,09}; //第一种方式
    struct date thismonth={.month=9,.year=2022};  //第二种方式。day的值为0

    printf("Today is %i-%i-%i.\n",today.year,today.month,today.day);
    printf("This month is %i-%i-%i.\n",thismonth.year,thismonth.month,thismonth.day);
    return 0;
}

结构成员

声明结构类型的时候,结构类型里可以给出一些它的成员,叫做成员变量。从某种角度看,结构和数组有点像,数组里面有很多的单元,结构里面有很多的成员,但不一样的是,数组的单元必须是相同类型的,而结构的成员可以是不同类型的。

数组用[ ]运算符和下标访问其单元:     a[0]=10;

结构用  . 运算符和名字访问其成员:today.day ;student.firstName ; p1.x ; p1.y

我们有结构类型,有结构变量。结构类型是虚的,不是实体。声明了一个结构类型只是告诉编译器所有这种类型的变量的样子,但是结构类型没有东西,所以  .的左边一定是一个变量,结构变量才是实体。

结构运算

要访问整个结构,直接用结构变量的名字。对于整个结构,可以做赋值、取地址,也可以传递给函数参数。

p1=(struct point){5,10};  //相当于p1.x=5;p1.y=10;

p1=p2;   //相当于p1.x=p2.x;p1.y=p2.y;

数组无法做上述的两种运算

#include<stdio.h>

struct date{
    int year;
    int day;
    nit month;
};

int main(int argc,cchar const *argv[])
{
    struct date today;
    today=(struct date){2022,23,09};
    struct date day;
    day=today;   //本次赋值day得到了today的所有成员的值
    day.year=2021;
    printf(Today's date is %i-%i-%i.\n",today.year,today.month,today.day);
    printf(The day's date is %i-%i-%i.\n",day.year,day.month,day.day);
    return 0;
}
输出:
Today's date is 2022-09-23.
The day's date is 2021-09-23

这证明day和today是完全不同的两个结构的变量,它们有各自自己的值。

结构指针

和数组不同,结构变量的名字并不是结构变量的地址,必须使用&运算符。如:

struct date *pDate = &today;

结构体与函数

结构作为函数参数

int numberOfDays(struct date d)   //很明显这个函数的参数就是一个结构变量

所以整个结构可以作为参数的值传入函数,这时候是在函数内新建一个结构变量,并复制调用者的结构的值,也可以返回一个结构。这些与数组完全不同。

结构体与指针

如果将一个大的结构传递给一个函数,通常传递一个指针比复制整个结构更有效。

指向结构的指针

struct date{
    int year;
    int day;
    int month;
}myday;

struct date *p=&myday;
(*p).month=09;
p->month=09;  //人们用更简单的方式:用 -> 表示指针所指的结构变量中的成员

结构体数组

结构数组

struct date dates[100];

stryct date dates[]={

       {4,5,2005},{2,4,2005}};  //当我们去初始化它的时候,就要多一层括号。最外面的那一层括号表示要初始化一个数组,里面的每一层大括号表示每个单元的值。里面的第一个大括号表示dates[0]的值。

结构中的结构

sruct dateAndTime{

struct date sdate;

struct time stime;

};    // 第一个成员变量是一个date,第二个成员变量是一个time。

嵌套的结构

struct point{
    int x;
    int y;
};
struct rectangle{
    struct point pt1;
    struct point pt2;
};

如果有变量: struct rectangle r;

就可以有:r.pt1.x、r.pt1.y、r.pt2.x和 r.pt2.y

如果有变量定义:

struct rectangle r,*rp;

rp=&r;

那么下面的四种形式是等价的:

r.pt1.x <=> rp->pt1.x <=> (r.pt1).x <=> (rp->pt1).x

但是没有rp->pt1->x,因为pt1不是指针。

起别名typedef

自定义数据类型 typedef

C语言提供了一个叫做 typedef 的功能来声明一个已有的数据类型的新名字。比如:

typedef int Length;

使得Length成为int类型的别名。这样,Length这个名字就可以代替int出现在变量定义和参数声明的地方了:

Length a,b,len;

Length numbers[10];

Typedef

声明新的类型的名字。新的名字是某种类型的别名。

改善了程序的可读性

typedef long int64_t;
typedef struct ADate{
   int month;
   int day;
   int year;
} Date;

int64_t i=1000000000000;
Date d={9,1,2005};

typedef 后面的第一个东西是原来的实际的数据类型,而第二个东西是我们给它起的新名字。

在上面代码中,在typedef与Date中间的所有东西是它原来的类型,今后直接用Date的意思就相当于struct ADate。

typedef int Length;  //Length就等价于int类型

typedef *char[10] Strings;  //Strings是10个字符串的数组的类型

typedef struct node{

     int data;

     struct node *next;

} aNode;

typedef struct node aNode;  //这样用aNode就可以代替struct node。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值