1、结构体

1、为什么需要结构体

  为了表示一些复杂的事物,而普通的基本类型无法满足实际要。

2、求什么叫结构体
  把一些基本类型数据组合在一起形成的一个新的复合数据类型,这个叫做结构体。

3、如何定义结构体

/*----------------------------------------------
结构体的定义方式
-----------------------------------------------
3种方式,推荐使用第一种:
-----------------------------------------------*/

# include <stdio.h>

//第一种方式     这只是定义了一个新的数据类型,并没有定义变量
struct Student
{
    int age;
    float score;
    char sex;
};

//第二种方式
struct Student2
{
    int age;
    float score;
    char sex;
} st2;

//第三种方式
struct 
{
    int age;
    float score;
    char sex;
} st3;

int main(void)
{
    struct Student st = {80, 66.6, 'F'};    

    return 0;
}

4、怎样使用结构体变量

赋值和初始化
  定义的同时可以整体赋初值
  如果定义完之后,则只能单个的赋初值

/*----------------------------------------------
结构体变量的赋值和初始化
-----------------------------------------------*/

# include <stdio.h>

//第一种方式
struct Student
{
    int age;
    float score;
    char sex;
};

int main(void)
{
    struct Student st = {80, 66.6, 'F'}; //初始化  定义的同时赋初值
    struct Student st2;
    st2.age = 10;
    st2.score = 88;
    st2.sex = 'F';

    printf("%d %f %c\n", st.age, st.score, st.sex);          //80 66.599998 F
    printf("%d %f %c\n", st2.age, st2.score, st2.sex);       //10 88.000000 F
    
    return 0;
}

5、如何取出结构体变量中的每一个成员【重点】

1) 结构体变量名.成员名
2) 指针变量名-〉成员名(第二种方式更常用)

  指针变量名->成员名在计算机内部会被转化成(*指针变量名).成员名的方式来执行
  所以说这两种方式是等价的

/*----------------------------------------------
如何取出结构体变量中的每一个成员
-----------------------------------------------*/

# include <stdio.h>

struct Student
{
    int age;
    float score;
    char sex;
};

