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. 结构体类型与结构体变量的区别:
    结构体类型:不分配内存、不能赋值、存取、运算;
    结构体变量:分配内存、可以赋值、存取、运算
  3. 成员名可以与程序中的变量名相同,不会混淆
  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 枚举类型

枚举将变量的值一一列举出来,即限定了变量的值域。
定义方法:

  1. 先定义枚举类型,再用此类型定义变量:
    enum weekday {sun, mon, tue, wed, thu, fri, sat};
    enum weekday workday, week_end;
  2. 直接定义枚举变量:
    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); 
} 
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值