zoukankan      html  css  js  c++  java
  • C语言学习-Day_07


    • 学习参考B站郝斌老师的视频,文章内的源码如有需要可以私信联系。

    结构体

    • 为了表达一些复杂的事物,而普通的基本类型无法满足实际需求
    • 把一些基本数据组合在一起,形成的一个新的复合数据类型,叫结构体

    :结构体举例

    /*结构体*/
    # include <stdio.h>
    
    struct Student  //定义结构体,由基本的变量构成
    {
    	int age;
    	int score;
    	char sex;
    };
    
    int main(void)
    {
    	struct Student st = {20, 85, 'M'};  //定义结构体变量
    
    	return 0;
    }
    

    :定义结构体的方式

    /*定义结构体*/
    //第一种方式,推荐使用的方式
    struct Student  //只是定义了新的数据类型,并没有定义变量
    {
    	int age;
    	int score;
    	char sex;
    };
    
    //第二种方式
    struct Student
    {
    	int age;
    	int score;
    	char sex;
    }st;
    
    //第三种方式
    struct
    {
    	int age;
    	int score;
    	char sex;
    }st;
    

    结构体变量的使用

    • 赋值和初始化
      • 定义的同时可以整体赋初始值
      • 定义完后,只能单个的赋初始值
    • 取出结构体变量中的每一个成员
      • 结构体.成员名
      • 指针变量名->成员名
    • 结构体变量的运算
      • 结构体变量可以互相赋值,但是不能相加减,相乘除

    :结构体变量的赋值和初始化

    /*结构体变量的赋值和初始化*/
    # include <stdio.h>
    
    struct Student
    {
    	int age;
    	int score;
    	char sex;
    };
    
    int main(void)
    {
    	struct Student st = {20, 85, 'M'};  //定义变量时赋值
    	struct Student st2;  //定义完成后再赋值
    	st2.age = 20;
    	st2.score = 85;
    	st2.sex = 'M';
    	printf("%d %d %c
    ", st2.age, st2.score, st2.sex);
    
    	return 0;
    }
    
    /*运行结果*/
    20 85 M
    Press any key to continue
    

    :结构体中成员变量的取出

    /*结构体中成员变量的取出*/
    # include <stdio.h>
    
    struct Student
    {
    	int age;
    	int score;
    	char sex;
    };   //分号不能省略
    
    int main(void)
    {
    	struct Student st = {20, 85, 'M'};
    	struct Student * pst = &st;  //定义指针变量pst时存放结构体地址的
    
    	pst->age = 25;  //在计算机内部会被转化为(*st).age
    	st.age = 25;
    
    	printf("%d %d %c
    ", st.age, pst->score, st.sex);
    
    	return 0;
    }
    
    • pst->age等价于(*pst).age也等价于st.age
      • pst->age表示指针变量pst指向的结构体中的age这个成员变量
    /*运行结果*/
    25 85 M
    Press any key to continue
    

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

    /*通过函数完成对结构体变量的输入和输出*/
    # include <stdio.h>
    # include <string.h>  //使用strcpy需要定义头文件
    
    struct Student
    {
    	int age;
    	char sex;
    	char name[50];
    };
    
    void InputStudent(struct Student stu);
    
    int main(void)
    {
    	struct Student st;
    
    	InputStudent(st);
    	printf("%d %c %s
    ", st.age, st.sex, st.name);
    
    	return 0;
    }
    
    
    //此函数不能修改主函数中st的值
    void InputStudent(struct Student stu)
    {
    	stu.age = 10;
    	strcpy(stu.name, "Bad");  //对字符串的处理必须使用strcpy,不能直接使用stu.name='Bad'
    	stu.sex = 'M';
    }
    
    • 程序中,将变量st的值发送给stu,在定义的函数内,改变的是stu中的成员变量,当函数执行结束后,变量stu的存储空间被释放,不会修改主函数中st的值
      • 即形参与实参的改变不互相影响
    • 结构体中的成员变量都没有初始化,所以会使用垃圾数据填充,字符串知道读取到才会认为字符串读取完成
    /*运行结果*/
    -858993460 ?烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫蘰
    Press any key to continue
    

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

    /*通过函数完成对结构体变量的输入和输出*/
    # include <stdio.h>
    # include <string.h>  //使用strcpy需要定义头文件
    
    struct Student
    {
    	int age;
    	char sex;
    	char name[50];
    };
    
    void InputStudent(struct Student *);  //函数声明,需要指定形参的数据类型
    void OutputStudent(struct Student);
    
    int main(void)
    {
    	struct Student st;
    
    	InputStudent(&st);  //对结构体变量输入,将变量st的地址发送给函数
    	printf("%d %c %s
    ", st.age, st.sex, st.name);
    	OutputStudent(st);  //对结构体变量输出,将变量st的值发送给函数
    
    	return 0;
    }
    
    void InputStudent(struct Student * pstu)
    {
    	(*pstu).age = 20;  //指针变量pstu用于存放st的地址,则*pstu即st的值
    	strcpy(pstu->name, "Bad");
    	pstu->sex = 'M';
    }
    
    void OutputStudent(struct Student stu)
    {
    	printf("%d %c %s
    ", stu.age, stu.sex, stu.name);
    }
    
    • 定义结构体,即定义一个数据类型,其中包含多个基本变量
    • 主函数中定义变量st,将st的地址发送到InputStudent函数,函数对结构体中的变量进行赋值
      • 函数接收st的地址后,使用(*pstu).age为结构体中的成员变量赋值
      • 指针变量pstu存放的是st的地址,则*pstu存放的是st的值,所以(*pstu).age等价于st.age
    • 函数执行完后,主函数再将成员变量输出
    • OutputStudent函数因为只对结构体变量输出,不进行改变,所以在主函数中将变量st的值或地址发送给定义函数都可以
      • 主函数发送的是地址会更好,因为如果直接发送内容,则需要发送的字节很多,而地址是固定的(4字节),可以减小内存的消耗,也可以提高执行速度
    /*运行结果*/
    20 M Bad
    20 M Bad
    Press any key to continue
    

    冒泡排序

    /*冒泡排序*/
    # 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[5] = {3, 5, 2, 0, -1};
    	int i;
    
    	Sort(a, 5);
    
    	for (i = 0; i < 5; ++i)
    		printf("%d ", a[i]);
    
    	printf("
    ");
    
    	return 0;
    }
    

    冒泡排序

    • 主函数中定义一个数组a[5],其中有五个元素,乱序存储,调用定义函数Sort,将数组的第一个元素存储的地址和数组的长度发送给Sort函数,对数组中的元素进行排序,然后对数组中的内容输出
    • 定义函数Sort,形参接收主函数的数组中第一个元素存储的地址和数组长度
    • 冒泡排序:
      • 将数组中的第一个数与第二个数进行比较,第二个数更大,则不需要交换位置
      • 将数组中的第二个数与第三个数比较,第二个数更大,所以将第二个数放在第三个数的位置
      • 依次类推,将最大的一个数放在数组最后的位置
      • 再从剩下的len - 1 - i个数中继续比较,将大的数放在剩下数中的最后一个位置
    • 排序后,最大的数或最小的数放在数组的最后,冒泡排序是将所有的数中两两之间进行比较,选出最大或最小的数

    综合程序

    • 要求用户输入需要录入的学生个数,然后依次录入学生的姓名、年龄、成绩,并根据成绩进行排序,排序后进行输出。

    :不使用函数

    /*学生管理系统*/
    # include <stdio.h>
    # include <malloc.h>
    
    /*定义结构体*/
    struct Student
    {
    	char name[50];
    	int age;
    	float score;
    };
    
    int main(void)
    {
    	int len;  //用于存放学生的个数
    	struct Student * p;
    	int i, j;
    	struct Student t;  //用于交换学生名次的中间变量
    
    	/*动态构造一维数组*/
    	printf("请输入需要录入学生的个数:");
    	scanf("%d", &len);  //将输入数值赋值给变量len
    	p = (struct Student *)malloc(len * sizeof(struct Student));
    	/*
    		动态构建一维数组
    		数组存放的数据类型为结构体定义的类型
    		动态分配的地址空间为学生个数 * 结构体所占的字节数
    	 */
    
    	/*输入学生信息*/
    	for (i = 0; i < len; ++i)
    	{
    		printf("请输入%d个学生的信息:
    ", i + 1);
    		printf("Nmae: ");
    		scanf("%s", p[i].name);  
    		/*
    			name是数组名,本身即为第一个元素的地址,则不需要再取地址
    			%s表示从键盘接收的数据是char类型
    			p存放的是结构体的地址,结构体中有三个基本变量,所以需要使用p[i].name来指定赋值给哪个变量
    		 */
    
    		printf("Age: ");
    		scanf("%d", &p[i].age);
    
    		printf("Score:");
    		scanf("%f", &p[i].score);  //%f表示从键盘接收的数据是float类型
    	}
    
    	/*对学生的成绩进行排序-冒泡排序*/
    	for (i = 0; i < len - 1; ++i)
    	{
    		for (j = 0; j < len - 1 - i; ++j)
    		{
    			if (p[j].score > p[j + 1].score)  //大于号是升序,小于号是降序
    			{
    				t = p[j];
    				p[j] = p[j + 1];
    				p[j + 1] = t;
    			}
    		}
    	}
    
    	printf("
    
    ");
    	/*输出学生信息*/
    	for (i = 0; i < len; ++i)
    	{
    		printf("第%d名学生的信息如下:
    ", i + 1);
    		printf("Name: %s
    ", p[i].name);
    		printf("Age: %d
    ", p[i].age);
    		printf("Score: %f
    ", p[i].score);
    		printf("
    ");
    	}
    
    	return 0;
    }
    
    /*运行结果*/
    请输入需要录入学生的个数:3
    请输入1个学生的信息:
    Nmae: Bad
    Age: 20
    Score:100
    请输入2个学生的信息:
    Nmae: Boy
    Age: 18
    Score:75
    请输入3个学生的信息:
    Nmae: Five
    Age: 15
    Score:851名学生的信息如下:
    Name: Boy
    Age: 18
    Score: 75.0000002名学生的信息如下:
    Name: Five
    Age: 15
    Score: 85.0000003名学生的信息如下:
    Name: Bad
    Age: 20
    Score: 100.000000
    
    Press any key to continue
    

    :将学生成绩的录入、排序、输出定义成函数

    /*学生管理系统*/
    # include <stdio.h>
    # include <malloc.h>
    
    /*定义结构体*/
    struct Student
    {
    	char name[50];
    	int age;
    	float score;
    };
    
    /*输入学生信息函数*/
    void Input_Info(struct Student * p, int len)
    {
    	int i;
    
    	for (i = 0; i < len; ++i)
    	{
    		printf("请输入%d个学生的信息:
    ", i + 1);
    		printf("Nmae: ");
    		scanf("%s", p[i].name);  
    		/*
    			name是数组名,本身即为第一个元素的地址,则不需要再取地址
    			%s表示从键盘接收的数据是char类型
    			p存放的是结构体的地址,结构体中有三个基本变量,所以需要使用p[i].name来指定赋值给哪个变量
    		 */
    
    		printf("Age: ");
    		scanf("%d", &p[i].age);
    
    		printf("Score:");
    		scanf("%f", &p[i].score);  //%f表示从键盘接收的数据是float类型
    	}
    }
    
    /*对学生的成绩进行排序-冒泡排序*/
    void Sort_Score(struct Student * p, int len)
    {
    	int i, j;
    	struct Student t;  //定义结构体中间变量,用于交换位置
    
    	for (i = 0; i < len - 1; ++i)
    	{
    		for (j = 0; j < len - 1 - i; ++j)
    		{
    			if (p[j].score > p[j + 1].score)  //大于号是升序,小于号是降序
    			{
    				t = p[j];
    				p[j] = p[j + 1];
    				p[j + 1] = t;
    			}
    		}
    	}
    }
    
    /*输出学生信息函数*/
    void Output_Info(struct Student * p, int len)
    {
    	int i;
    
    	printf("
    --------------------------
    ");
    	for (i = 0; i < len; ++i)
    	{
    		printf("第%d名学生的信息如下:
    ", i + 1);
    		printf("Name: %s
    ", p[i].name);
    		printf("Age: %d
    ", p[i].age);
    		printf("Score: %f
    ", p[i].score);
    		printf("
    ");
    	}
    }
    
    int main(void)
    {
    	int len;  //用于存放学生的个数
    	struct Student * p;
    
    	/*动态构造一维数组*/
    	printf("请输入需要录入学生的个数:");
    	scanf("%d", &len);  //将输入数值赋值给变量len
    	p = (struct Student *)malloc(len * sizeof(struct Student));
    	/*
    		动态构建一维数组
    		数组存放的数据类型为结构体定义的类型
    		动态分配的地址空间为学生个数 * 结构体所占的字节数
    	 */
    
    	/*调用输入学生信息函数*/
    	Input_Info(p, len);
    
    	/*对学生的成绩进行排序-冒泡排序*/
    	Sort_Score(p, len);
    
    	/*调用输出学生信息函数*/
    	Output_Info(p, len);
    
    	return 0;
    }
    
    /*运行结果*/
    请输入需要录入学生的个数:3
    请输入1个学生的信息:
    Nmae: Bad
    Age: 20
    Score:78
    请输入2个学生的信息:
    Nmae: Boy
    Age: 18
    Score:85
    请输入3个学生的信息:
    Nmae: Five
    Age: 15
    Score:63
    
    --------------------------1名学生的信息如下:
    Name: Five
    Age: 15
    Score: 63.0000002名学生的信息如下:
    Name: Bad
    Age: 20
    Score: 78.0000003名学生的信息如下:
    Name: Boy
    Age: 18
    Score: 85.000000
    
    Press any key to continue
    

    以上内容均属原创,如有不详或错误,敬请指出。
    
    做别人的宝贝,别来淌我这趟浑水。
  • 相关阅读:
    2019-12-2 异常捕获
    类与类之间的6种关系
    关键字与理解
    this与super的语法比较
    单继承与多继承对比
    为什么javaBean要有get/set方法的设计
    多态在面向对象中的意义以及带来的好处
    十四、线程设计
    十三、窗口设计
    十二、SWING界面设计
  • 原文地址:https://www.cnblogs.com/bad5/p/14633764.html
Copyright © 2011-2022 走看看