美文网首页C语言
C语言 第8节 结构体

C语言 第8节 结构体

作者: 小超_8b2f | 来源:发表于2019-07-09 19:06 被阅读0次

    C语言编程网 - 结构体

    一、为什么需要结构体?

    为了表示复杂的事物,而一些普通的基本类型无法满足需求

    二、什么是结构体

    把一些基本类型数据组合在一起形成的一个新的复合数据类型

    三、如何定义结构体(3种,只推荐使用其中一种)

    #include <stdio.h>
    
    #第一种方式
    struct Student {
        int age;
        float score;
        char sex;
    };
    
    #第二种方式:定义结构体的同时定义变量名,意味着只能定义一次,不好
    #并且只有在定义时才能用 = { }方式赋值
    typedef struct Student2 {
        int age;
        float score;
        char sex;
    } st2, st3;
    
    #第三种方式:不知道变量类型,只知道变量名
    struct {
        int age;
        float score;
        char sex;
    } st4, st5;
    
    #第四种,给结构体变量类型起别名
    typedef struct People {
      char name[200];
      int age;
      double score;
    } Person;
    
    
    int main(void) {
        int i = 10;
        struct Student st = {22,100.0,'f'};
        printf("%d\n",i);
        return 0;
        
        struct People p0 =  {"小超", 22, 100.0};
        Person p1 = {"小超", 22, 100.0};
    
        st2.age = 10;
        st2. sex = 'f';
    }
    

    四、怎样使用结构体变量

    1. 赋值和初始化
      (1)定义的同时可以整体赋初始值
      (2)如果定义完后只能单个属性赋值
    #include <stdio.h>
    
    struct Student {
        int age;
        float score;
        char sex;
    };
    
    int main(void) {
        int i = 10;
        struct Student st = {22,100.0,'f'};
    
        struct Student st2;
        //st2 = {22,100.0,'f'}; //这样写是❌的,不可以只能在定义时这样写
        st2.age = 20;
        st2.score = 99.9;
        st2.sex = 'm';
    
        printf("%d %f %c\n", st1.age, st1.score, st1.sex);
        printf("%d %f %c\n", st2.age, st2.score, st2.sex);
        printf("%d\n",i);
        return 0;
    }
    
    1. 如何取出结构体变量中的每一个成员
      (1) 结构体变量名.成员变量名
      (2) 指针变量 -> 成员变量名 (更常用)
    • pst -> age 在内部会被转化为(*pst).age,没为什么,这就是 ->的含义,硬性规定。所以 pst -> age = (*pst).age = st.age

    浮点数float和double都不能保证每一个数字数据的准确存储。其编码格式导致:IE754标准导致了无法准确存储,只能存储一个近视值。

    #include <stdio.h>
    
    struct Student {
        int age;
        float score;
        char sex;
        char name[100];
    };
    
    int main(void) {
        struct Student st = {22,100.0f,'f',"小超"};
        st.age = 20;  //第一种方式:结构体变量.成员变量
        st.score = 66.6f;  //浮点数float和double都不能保证数据的准确存储
        struct Student * pst = &st;
        pst -> age = 22; //第二种方式:指针变量 -> 成员变量
        printf("%d  %f  %c  %s \n",st.age, st.score, st.sex, st.name);
        printf("%d  %f  %c  %s \n",pst -> age, pst -> score, pst -> sex, pst -> name);
        return 0;
    }
    
    1. 结构体变量的运算

    结构体变量之间不能 加 减 乘 除(➕ ➖ ✖️ ➗), 只能赋值=

    1. 结构体变量和结构体变量指针作为函数参数传递的问题
    #include <stdio.h>
    #include <string.h>
    
    struct Student {
        int age;
        char sex;
        double score;
        char name[100];
    };
    
    void InputStudent(struct Student * st);
    void OutputStudent(struct Student st);
    
    int main(void) {
        struct Student st = {22,'m',22.2,"hello world"};
        OutputStudent(st);
    
        InputStudent(&st);
        
        OutputStudent(st);
        printf("%d  %d \n " sizeof(st), sizeof(&st));
        return 0;
    }
    
    //需要修改变量的值,所以必须使用指针变量
    void InputStudent(struct Student * st) { //st是保存4个字节的地址变量
        st -> age = 30;
        st -> sex = 'f';
        st -> score = 100.0;
        strcpy(st -> name , "world hello"); //字符串变量修改,不能用赋值符号 = 
    }
    /*
    只输出,不修改值,所以用不用指针无所谓。
    但是为了减少内存的使用 和 执行速度,一般会使用指针的方式
    缺点是不安全,C++及Java中使用const关键字使其不可修改
    推荐发送地址,而不是变量
    */
    void OutputStudent(struct Student st) {
        printf("%d %c %lf %s\n", st.age, st.sex, st.score, st.name);
    }
    

    Java中const关键字告诉你可以发生地址,但是不能修改。

    学数据结构,就是学数据的存储和操作。要学数据结构,必须学指针,不懂指针,就学不会数据结构。

    1. 举例:动态构造存放学生信息的结构体数组
    # include <stdio.h>
    # include <malloc.h>
    
    /*冒泡排序*/
    void sort(int * a, int len) {
        int i, j, t;
        for(i = 0; i < len -1; i++) {
            for(j = 0; j < len-1 -i; ++j) {
                if(a[j] > a[j+1]) {
                    t = a[j];
                    a[j] = a[j+1];
                    a[j+1] = t;
                }
            }
        }
    }
    
    int main(void) {
        int arr[5] = {10, 6, 8, -5, 4};
        sort(arr, 5);
        for(int i = 0; i < 5; i++) {
            printf("%d\n",arr[i]); 
        }
        
        return 0;
    }
    

    动态构造一个数组,存放学生的信息
    然后按分数排序输出

    #include <stdio.h>
    #include <malloc.h>
    
    struct Student {
        int age;
        double score;
        char name[100];
    };
    
    int main(void) {
        int len, i,j;
        struct Student * pArr;
        struct Student t;
        printf("请输入学生的个数:\n");
        printf("len = ");
        scanf("%d", &len);
    
        //动态构造一维数组,len是数组长度,pArr指向数组第一个元素的地址,元素类型是struct Student
        pArr = (struct Student *)malloc(len * sizeof(struct Student));
    
        //输入学生信息
        for(i = 0; i < len; i++) {
            printf("请输入第%d个信息\n", i+1);
            printf("age = ");
            scanf("%d",&pArr[i].age);
            printf("name = ");
            scanf("%s",pArr[i].name); //name是数组名,本身已经是数组首元素地址,所以不需要取地址符
            printf("score = ");
            scanf("%lf",&pArr[i].score);
            printf("\n");
        }
    
        //冒泡排序
        for(i = 0; i < len -1; i++) {
            for(j = 0; j < len -1 -i; j++) {
                if(pArr[j].score > pArr[j+1].score) {
                    t = pArr[j];
                    pArr[j] = pArr[j+1];
                    pArr[j+1] = t;
                }
            }
        }
    
        printf("\n\n学生的信息是:\n");
    
        //输出
        for(i = 0; i < len; ++i) {
            printf("第%d个学生的信息\n", i+1);
            printf("age = %d\n",pArr[i].age);
            printf("name = %s\n",pArr[i].name); //name是数组名,本身已经是数组首元素地址,所以不需要取地址符
            printf("score = %lf\n",pArr[i].score);
        }
        return 0;
    }
    
    1. 链表

    相关文章

      网友评论

        本文标题:C语言 第8节 结构体

        本文链接:https://www.haomeiwen.com/subject/qjvmhctx.html