Post

结构体

结构体

结构的模型:

  • 1
    2
    3
    4
    5
    6
    7
    
    struct 结构体名
    {
        //[成员列表(member list)/域表(field list)]
        类型名1 成员名1;
        类型名2 成员名3;
              
    }
    
    • 成员可以是其他结构体

定义结构体

    1. 先声明结构体类型,在定义该类型的变量

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      //声明结构体类型
      struct Student
      {
       int num;
       char name[20];
       char sex;
       int age;
       //struct Date birthday;
       chat addr[30];
      }
      struct Student student1,student2;
      
    • Tips:
      • 许多计算机以4个字节为一个“字”,所以,如果在一个“字”中只存放了一个字节,但是该“字”剩下的3个字节不会被占用,而是跳过他们,去到下一个“字”开始存放。
      • 所以这里sizeof(student1)的结果是64,而不是63
      • 这种定义方式的好处:将声明类型定义变量分离开来,可以随时修改
  • 2.在声明类型的同时定义变量

    • 1
      2
      3
      4
      5
      6
      7
      
      struct Student
      {
          int num;
          char name[20];
          char sex;
          int age;
      }student1,student2;
      
  • 3.不指定类型名而直接定义结构体类型变量

    • 1
      2
      3
      4
      5
      6
      7
      8
      
      struct
      {
          int num;
          int num;
          char sex;
          int age;
          /* data */
      }student1,student2;
      
  • Tips:
    • 结构体类型与结构体变量:
      • 类型:定义结构体时用的,不会分配内存;
      • 变量:实例化后的结构体,对其分配对应的空间大小;
    • 结构体的成员名可以和程序中的变量名相同

结构体变量的初始化和引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>

int main(int argc, char const *argv[])
{
//初始化(赋值)
    struct Student
    {
        /* data */
        long int num;
        char name[20];
        char sex;
        char addr[20];
    }a{ 10101,"li min",'m',"123 beijing"};
    //赋值方式一
    
    struct Student b{ .name = "zhang fang"};
    //赋值方式2
    //.name === b.name
    //其他未指定初始化0
    //数值 -> 0
    //字符型 -> '\0`
    //指针型 -> 'NULL`

//引用
//结构体变量名.成员名
// . 是成员运算符 (运算符中最高的优先级) ==> 可以把student1.num看作是一个整体
    return 0;
}

使用结构体数组

  • 定义
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      // 方式1.
      struct 结构体名 
          { 成员列表} 数组名[数组长度];
        
      //方式2
      struct Person{
          ...
      };
      struct Person leader[3];
    
  • 赋值
    1
    2
    3
    
      struct Person leader[3] = { "li",0,"zhang",0,"sun",0};
        
      struct Person leader[3] = { {"li",0},{"zhang",0},{"sun",0}};
    

结构体指针

就是指向结构体变量的指针

  • 一个结构体变量的起始地址 === 结构体变量的指针
指向结构体变量的指针
  • 3种等价方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    struct Student
    {
        long num;
    };
    struct Student stu;
      
    //方法1
    stu.num;
    //方法2
    (*p).num;
    //方法3
    p->num;
    
指向结构体数组的指针
  • 可以用指针变量指向结构体数组的元素

  • p应该指向结构体类型,而不是结构体数组元素中的成员

  • 如果非要,先将成员的地址转换成p的类型

    1
    
    p = (struct Student*)stu[0].name;
    

结构体变量和结构体变量的指针作为函数参数

用指针处理链表

共用体类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
struct 
{
    int num;
    char name[10];
    char sex;
    char job;
    union 
    {
        int class;
        char position[10];    
    }category;
}person[2];
//定义结构体数组person,有两个元素
int main(int argc, char const *argv[])
{
    int i; 
    for(i=0;i<2;i++)
    {
        printf("please enter the date of person: \n");
        scanf("%d %s %c %c",&person[i].num, 
                        &person[i].name, 
                        &person[i].sex,
                        &person[i].job);
        if(person[i].job=='s') scanf("%d",&person[i].category.class);
        else if(person[i].job == 't') scanf("%s",person[i].category.position);
        else printf("input error!!!");
    }
    printf("\n");


    printf(" NO.\tname\tsex\tjob\tclass/position\n");
    for(i=0;i<2;i++){
        if(person[i].job=='s') printf("%-6d%-10s%-4c%-4c%-10d\n",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.class);
        //%-6d 表示以十进制输出,占6列,数据向左对齐
        else printf("%-6d%-10s%-4c%-4c%-10s\n",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.position);
    }
    return 0;
}
1
2
3
4
5
6
7
8
9
//输出
please enter the date of person: 
101 li f s  501
please enter the date of person:
102 wang m t prof

 NO.    name    sex     job     class/position
101   li        f   s   501
102   wang      m   t   prof

枚举类型

  • 类型声明
    • 方式1:
      • 同时声明和定义[不带枚举类型名]
      • enum {sum,mon,tue,wed,thu,fri,sat} workday,weekend;
    • 方式2:
      • 先声明枚举类型名,再定义枚举变量
      • enum Weekday{sum,mon,tue,wed,thu,fri,sat};
      • enum Weekday workday,weekend;
  • 枚举类型的枚举元素是常量,不能对其赋值
  • 每个枚举元素都代表一个整数,一般默认顺序为:0,1,2,3,4….
  • 枚举元素可以用来判断比较,因为每个枚举类型变量的值是整数。

    typedef声明新类型名

1
2
typedef int Integer; //指定Interger为类型名,作用与 int相同
typedef int Count;   //define int into Count,make reader easy to understand its function.

typedef与#define的区别

  • 相似:作用都是用来将一个名字替换成另一个
  • 不同:
    • typedef is during compile
    • #defineis during precomppile
This post is licensed under CC BY 4.0 by the author.