文章目录
一.结构体
在实际问题中,一组数据往往具有不同的数据类型。
例如,在学生登记表中,姓名应为字符型;年龄应为整型;性别应为字符型。显然不能用一个数组来存放这一组数据。因为数组中各元素的类型和长度都必须一致,以便于编译系统处理。为了解决这个问题,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));