【C语言从入门到入土】第八章 结构体

第八章 结构体

完结散花,C语言全部章节更新完毕

文章目录

1.初识

1.1为什么要用结构体

整型数,浮点型数,字符串是分散的数据表示,有时候我们需要用很多类型的数据来表示一个整体,比如学生信息

类比与数组:数组是元素类型一样的数据集合。如果是元素类型不同的数据集合,就要用到结构体了。

1.2定义一个结构体

它算是一个模板,一般不给赋具体的值,每一项在实际应用中并不是都要使用。

成员列表------也称为域表------每个成员都是结构体中的一个域

在声明的同时,定义变量,尽量少用

1.3初始化一个结构体变量并引用
c 复制代码
//初始化结构体
#include <stdio.h>
#include <string.h>
struct Student
{
    int    num;
    char   name[32];
    char   sex;
    int    age;
    double score;
    char   addr[32];
};  //注意这里的分号不要丢
int main()
{
	int a;
    //struct Student (这里可以看做 int)   stu1(这个就属于a,变量名)
	struct Student stu1 = {2,"张三",'g',17,99.5,"北京"};//01
    //001.那么如何赋值呢?两种赋值方式 1.int a=10  2.int a; a=10;对比以前的
    struct Student stu2;//02
    stu2.num   = 2;//1.点运算符来访问结构体中的成员变量(域)
    stu2.age   = 18;//2.结构体里面的成员变量不是非要用上的,只用一部分也是可以的
    stu2.score = 88.8;
    strcpy(stu2.name,"李四");
    strcpy(stu2.addr,"湖南");
    //002.那么如何去引用呢?
    printf("学号:%d,年龄:%d,分数:%.2f,名字:%s,地址:%s\n",stu2.num,stu2.age,stu2.score,stu2.name,stu2.addr);
    return 0;
}
1.4例题

例题:输入两个学生的名字,学号,成绩,输出成绩高的学生的信息

重点认知:结构体没什么特殊的,只是把变量藏在结构体里面,而内部的变量,以前学习的东西是通用的,只是"触达的方式"不同

c 复制代码
#include <stdio.h>
#include <string.h>
struct Student
{
    int    num;
    char   name[32];
    char   sex;
    int    age;
    double score;
    char   addr[32];
}; 
int main()
{
	int a;
    //int tmp;
	struct Student stu1 = {2,"张三",'g',17,9,"北京"};//01
    struct Student stu2;//02
	struct Student max;//注意要把这个定义出来
    stu2.num   = 2;
    stu2.age   = 18;
    stu2.score = 88.8;
    strcpy(stu2.name,"李四");
    strcpy(stu2.addr,"湖南");
    max = stu1;//做一个变量的话,可以省写很多,要不然两个需要一一打印
    if(stu1.score<stu2.score){
        max = stu2;
    }
    printf("学号:%d,年龄:%d,分数:%.2f,名字:%s,地址:%s\n",
           max.num,max.age,max.score,max.name,max.addr);
    return 0;
}

2.结构体数组

c 复制代码
#include <stdio.h>
#include <string.h>
struct Student
{
    int    num;
    char   name[32];
    char   sex;
    int    age;
    double score;
    char   addr[32];
}; 
int main()
{
    int arr[3] ={1,2,3};
    int i;
    int len;
  //       len = sizeof(arr)/sizeof(arr[0]);
    //类比数组来做结构体的数组
 	struct Student arr2[3] =
    {
        {1,"张三",'g',17,9,"河北"},
        {2,"李四",'g',18,9,"广东"},
        {3,"王五",'g',17,9,"湖南"}
    };

	len = sizeof(arr2)/sizeof(arr2[0]);

    for(i=0;i<len;i++)
    {
          printf("学号:%d,年龄:%d,分数:%.2f,名字:%s,地址:%s\n",
           arr2[i].num,arr2[i].age,arr2[i].score,arr2[i].name,arr2[i].addr);
    }
  
    return 0;
}

3.应用练习:选票系统

c 复制代码
#include <stdio.h>
#include <string.h>

