C语言

C语言 第8节 结构体

2019-07-09  本文已影响0人  小超_8b2f

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) 指针变量 -> 成员变量名 (更常用)

浮点数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. 链表
上一篇 下一篇

猜你喜欢

热点阅读