int main(void)
{
    struct Student st = {80, 66.6F, 'F'}; //初始化  定义的同时赋初值
    struct Student * pst = &st;  //&st不能改成st

    pst->age = 88;//第二种方式   
    st.score = 66.6f; //第一种方式  66.6在C语言中默认是double类型,如果希望一个实数是float类型,则必须在末尾加f或F, 
//因此66.6是double, 66.6f或66.6F是float
printf("%d %f\n", st.age, pst->score); //88 66.599998:因为浮点型数据不能保证每一个数字都能准确存储 return 0; } /*----------------------------------------------------------------------------------------------- 1.pst->age在计算机内部会被转化成(*pst).age,没有什么为什么,这就是一>的含义,这也是一种硬性规定 2.所以pst->age等价于(*pst).age也等价于st.age 3.我们之所以知道pst->age等价于st.age,是因为pst->age是被转化成了(*pst).age来执行 4.pst->age的含义: pst所指向的那个结构体变量中的age这个成员 ------------------------------------------------------------------------------------------------*/

6、结构体变量和结构体指针变量作为函数参数传递的问题

  推荐使用结构体指针变量作为函数参数来传递

/*
    通过函数完成对结构体变量的输入和输出
*/

# include <stdio.h>
# include <string.h>

struct Student
{
    int age;
    char sex;
    char name[100];
}; //分号不能省

void InputStudent(struct Student *);
void OutputStudent(struct Student ss);
int main(void)
{
    struct Student st;  //15行

    InputStudent(&st); //对结构体变量输入  必须发送st的地址
//    printf("%d %c %s\n", st.age, st.sex, st.name);
    OutputStudent(st); //对结构体变量输出  可以发送st的地址也可以直接发送st的内容

    return 0;
}

void OutputStudent(struct Student ss)  
{
    printf("%d %c %s\n", ss.age, ss.sex, ss.name);    //10 F 张三
}


//pstu存放st的地址,*pstu就是st,    (*pstu).age = 10等价于st.age=10

void InputStudent(struct Student * pstu) //pstu只占4个字节
{
    (*pstu).age = 10;
    strcpy(pstu->name, "张三");
    pstu->sex = 'F';    
}

/*
//本函数无法修改主函数15行st的值 所以本函数是错误的
void InputStudent(struct Student stu)
{
    stu.age = 10;
    strcpy(stu.name, "张三");  //不能写成 stu.name = "张三";
    stu.sex = 'F';
}
*/
/*
    示例:
        发送地址还是发送内容
    目的:
        指针的优点之一:
            快速的传递数据,
            耗用内存小
            执行速度快
*/


# include <stdio.h>
# include <string.h>

struct Student
{
    int age;
    char sex;
    char name[100];
}; //分号不能省

void InputStudent(struct Student *);
void OutputStudent(struct Student *);
int main(void)
{
    struct Student st ;  //15行
    //printf("%d\n", sizeof(st));

    InputStudent(&st); //对结构体变量输入  必须发送st的地址
    OutputStudent(&st); //对结构体变量输出  可以发送st的地址也可以直接发送st的内容 但为了减少内存的耗费,也为了提高执行速度,推荐发送地址

    return 0;
}

void OutputStudent(struct Student *pst)
{
    printf("%d %c %s\n", pst->age, pst->sex, pst->name);
}

void InputStudent(struct Student * pstu) //pstu只占4个字节
{
    (*pstu).age = 10;
    strcpy(pstu->name, "张三");
    pstu->sex = 'F';    
}

/*
//本函数无法修改主函数15行st的值 所以本函数是错误的
void InputStudent(struct Student stu)
{
    stu.age = 10;
    strcpy(stu.name, "张三");  //不能写成 stu.name = "张三";
    stu.sex = 'F';
}
*/
应该发送内容还是发送地址

7、结构体变量的运算

  结构体变量不能相加,不能想减,也不能相互乘除但结构体变量可以相互赋值。

struct Student
{
    int age;
    char sex;
    char name[100];
};
struct Student st1,st2;
//st1+st2 st1*st2 st1/st2都是错误的,st1=st2或者st2=st1都是正确的 
# include <stdio.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 a[6] = {10, 2, 8, -8, 11, 0};
    int i = 0;

    sort(a, 6);

    for (i=0; i<6; ++i)
    {
        printf("%d ", a[i]);
    }
    printf("\n");

    return 0;
}
冒泡排序

8、动态构造存放学生信息的结构体数组

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

# include <stdio.h>
# include <malloc.h>

struct Student
{
    int age;
    float score;
    char name[100];
};

int main(void)
{
    int len;
    struct Student * pArr;
    int i, j;
    struct Student t;
    

    //动态的构造一维数组
    printf("请输入学生的个数:\n");
    printf("len = ");
    scanf("%d", &len);
    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是数组名,本身就已经是数组首元素的地址, 所以pArr[i].name 不能改成 &pArr[i].name

        printf("score = ");
        scanf("%f", &pArr[i].score);
    }

    //按学生成绩升序排序 冒泡算法
    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是数组名,本身就已经是数组首元素的地址, 所以pArr[i].name 不能改成 &pArr[i].name
        printf("score = %f\n", pArr[i].score);
    
        printf("\n");
    }

    return 0;
}

/*-------------------------------
        请输入学生的个数:
        len = 3
        请输入第1个学生的信息:
        age = 21
        name = zhang
        score = 100
        请输入第2个学生的信息:
        age = 20
        name = bo
        score = 99
        请输入第3个学生的信息:
        age = 21
        name = hh
        score = 98


        学生的信息是:
        第1个学生的信息是:
        age = 21
        name = hh
        score = 98.000000

        第2个学生的信息是:
        age = 20
        name = bo
        score = 99.000000

        第3个学生的信息是:
        age = 21
        name = zhang
        score = 100.000000

        Press any key to continue
--------------------------------------*/
学生管理系统

 

posted @ 2020-04-06 14:56  zh_小猿  阅读(256)  评论(0编辑  收藏  举报