struct xuanmin{
    int tickets;
    char name[32];
};
int main()
{
    int total = 5;
    char person[32];
    int mark;
    int qipiao = 0;
    int j;
//第二个思路我想要选择出弃票的有几个,然后票数最高的是谁
    struct xuanmin arr[3];
    struct xuanmin max;
    max.tickets = 0;
    int len =sizeof(arr)/sizeof(arr[0]);
    //1.输入候选人
    for(int i =0;i<len;i++){
    	arr[i].tickets = 0;
        printf("请输入第%d候选人的名字\n",i+1);
        scanf("%s",arr[i].name);
     }
        
     //2.你要投那个候选人(一人一票,共五个人)
     for(int i = 0;i<total;i++){
        printf("请输入你想投的给谁一票\n");
        memset(person,'\0',sizeof(person));
        scanf("%s",person);
        mark = 0;
        for(int j =0;j<3;j++){
           if(strcmp(person,arr[j].name)==0){
               arr[j].tickets++;
               mark = 1;
           }    
    	}
         if(mark == 0){
             qipiao++;
         }
    }
     //3.公布结果
     for(int i=0;i<3;i++){
       printf("%s候选人共%d票\n",arr[i].name,arr[i].tickets);	
	}
     for(int i =0;i<len;i++){
     	if(max.tickets<arr[i].tickets){
     		max = arr[i];//这是一个出彩的点,直接用一个票数换了整个结构体 
     		j = i;
		 }
	 }
	 printf("%s候选人以%d票当选,弃票%d人\n",max.name,max.tickets,qipiao);
    return 0;
}

4.结构体指针

1.概念引入
  1. 回忆:指针就是地址 指针变量就是存放地址的变量
    结构体也是变量
    变量访问有两种方式 : 1.变量名 2.地址
    之前案例,是用变量名访问
  2. 通过结构体变量地址来访问该结构体
    需要一个变量来保持这个地址:
    这和之前说的指针,其实是一样的
    只是指针类型是结构体
  3. int a; struct Test t;
    int *p; struct Test *p;
    p = &a; p = &t
c 复制代码
#include <stdio.h>
#include <string.h>
struct student{
    char name;
    int  numble;
};
int main()
{
    //我们对照以前的
    int a;
    int *p =&a;
    
    char c;
    char *p2=&c;
    
    struct student stu1 ={'c',21};
    struct student *stu = &stu1; //结构体指针的定义
    
    //那我如果想要访问里面的数据呢?
    printf("%d\n",stu1.numble);//普通的变量名访问
    printf("%C\n",stu1.name);  //用最常见的.运算符
    stu ->name ='d';
    printf("%c\n",stu->name[32]);  //间接的地址访问
    printf("%d\n",stu->numble);//用->运算符
}
2.小应用
1.指针在结构体数组中的偏移
c 复制代码
#include <stdio.h>
#include <string.h>
struct Student
{
    int    num;
    char   name[32];
    char   sex;
    int    age;
    double score;
    char   addr[32];
}; 
int main()
{
    int arr[3] ={1,2,3};
    int i;
    int len;
    
    
  //       len = sizeof(arr)/sizeof(arr[0]);
    //类比数组来做结构体的数组
 	struct Student arr2[3] =
    {
        {1,"张三",'g',17,9,"河北"},
        {2,"李四",'g',18,9,"广东"},
        {3,"王五",'g',17,9,"湖南"}
    };
	struct Student *p = arr2;
	len = sizeof(arr2)/sizeof(arr2[0]);
	
    for(i=0;i<len;i++)
    {
          printf("学号:%d,年龄:%d,分数:%.2f,名字:%s,地址:%s\n",
          p->num,p->age,p->score,p->name,p->addr);//指针指向结构体
          p++;//指针偏移
    }
  
    return 0;
}
c 复制代码
//用结构体指针来替换原先的选票系统
#include <stdio.h>
#include <string.h>

struct xuanmin{
    int tickets;
    char name[32];
};
int main()
{
    int total = 5;
    char person[32];
    int mark;
    int qipiao = 0;

//第二个思路我想要选择出弃票的有几个,然后票数最高的是谁
    struct xuanmin arr[3];
    struct xuanmin max;
    struct xuanmin *p = arr;
    max.tickets = 0;
    int len =sizeof(arr)/sizeof(arr[0]);
    //1.输入候选人
    for(int i =0;i<len;i++){
    	arr[i].tickets = 0;
        printf("请输入第%d候选人的名字\n",i+1);
        scanf("%s",p->name);
        p++;
     }
    p = arr;    
     //2.你要投那个候选人(一人一票,共五个人)
     for(int i = 0;i<total;i++){
     	p =arr;
        printf("请输入你想投的给谁一票\n");
        memset(person,'\0',sizeof(person));
        scanf("%s",person);
        mark = 0;
        for(int j =0;j<3;j++){
           if(strcmp(person,p->name)==0){
               (p->tickets)++;
               mark = 1;
           } 
		p++;      
    	}
    	
         if(mark == 0){
             qipiao++;
         }
         
    }
    p = arr;
     //3.公布结果
     for(int i=0;i<3;i++){
       printf("%s候选人共%d票\n",p->name,p->tickets);
	   p++;	
	}
	p = arr;
	max = arr[0];
     for(int i =1;i<len;i++){
     	if(max.tickets<p->tickets){
     		max = arr[i];//这是一个出彩的点,直接用一个票数换了整个结构体 
		 }
		 p++;
	 }
	 printf("%s候选人以%d票当选,弃票%d人\n",max.name,max.tickets,qipiao);
    return 0;
}

