【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;
}
相关推荐
oe10196 分钟前
好文与笔记分享 A Survey of Context Engineering for Large Language Models(下)
人工智能·笔记·语言模型·agent
冷雨夜中漫步38 分钟前
高级系统架构师笔记——系统质量属性与架构评估(1)软件系统质量属性
笔记·架构·系统架构
czy878747539 分钟前
C语言实现状态模式
c语言·状态模式
czy87874751 小时前
C语言实现迭代器模式
c语言·迭代器模式
野生技术架构师1 小时前
牛客网Java 高频面试题总结(2025最新版)
java·开发语言·面试
一只鹿鹿鹿1 小时前
系统安全设计方案书(Word)
开发语言·人工智能·web安全·需求分析·软件系统
oe10191 小时前
好文与笔记分享 A Survey of Context Engineering for Large Language Models(中)
人工智能·笔记·语言模型·agent开发
GilgameshJSS1 小时前
STM32H743-ARM例程36-DNS
c语言·arm开发·stm32·单片机·嵌入式硬件
持梦远方1 小时前
【C++日志库】启程者团队开源:轻量级高性能VoyLog日志库完全指南
开发语言·c++·visual studio
聪明努力的积极向上1 小时前
【C#】HTTP中URL编码方式解析
开发语言·http·c#