C语言学习——结构体详解
C语言学习——结构体详解
1 结构体与结构体变量
1.1 概 述
数据处理经常需引用不同类型的数据组合成数据集合:
可定义一个结构类型来描述上述信息。
1.2 结构体与结构体变量
1.2.1 先定义结构类型,再定义结构变量
例
struct person
{
int num;
char name[20];
char sex;
float salary;
};
struct person employee1, employee2;
或采用宏定义
#define PERSON struct person
PERSON
{
int num;
char name[20];
char sex;
float salary;
};
PERSON employee1, employee2;
1.2.2结构类型和结构变量同时定义
1.2.3使用类型关键字typedef
语法:typedef 原类型名 新类型名;
功能:给已经存在的类型命一个新名。
#include "stdio.h"
typedef int INTEGER; /*定义整型的数据类型符为INTEGER */
typedef float REAL; /*定义单精度实型的数据类型符为REAL*/
void main( void )
{
INTEGER n,m; /*相当于int n,m*/
REAL x,y,z; /*相当于float x,y,z;*/
…
}
例 typedef struct person
{
long num;
char name[16];
char sex;
int age;
float score[7];
} PERSON;
PERSON stu1,stu2;
说明:
1、结构体也是一种数据类型
2、typedef 没有创造新数据类型
3、typedef 是定义类型,不能定义变量
1.2.4 说明:
- 结构类型构造了一种新的数据类型,制定了一种特定的内存使用方法
- 结构体类型与结构体变量的区别:
结构体类型:不分配内存、不能赋值、存取、运算;
结构体变量:分配内存、可以赋值、存取、运算 - 成员名可以与程序中的变量名相同,不会混淆
- 成员的用法与普通变量相同;
1.2.5成员也可以是一个结构体变量(嵌套的结构体)
struct date
{
int month;
int day;
int year;
};
struct
{
int num;
char name[20];
char sex;
struct date birthday;
float salary;
} employee1, employee2;
含义:首先定义一个结构体 date,由 month(月)、day(日)、year(年) 三个成员组成。
在定义结构体时并定义变量 employee1 和 employee2 时,其中的成员 birthday 被定义为 date 结构体类型。成员名可与程序中其他变量同名,互不干扰。
1.3 引用结构变量
引用方式一: 结构体变量名.成员名
1.4 结构变量初始化
在定义结构体变量、数组、指针变量时,也可以使用赋初值方式对其进行初始化,但是变量后面的一组数据应该用“{}”括起来,其顺序也应该与结构体中的成员顺序保持一致。
结构体变量初始化。
#include "stdio.h"
void main( void )
{
struct student
{
int no;
char name[20];
char sex;
int age;
char pno[19];
char addr[40];
char tel[20];
}student1={11301,"Merry",'F',19, "340104200601264","hefei","(0551)65106313"};
printf("no=%d,name=%s,sex=%c,age=%d,pno=%s\naddr=%s,tel=%s\n", student1.no,student1.name,student1.sex,student1.age,student1.pno,student1.addr,student1.tel);
}
2 结构体数组
【例 】 定义一个结构体数组。
struct person
{
int num;
char *name;
char sex;
float salary;
} employee[5];
定义了一个结构体数组 employee, 共有 5 个元素,employee[0]~employee[4]。每个数组元素都具有 struct person 的结构体形式。
结构体数组的初始化
与结构体变量的初始化类似,对外部结构体数组或静态结构体数组可以作初始化赋值,只是在对结构体数组初始化时,要将每个元素的数据用“{}”括起来。
【例 】 结构体数组的初始化。
struct person
{
int num;
char *name;
char sex;
float salary;
} employee[5]={ {101,"Petor ","M",2450.50},
{102,"Davie","M",3064.50},
{103," Merry ","F",1986.50},
{104,"Anny","F",2180.50},
{105,"Tom","M",2070.50} };
3 结构体指针
3.1指向结构体变量的指针
3.1.1定义形式
struct 结构体名 *结构体指针名;
例 struct student *p;
p:存放结构体变量在内存的起始地址
3.1.2 使用结构体指针变量引用成员形式
3.1.3 结构体数组的引用
结构体数组的引用可以分为:数组首地址的引用、数组元素的引用、数组元素地址的引用、数组元素成员的引用、数组元素成员地址的引用。
注意:运算符“”的级别低于“.” ,所以“(结构体数组名+下标)”必须加圆括号。由于运算符“&”的级别低于“.” ,所以“&结构体数组名[下标]”和“ &(*(结构体数组名+下标)) ”可以不加圆括号。
3.2 指向结构体数组的指针
1、结构体指针变量可以指向一个结构体数组,这时结构体指针变量的值是整个结构体数组的首地址。
2、结构体指针变量也可指向结构体数组的一个元素,这时结构体指针变量的值是该结构体数组元素的首地址。
设 ps 为指向结构体数组的指针变量,则 ps 也指向该结构体数组的 0 号元素,ps+1 指向1 号元素,ps+i则指向 i 号元素。这与普通数组的情况是一致的。
注意:当使用指针变量来引用所指向的数据时,普通的变量或数组元素是可以直接使用的,而结构体指针变量引用的数据是结构体,不能直接使用,只能使用结构体中的成员。
对指向结构体数组的指针变量赋初值或赋值的格式:
结构体指针变量=&数组名[下标] (指向数组元素)
结构体指针变量=数组名+下标 (指向数组元素)
结构体指针变量=数组名 (指向数组首元素)
【例 】 用指针变量输出结构体数组。
#include "stdio.h"
struct person
{ int num;
char *name;
char sex;
float salary;
}employee[5]={
{101,"Petor",'M',2450.50},
{102,"Davie",'M',3064.50},
{103,"Merry",'F',1986.50},
{104,"Anny",'F',2180.50},
{105,"Tom",'M',2070.50}
};
void main( void )
{
struct person *ps;
printf("No\tName\t\tSex\tSalary\t\n");
for(ps=employee;ps<employee+5;ps++)
printf("%d\t%s\t\t%c\t%f\t\n",ps->num,ps->name,ps->sex,ps->salary);
}
4 共用体(联合体)
union u1 /*共用体名为u1*/
{
char c1[8]; /*该成员占用8 个单元*/
int i2; /*该成员占用2 个单元*/
long l3; /*该成员占用4 个单元*/
}; /*该共用体数据共占用8 个单元*/
共用体每个成员都有确定的数据类型和名称。这些成员将占用相同的内存单元。若成员名前面有“*”,成员是指针型;若成员名后有“[长度]”,成员是数组。定义共用体时,最后的“分号”不能丢。共用体的成员是不分配内存的,只有定义了该共用体的变量、数组、指针变量后,才会给这些变量、数组、指针变量分配内存。共用体名和成员名的命名应符合C语言标识符的规定。
【例7-37 】 共用体变量的说明。
形式一:
union u1
{ char c1[8]; /* 该成员占用8 个单元*/
int i2; /* 该成员占用2 个单元*/
long l3; /* 该成员占用4 个单元*/
};
union u1 a,b; /*说明a,b 为u1类型*/
形式二:
union u1
{ char c1[8]; /* 该成员占用8 个单元*/
int i2; /* 该成员占用2 个单元*/
long l3; /* 该成员占用4 个单元*/
} a,b; /*说明a,b 为u1类型*/
形式三:
union
{ char c1[8]; /* 该成员占用8 个单元*/
int i2; /* 该成员占用2 个单元*/
long l3; /* 该成员占用4 个单元*/
}a,b; /*直接说明a,b 为以上共用体类型*/
共用体类型数据特点:
1 )同一内存段可以用来存放不同类型的成员,但是每一瞬时只能存放其中的一种(也只有一种有意义)。
2 )共用体变量中有意义的成员是最后一次存放的成员。例如:在x.a=1;x.b=3.6;x.c=’H’语句后;当前只有x.c有意义(x.a,x.b 也可以访问,但没有实际意义)。
3 )共用体变量的地址和它的成员的地址都是同一地址。即,&x.a=&x.b=&x.c=&x。
4 )除整体赋值外,不能对共用体变量进行赋值,也不能企图引用共用体变量来得到成员的值。不能在定义共用体变量时对共用体变量进行初始化(系统不清楚是为哪个成员赋初值);
5 )可以将共用体变量作为函数参数,函数也可以返回共用体,共用体指针。
6 )共用体、结构体可以相互嵌套。
5 枚举类型
枚举将变量的值一一列举出来,即限定了变量的值域。
定义方法:
- 先定义枚举类型,再用此类型定义变量:
enum weekday {sun, mon, tue, wed, thu, fri, sat};
enum weekday workday, week_end; - 直接定义枚举变量:
enum weekday {sun, mon, tue, wed, thu, fri, sat}
workday,week_end;
说明:
1.枚举元素为常量
2.枚举元素默认为0、1、2······7
3.可改变枚举元素的默认值:enum weekday { sun=7, mon=1, tue,…};
4.一个整数不能直接赋值给一个枚举变量:
workday= (enum weekday) 2; 或:workday=tue;
#include <stdio.h>
void main( void)
{
struct
{
int nian;
int yue;
int ri;
} x={1984,3,1};
int y[]={0,31,28,31,30,31,30,31,31,30,31,30},i,j,s=0;
for (i=1;i<x.yue;i++)
s+=y[i];
s+=x.ri;
if (x.nian%4==0&&x.nian%100!=0||x.nian%400==0)
s++;
printf("%d\n",s);
}
#include <stdio.h>
struct ks
{
int a;
int *b;
} s[4], *p;
void main(void)
{
int i, n=1;
printf("\n");
for(i=0;i<4;i++)
{
s[i].a=n;
s[i].b=&s[i].a;
n=n+2;
}
p=&s[0];
p++;
printf("%d,%d\n",(++p)->a);
}
上一篇: C语言for循环基础(嵌套循环)打印九九乘法口诀表
下一篇: