欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言学习——结构体详解

程序员文章站 2022-05-08 14:38:17
...

C语言学习——结构体详解

1 结构体与结构体变量

1.1 概 述

数据处理经常需引用不同类型的数据组合成数据集合:

C语言学习——结构体详解可定义一个结构类型来描述上述信息。
C语言学习——结构体详解

1.2 结构体与结构体变量

1.2.1 先定义结构类型,再定义结构变量

C语言学习——结构体详解

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结构类型和结构变量同时定义

C语言学习——结构体详解

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. 成员的用法与普通变量相同;
    C语言学习——结构体详解
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 引用结构变量

引用方式一: 结构体变量名.成员名
C语言学习——结构体详解
C语言学习——结构体详解

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 使用结构体指针变量引用成员形式

C语言学习——结构体详解C语言学习——结构体详解

3.1.3 结构体数组的引用

结构体数组的引用可以分为:数组首地址的引用、数组元素的引用、数组元素地址的引用、数组元素成员的引用、数组元素成员地址的引用。

C语言学习——结构体详解
注意:运算符“”的级别低于“.” ,所以“(结构体数组名+下标)”必须加圆括号。由于运算符“&”的级别低于“.” ,所以“&结构体数组名[下标]”和“ &(*(结构体数组名+下标)) ”可以不加圆括号。

3.2 指向结构体数组的指针

1、结构体指针变量可以指向一个结构体数组,这时结构体指针变量的值是整个结构体数组的首地址。
2、结构体指针变量也可指向结构体数组的一个元素,这时结构体指针变量的值是该结构体数组元素的首地址。

设 ps 为指向结构体数组的指针变量,则 ps 也指向该结构体数组的 0 号元素,ps+1 指向1 号元素,ps+i则指向 i 号元素。这与普通数组的情况是一致的。

注意:当使用指针变量来引用所指向的数据时,普通的变量或数组元素是可以直接使用的,而结构体指针变量引用的数据是结构体,不能直接使用,只能使用结构体中的成员。

对指向结构体数组的指针变量赋初值或赋值的格式:
结构体指针变量=&数组名[下标] (指向数组元素)
结构体指针变量=数组名+下标 (指向数组元素)
结构体指针变量=数组名 (指向数组首元素)
C语言学习——结构体详解

【例 】  用指针变量输出结构体数组。 
#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 为以上共用体类型*/ 

C语言学习——结构体详解共用体类型数据特点:
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 )共用体、结构体可以相互嵌套。

C语言学习——结构体详解

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); 
}