5.共用体/联合体

1.概念引入
  1. 有时候同一个内存空间存放类型不同,不同类型的变量共享一块空间
  2. 结构体元素有各自单独空间
    共用体元素共享空间,空间大小有最大类型确定
  3. 结构体元素互不影响
    共用体赋值会导致覆盖
c 复制代码
#include <stdio.h>
#include <string.h>

//1.联合体的大小取决于最大的整数数
//2.联合体里面的变量值都是在同一个地址里面存放着
struct Test{
    int    idata;
    char   cdata;
    double ddata;
};
union Testu{
    int    idata;
    char   cdata;
    double ddata;
};
int main()
{
    struct Test t;
    union  Testu u;
    
    printf("结构体的大小为%d\n",sizeof(t));
    printf("联合体的大小为%d\n",sizeof(u));
    
    printf("idata:%p\n",&t.idata);
    printf("cdata:%p\n",&t.cdata);
    printf("ddata:%p\n",&t.ddata);
    
    printf("idata:%p\n",&u.idata);
    printf("cdata:%p\n",&u.cdata);
    printf("ddata:%p\n",&u.ddata);
   return 0;
}
c 复制代码
#include <stdio.h>
#include <string.h>

//1.联合体的大小取决于最大的整数数
//2.联合体里面的变量值都是在同一个地址里面存放着
struct Test{
    int    idata;
    char   cdata;
    double ddata;
};
union Testu{
    int    idata;
    char   cdata;
    double ddata;
};
int main()
{
    struct Test t;
    union  Testu u;
    
    printf("结构体的大小为%d\n",sizeof(t));
    printf("联合体的大小为%d\n",sizeof(u));
//3.共同体的数据会被覆盖
    t.idata = 10;
    t.cdata = 'a';
    printf("idata:%p,%d\n",&t.idata,t.idata);
    printf("cdata:%p,%d\n",&t.cdata,t.cdata);
    printf("ddata:%p\n",&t.ddata);
    u.idata = 20;
    u.cdata = 'a';
    printf("idata:%p,%d\n",&u.idata,u.idata);
    printf("cdata:%p,%d\n",&u.cdata,u.cdata);
    printf("ddata:%p\n",&u.ddata);
   return 0;
}

6.宏定义define

宏定义define的新变量在左边,

  • 关键字:#define
  • 用途:用一个字符串代替一个数字(字符也可以),便于理解,防止出错;提取程序中经常出现的参数,便于快速修改定义
  • 宏定义: #define ABC 12345
  • 引用宏定义: int a = ABC; //等效于int a = 12345;

7.typedef

给变量类型结合,一般跟结构体配合较多

  • 关键字:typedef
  • 用途:将一个比较长的变量类型名换个名字,便于使用
  • 定义typedef: typedef unsigned char uint8_t;
  • 引用typedef: uint8_t a; //等效于unsigned char a;
  • 注意typedef不需要加分号,define需要加分号
c 复制代码
#include <stdio.h>

struct student{char name;int sex} stu1
int main()
{
    
    
    return 0;
}
相关推荐
hccee13 分钟前
C# IO文件操作
开发语言·c#
hummhumm18 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
J老熊28 分钟前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
寻找码源38 分钟前
【头歌实训:利用kmp算法求子串在主串中不重叠出现的次数】
c语言·数据结构·算法·字符串·kmp
zmd-zk42 分钟前
flink学习(2)——wordcount案例
大数据·开发语言·学习·flink
好奇的菜鸟1 小时前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang
Alive~o.01 小时前
Go语言进阶&依赖管理
开发语言·后端·golang
花海少爷1 小时前
第十章 JavaScript的应用课后习题
开发语言·javascript·ecmascript
手握风云-1 小时前
数据结构(Java版)第二期:包装类和泛型
java·开发语言·数据结构
喵叔哟1 小时前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构