定义和使用结构体变量
自己建立结构体类型
用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体
声明一个结构体类型的一般形式为:
struct 结构体名
{ 成员表列 };
**************************
struct Student{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}
上面这个的结构体类型为 :struct Student
它包括num,name,sex,age,score,addr等不同类型的成员
注:结构体的成员可以是结构体
struct Date{
int month; int day; int year; };
struct Stu {
int num;char name[20];struct Date birthday;
};
定义结构体类型变量
定义结构体类型变量有以下几种方法
-
先声明结构体类型,再定义该类型变量。
声明结构体类型struct Student
struct Student student1,student2;
student1
10001 Zhang Xin 19 Shanghai -
在声明类型的同时定义变量
struct Student
{ int num;
char name[20];
int age;
char addr[30];
} student1,student2;
- 不指定类型名而直接定义结构体类型变量
struct
{ 成员表列 }
变量名表列;
注:
- 结构体类型与结构体变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。
- 结构体类型中的成员名可以与程序中的变量名相同(尽量不要重名),但二者不代表同一对象。
- 对结构体变量中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。
结构体变量的初始化和引用
定义结构体数组一般形式是
① struct 结构体名
{成员表列}
数组名[数组长度];
② 先声明一个结构体类型,然后再用此类型定义结构体数组:
结构体类型 数组名[数组长度];
如:
struct Person leader[3];
直接看例子,就是定义一个学生信息的结构体,然后对他初始化输出
#include <stdio.h>
int main( ){
struct Studen{
long int num;
char name[20];
char sex;
char addr[20];
}
a={10101,"Li Lin",'M',"Beijing"};
printf("NO.:%ld\nname:%s\n sex:%c\naddress:%s\n",
a.num,a.name,a.sex,a.addr);
return 0;
}
NO.:10101
name:Li Lin
sex:M
address:Beijing
下面这些是对上面的补充
a.num=10010; 对
printf(“%s\n”,a); 不对
struct Student b;
b=a; 对
b.num++; 对
scanf(″%ld″,&a.num); 对
printf(″%o″,&a); 对
scanf(“%ld,%s,%c,%s\n”,&a); 错
a.birthday.month=12; 对
a.age=10; b.age=9; 对
sum=a.age+b.age; 对
使用结构体数组
定义结构体数组
还是从例题入手,理论多没意思啊
例:有3个候选人,每个选民只能投票选一人,要求编一个统计选票的程序,先后输入被选人的名字,最后输出各人得票结果。
#include <string.h>
#include <stdio.h>
struct person // 声明结构体类型struct person
{char name[20]; // 候选人姓名
int count; // 候选人得票数
}leader[3]={"Li",0,"Zhang",0,"Fun",0}; // 定义结构体数组并初始化
int main()
{int i,j;
char leader_name[20]; // 定义字符数组
for (i=1;i<=10;i++)
{scanf("%s",leader_name); // 输入所选的候选人姓名
for(j=0;j<3;j++)
if(strcmp(leader_name,leader[j].name)==0) leader[j].count++;
}
printf("\nResoult:\n");
for(i=0;i<3;i++)
printf("%5s:%d\n",leader[i].name,leader[i].count);
return 0;
}
前面设了一个结构体,里面包含name和count,后面leader是数组名3是数组长度
L、Z、S就是三个人的名字,有10个人投票,strcmp是判断两个字符是否i相等,是就为0,不是就为1。
结构体指针
指向结构体变量的指针
指向结构体对象的指针变量既可以指向结构体变量,也可以用来指向结构体数组中的元素。
指针变量的基类型必须与结构体变量的类型相同。例如:
struct Student *pt;
通过指向结构体变量的指针变量输出结构体变量中成员的信息
#include <stdio.h>
#include <string.h>
int main(){
struct student
{long num;
char name[20];
char sex;
float score;
};
struct student stu_1; // 定义struct student类型的变量stu_1
struct student * p; // 定义指向struct student 类型数据的指针变量p
p=&stu_1; // p指向stu_1
stu_1.num=10101; // 对结构体变量的成员赋值
strcpy(stu_1.name,"Li Lin");
stu_1.sex='M';
stu_1.score=89.5;
printf("No.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",
stu_1.num,stu_1.name,stu_1.sex,stu_1.score); // 输出结果
printf("\nNo.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",
(*p).num,(*p).name,(*p).sex, (*p).score);
return 0;
}
可以看到*p也是这个结构体的,p指向同一类型(student类型)的stu_1,下面两种输出方式结果是一样的。*p就是取p存的内容,就是stu_1
指向结构体数组的指针
有3个学生的信息,放在结构体数组中,要求输出全部学生的信息
#include <stdio.h>
struct student
{int num;
char name[20];
char sex;
int age;
};
struct student stu[3]={{10101,"Li Lin",'M',18},
{10102,"Zhang Fun",'M',19},
{10104,"Wang Min",'F',20}}; // 定义结构体数组并初始化
int main(){
struct student *p; //定义指向struct student结构体的数组
printf(" No. Name sex age\n");
for (p=stu;p<stu+3;p++)
printf("%5d %-20s %2c %4d\n",p->num, p->name, p->sex, p->age);
return 0;
}
为了使用方便和直观,C语言允许把(*p).num用p->num来代替
(*p).name等价于p->name
用指针处理链表
什么是链表
链表是一种常见的重要的数据结构
它是动态地进行存储分配的一种结构
链表必须利用指针变量才能实现
建立简单的静态链表
建立一个如图所示的简单链表,它由3个学生数据的结点组成,要求输出各结点中的数据。
#include <stdio.h>
struct student // 声明结构体类型struct student
{int num;
float score;
struct student *next;
};
int main()
{struct student a,b,c,*head,*p; // 定义3个结构体变量作为链表的结点
a.num=10101; a.score=89.5; // 对结点a的num和score成员赋值
b.num=10103; b.score=90; // 对结点b的num和score成员赋值
c.num=10107; c.score=85; // 对结点c的num和score成员赋值
head=&a; // 将结点a的起始地址赋给头指针head
a.next=&b; // 将结点b的起始地址赋给a结点的next成员
b.next=&c; // 将结点c的起始地址赋给a结点的next成员
c.next=NULL; // c结点的next成员不存放其他结点地址
p=head; // 使p也指向a结点
do
{printf("%ld %5.1f\n",p->num,p->score); // 输出p指向的结点的数据
p=p->next; // 使p指向下一结点
}while(p!=NULL); // 输出完c结点后p的值为NULL,循环终止
return 0;
}
共用体类型
有时想用同一段内存单元存放不同类型的变量。
使几个不同的变量共享同一段内存的结构,称为 “共用体”类型的结构。
定义共用体类型变量的一般形式为:
union 共用体名
{ 成员表列
}变量表列;
union Data
{ int i;
char ch;
float f;
};
union Data a,b,c;
“共用体”与“结构体”的定义形式相似,但它们的含义是不同的。
结构体变量所占内存长度是各成员占的内存长度之和,每个成员分别占有其自己的内存单元。而共用体变量所占的内存长度等于最长的成员的长度。
引用共用体变量的方式
只有先定义了共用体变量才能引用它,但应注意,不能引用共用体变量,而只能引用共用体变量中的成员。
例如,前面定义了a,b,c为共用体变量,下面的引用方式是正确的:
a.i a.ch a.f
共用体类型数据的特点
- 同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一个成员,而不是同时存放几个。
- 可以对共用体变量初始化,但初始化表中只能有一个常量。
- 共用体变量中起作用的成员是最后一次被赋值的成员,在对共用体变量中的一个成员赋值后,原有变量存储单元中的值就取代。
- 共用体变量的地址和它的各成员的地址都是同一地址。
- 不能对共用体变量名赋值,也不能企图引用变量名来得到一个值
- 以前的C规定不能把共用体变量作为函数参数,但可以使用指向共用体变量的指针作函数参数。C99允许用共用体变量作为函数参数。
- 共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。
有若干个人员的数据,其中有学生和教师。学生的数据中包括:姓名、号码、性别、职业、班级。教师的数据包括:姓名、号码、性别、职业、职务。要求用同一个表格来处理。
#include <stdio.h>
#include <malloc.h>
#define LEN sizeof(struct student)
struct student
{long num;
float score; struct student *next;
};
int n;
struct student *creat()
{struct student *head;
struct student *p1,*p2;
n=0;
p1=p2=( struct student*) malloc(LEN);
scanf("%ld,%f",&p1->num,&p1->score);
head=NULL;
while(p1->num!=0)
{n=n+1;
if(n==1)head=p1;
else p2->next=p1;
p2=p1;
p1=(struct student*)malloc(LEN);
scanf("%ld,%f",&p1->num,&p1->score);
}
p2->next=NULL;
return(head);
}
void print(struct student *head)
{struct student *p;
printf("\nNow,These %d records are:\n",n);
p=head;
if(head!=NULL)
do
{printf("%ld %5.1f\n",p->num,p->score);
p=p->next;
}while(p!=NULL);
}
int main()
{struct student *head ;
head=creat();
print(head);
return 0;
}
算了我也没懂嘿嘿这个用到再仔细研究吧。
毕竟是小白,从小白视角看可能不会太深,但像我一样的小白应该都能看懂。
这篇博客主要是写给新手的,希望大家都能学懂学好,嘿嘿,写的不好还望大佬勿喷。