0数据结构-结构体struct与typedef

一.结构体

在实际问题中,一组数据往往具有不同的数据类型。
例如,在学生登记表中,姓名应为字符型;年龄应为整型;性别应为字符型。显然不能用一个数组来存放这一组数据。因为数组中各元素的类型和长度都必须一致,以便于编译系统处理。为了解决这个问题,C语言中给出了另一种构造数据类型——“结构(structure)”或叫“结构体”。

(一)定义结构与说明结构变量

1.先定义结构

struct stu
{
	int num;
	char name[20];
	char sex;
};//应注意在括号后的分号是不可少的

在这个结构定义中,结构名为 stu,该结构由3个成员组成。
第一个成员为num,整型变量;
第二个成员为name,字符数组;
第三个成员为sex,字符变量;

2.结构定义之后,即可进行变量说明。凡说明为结构stu的变量都由上述3个成员组成:说明了两个变量boy1和boy2为stu结构类型

struct stu boy1,boy2;

在这里也可以用宏定义使一个符号常量来表示一个结构类型。

#define STU struct stu//使用STU代替struct stu
STU
{
	int num;
	char name[20];
	char sex;
};

STU boy1,boy2;

(二)在定义结构类型的同时说明结构变量

struct stu
{
	int num;
	char name[20];
	char sex;
}boy1,boy2;

(三)直接说明结构变量

此方法省去了结构名,而直接给出结构变量

struct
{
	int num;
	char name[20];
	char sex;
}boy1,boy2;

(四)成员也可以又是一个结构,即构成了嵌套的结构

struct date
{
	int month;
	int day;
	int year;
};
struct{
	int num;//学号
	struct date birthday;
}boy1,boy2;

在这里首先定义一个结构date,由month(月)、day(日)、year(年) 三个成员组成。 在定义并说明变量 boy1 和 boy2 时,其中的成员birthday被说明为date结构类型。成员名可与程序中其它变量同名,互不干扰。

(五)结构变量成员的表示方法

boy1.num 即第一个人的学号

如果成员本身又是一个结构则必须逐级找到最低级的成员才能使用。
boy1.birthday.month
即第一个人出生的月份成员可以在程序中单独使用,与普通变量完全相同。

(六)结构数组的定义

struct stu
{
	int num;
	char *name;
	char sex;
	float score;
}boy[5];

定义了一个结构数组boy,共有5个元素,boy[0]~boy[4]。每个数组元素都具有struct stu的结构形式。

对结构数组可以作初始化赋值。当对全部元素作初始化赋值时,也可不给出数组长度。

struct stu
{
	int num;
	char *name;
	char sex;
	float score;
}boy[5]={
	{1,"a","M",1},
	{2,"b","M",1.2},
	{3,"c","F",2.3},
	{4,"d","F",2.4},
	{5,"e","M",2.5};
}

(七)指向结构变量的指针

在前面的例题中定义了stu这个结构,如要说明一个指向stu的指针变量pstu,可写为struct stu *pstu; 当然也可在定义stu结构时同时说明pstu。与前面讨论的各类指针变量相同,结构指针变量也必须要先赋值后才能使用。

赋值是把结构变量的首地址赋予该指针变量,不能把结构名赋予该指针变量。如果boy是被说明为stu类型的结构变量,则:
pstu=&boy是正确的,
pstu=&stu是错误的。
结构名和结构变量是两个不同的概念,不能混淆。结构名只能表示一个结构形式,编译系统并不对它分配内存空间。只有当某变量被说明为这种类型的结构时,才对该变量分配存储空间。
因此上面&stu这种写法是错误的,不可能去取一个结构名的首地址。有了结构指针变量,就能更方便地访问结构变量的各个成员。

其访问的一般形式为:

(*结构指针变量).成员名 即 (*pstu).num
或为:
结构指针变量->成员名 即 pstu->num

应该注意(*pstu)两侧的括号不可少,因为成员符“ . ”的优先级高于" * "。如去掉括号写作pstu.num则等效于(pstu.num),这样,意义就完全不对了。

(八)指向结构数组的指针

指针变量可以指向一个结构数组,这时结构指针变量的值是整个结构数组的首地址。结构指针变量也可指向结构数组的一个元素,这时结构指针变量的值是该结构数组元素的首地址。
设ps为指向结构数组的指针变量,则ps也指向该结构数组的0号元素,ps+1指向1号元素,ps+i则指向i号元素。这与普通数组的情况是一致的。

(九)malloc和free

1.分配内存空间函数malloc
(类型说明符*)malloc(size)

功能:在内存的动态存储区中分配一块长度为"size"字节的连续区域。函数的返回值为该区域的首地址。
“类型说明符”表示把该区域用于何种数据类型。
(类型说明符*)表示把返回值强制转换为该类型指针。
“size”是一个无符号数。

例如:
pc=(char *)malloc(100);
表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。

2.释放内存空间函数free
free(void*ptr);
功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应是由malloc函数所分配的区域。

二.类型定义符typedef

即 为数据类型取“别名”
一般形式为:typedef 原类型名 新类型名
其中原类型名中含有定义部分,新类型名一般用大写表示,以便于区别。
有时也可用宏定义(define)来代替typedef的功能,但是宏定义是由预处理完成的,而typedef则是在编译时完成的,后者更为灵活方便。

【例1】原始定义整型变量a,b

INTEGER a,b;

其中INTEGER为int的完整写法。为了增加程序的可读性,可把整型说明符用typedef定义为int

typedef int INTEGER

以后就可也直接写做

int a,b;

【例2】
例如:

typedef char NAME[20];    

表示NAME是字符数组类型,数组长度为20。

然后可用NAME来说明变量:

NAME a,b;

完全等效于:

char a[20],b[20];

【例3】

typedef struct stu
{ 
	char name[20];
	int age;
	char sex;
} STU;

定义STU表示stu的结构类型,然后可用STU来说明结构变量:

STU a,b;

【例4】

typedef struct stu{
    char name[20];
    int age;
    char sex;
} STU;

STU 是 struct stu 的别名,可以用 STU 定义结构体变量:

STU body1,body2;

它等价于:

struct stu body1, body2;

【例5】

typedef struct LNode {
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;

以上代码等价于

struct LNode {//结点
	ElemType data;
	struct LNode *next;
};
typedef struct LNode LNode;//将struct LNode定义为LNode
typedef struct LNode *LinkList;//将struct LNode *定义为LinkList


LNode *L 等价于 LinkList L

【例6】

struct LNode {
	ElemType data;
	struct LNode *next;
};
struct LNode *p=(struct LNode *)malloc(sizeof(struct LNode));

将struct LNode定义为LNode

typedef struct LNode LNode;

malloc可简化为

LNode *p = (LNode*)malloc(sizeof(LNode));
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡__卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值