[TOC]文章目录
目录
前言
本篇是有关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。