栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言n番战--结构体(七)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言n番战--结构体(七)

嵌入式之路,贵在日常点滴

                                                                ---阿杰在线送代码

目录

一、什么是结构体

二、定义结构体类型

三、定义结构体变量

四、结构体成员的访问

五、结构体的三种定义赋值方法 

六、结构体类型作用域

七、结构体数组 

八、结构体指针 

实际应用例子:

二级指针 


一、什么是结构体
  • 结构体和数组一样属于构造类型
  • 数组是用于保存一组相同类型数据的, 而结构体是用于保存一组不同类型数据的
    • 例如,在学生登记表中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。
    • 显然这组数据不能用数组来存放, 为了解决这个问题,C语言中给出了另一种构造数据类型——“结构(structure)”或叫“结构体”。

二、定义结构体类型

在使用结构体之前必须先定义结构体类型, 因为C语言不知道你的结构体中需要存储哪些类型数据, 我们必须通过定义结构体类型来告诉C语言, 我们的结构体中需要存储哪些类型的数据

  • 格式:
struct 结构体名{
     类型名1 成员名1;
     类型名2 成员名2;
     ……
     类型名n 成员名n;
 };
  • 示例:
struct Student {
    char *name; // 姓名
    int age; // 年龄
    float height; // 身高
};

 

三、定义结构体变量

定义好结构体类型之后, 我们就可以利用我们定义的结构体类型来定义结构体变量

格式: struct 结构体名 结构体变量名;

 

  • 先定义结构体类型,再定义变量
struct Student {
     char *name;
     int age;
};
struct Student stu;
  • 定义结构体类型的同时定义变量
struct Student {
    char *name;
    int age;
} stu;
  • 匿名结构体定义结构体变量
struct {
    char *name;
    int age;
} stu;

第三种方法与第二种方法的区别在于,第三种方法中省去了结构体类型名称,而直接给出结构变量,这种结构体最大的问题是结构体类型不能复用

四、结构体成员的访问

一般对结构体变量的操作是以成员为单位进行的,引用的一般形式为:结构体变量名.成员名

 struct Student {
     char *name;
     int age;
 };
 struct Student stu;
 // 访问stu的age成员
 stu.age = 27;
 printf("age = %d", stu.age);

五、结构体的三种定义赋值方法 
#include 
#include 

struct student
{
        int englishScore;
        int mathScore;
        int chineseScore;
        char name[128];
        
};//此处分号易漏

int main()
{
        //一、在结构体变量定义的时候就赋值,此时要全部赋值
        struct student stu1={100,100,100,"张三"};

        //二、先定义,后赋值,不需要全部赋值
        struct student stu2;
        stu2.englishScore = 90;
       //stu2.name = "李四";
	    strcpy(stu2.name,"李四");

        //三、常用的部分赋值方式,多见于内核源码对结构体的定义
        struct student stu3={
                .name = "周浩杰",
                .englishScore = 90,
                .mathScore = 80,    //此处是逗号
        };//分号易漏

        printf("stu1的名字是:%s,分数:%dn",stu1.name,stu1.englishScore);
        printf("stu2的名字是:%s,分数:%dn",stu2.name,stu2.englishScore);
        printf("stu3的名字是:%s,分数:%dn",stu3.name,stu3.englishScore);

	    return 0;
}

运行结果:

stu1的名字是:张三,分数:100
stu2的名字是:李四,分数:90
stu3的名字是:周浩杰,分数:90

为什么使用strcpy?

如果不在结构体变量初始化的时候就对具有数组类型的表达式赋值,则要使用strcpy,即不能直接赋值。

六、结构体类型作用域
  • 结构类型定义
    • 从定义的那一行开始, 直到遇到return或者大括号结束为止
  • 结构类型定义在函数外部的作用域与全局变量的作用域是相同的
    • 从定义的那一行开始,直到本文件结束为止
#include "stdio.h"

//定义一个全局结构体,作用域到文件末尾
struct Person{
    int age;
    char *name;
};

void test();

int main(int argc, const char * argv[])
{
    //定义局部结构体名为Person,会屏蔽全局结构体
    //局部结构体作用域,从定义开始到“}”块结束
    struct Person{
        int age;
    };
    // 使用局部结构体类型
    struct Person pp;
    pp.age = 50;
    //pp.name = "zbz";
	printf("局部结构体类型:%dn",pp.age);

    test();
    return 0;
}

void test() 
{
    //使用全局的结构体定义结构体变量p
    struct Person p = {10,"sb"};
    printf("全局的结构体:%d,%sn",p.age,p.name);
}

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

#include "stdio.h"
#include "string.h"

struct Student
{
	int num;
	char name[32];
	char sex;
	int age;
	double score;
	char addr[32];
};

int main()
{
	struct Student stu1 = {1,"李四",'g',17,95.5,"汕头"};
	struct Student stu2 = {2,"张三",'b',18,99.5,"东莞"};
	struct Student max;
	
	max = stu1;
	
	if(stu1.score < stu2.score)
	{
		max = stu2;
	}
	printf("成绩比较好的是:n");
	printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%sn",
		max.num,max.age,max.score,max.name,max.addr);
	
	//if(stu1.score < stu2.score)
	//{
	//	printf("成绩比较好的是:n");
	//	printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%sn",
	//		stu2.num,stu2.age,stu2.score,stu2.name,stu2.addr);
	//}
	//else
	//{
	//	printf("成绩比较好的是:n");
	//	printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%sn",
	//		stu1.num,stu1.age,stu1.score,stu1.name,stu1.addr);
	//}

	return 0;
}

七、结构体数组 

 做个简单应用就好:输入4个学生的名字成绩,找出最高分。

#include 
#include 
#include 

struct student
{
        char* name;
        int score;
};

int main()
{
        int i;
        struct student stu[4] = {0};

        for(i=0;i<4;i++)
        {
                printf("请输入第%d个学生的名字n",i+1);
                stu[i].name = (char* )malloc(sizeof(char)*16);
                memset(stu[i].name,0,sizeof(char)*16);
                scanf("%s",stu[i].name);

                printf("请输入他的成绩n");
                scanf("%d",&stu[i].score);
        }

        struct student stuMax = stu[0];//就像正常的变量一样,可以相互赋值

        for(i=1;i<3;i++)
        {
                if(stu[i].score > stuMax.score){
                        stuMax = stu[i];
                }
        }

        printf("最高分是%s:%dn",stuMax.name,stuMax.score);

        return 0;
}

请输入第1个学生的名字
张三
请输入他的成绩
56
请输入第2个学生的名字
李四
请输入他的成绩
85
请输入第3个学生的名字
王五
请输入他的成绩
95
请输入第4个学生的名字
李六
请输入他的成绩
64
最高分是王五:95

选票系统 

#include "stdio.h"
#include "string.h"

struct XuanMin
{
	char name[32];
	int tickets;
};

int main()
{
	struct XuanMin xm[3];
	struct XuanMin max;
	
	int feipiao = 0;
	int i;
	int len;
	int j;
	int mark = 0;
	
	int total = 5;
	char tempName[32];
	
	//初始化选民信息
	len = sizeof(xm)/sizeof(xm[0]);
	for(i=0;i 

 请输入第1个选民的名字:
aa
请输入第2个选民的名字:
bb
请输入第3个选民的名字:
cc
请输入你投给谁:
aa
请输入你投给谁:
bb
请输入你投给谁:
dd
没有此候选人,放弃
请输入你投给谁:
cc
请输入你投给谁:
cc
名字:aa,票数:1
名字:bb,票数:1
名字:cc,票数:2
cc以2票当选!!废票是1

八、结构体指针 
  • 一个指针变量当用来指向一个结构体变量时,称之为结构体指针变量
  • 格式: struct 结构名 *结构指针变量名
  • 示例:
      // 定义一个结构体类型
      struct Student {
          char *name;
          int age;
      };

     // 定义一个结构体变量
     struct Student stu = {“lnj", 18};

     // 定义一个指向结构体的指针变量
     struct Student *p;

     // 指向结构体变量stu
     p = &stu;

     
     // 方式1:结构体变量名.成员名 
     printf("name=%s, age = %d n", stu.name, stu.age);

     // 方式2:(*指针变量名).成员名
     printf("name=%s, age = %d n", (*p).name, (*p).age);

     // 方式3:指针变量名->成员名
     printf("name=%s, age = %d n", p->name, p->age);

     return 0;
  • 通过结构体指针访问结构体成员, 可以通过以下两种方式
    • (*结构指针变量).成员名
    • 结构指针变量->成员名(用熟)

(pstu)两侧的括号不可少,因为成员符“.”的优先级高于“*”。

如去掉括号写作pstu.num则等效于(pstu.num),这样,意义就完全不对了。

#include 
#include 
#include 

struct STU
{
        int score;
        char name[128];
};

int main()
{
        struct STU stu1 = {
                .score = 99,
                .name = "陈立臣",
        };

        //malloc为结构体指针开辟一块空间
        struct STU *pstu = (struct STU *)malloc(sizeof(struct STU));
        //结构体指针的赋值1:直接赋值,在此之前要开辟空间
        pstu->score = 100;
        strcpy(pstu->name,"周浩杰");
        
        printf("%s:%dn",pstu->name,pstu->score);
        free(pstu);//释放指针,重新指向一段地址
        
        //结构体指针的赋值2:指向结构体变量的地址
        pstu = &stu1;
        printf("%s:%dn",pstu->name,pstu->score);

        //指针偏移
        printf("%pn",pstu);
        printf("%pn",++pstu);

        return 0;
}

 结果:结构体偏移了4+128个字节

周浩杰:100
陈立臣:99
0x7e905170
0x7e9051f4

实际应用例子:

用一个结构体指针做一个最简单的学生成绩管理。

#include 
#include 
#include 

struct stud
{
        char* name;
        int score;
};

int main()
{
        int num;
        int i;
        printf("需要录入几个学生的成绩?n");
        scanf("%d",&num);

        //这里开辟了num个结构体所需要的空间,动态分配内存
        struct stud *pstu = (struct stud *)malloc(sizeof(struct stud)*num);


        for(i=0;iname = (char* )malloc(sizeof(char)*16);
                memset(pstu->name,0,sizeof(char)*16);

                printf("请输入第%d个学生的名字n",i+1);
                scanf("%s",pstu->name);
                printf("请输入第%d个学生的成绩n",i+1);
                scanf("%d",&pstu->score);
                pstu++;
        }
        pstu -= num;

        for(i=0;iname,pstu->score);
                pstu++;
        }

        return 0;
}   

结果: 

美羊羊:45
废羊羊:100
喜羊羊:60
灰太狼:76

因为呢结构体比较重要,搞个稍微复杂一点的练练手。

主要运用结构体指针,输入学生的学号,语文数学英语成绩。

要求封装功能函数(初始化学生成绩,找到分数最高的学生,算出班级平均分)。

#include 
#include 
#include 

typedef struct student
{
        char* name;
        int chinese;
        int math;
        int english;
        int total;
}STU,*PSTU;

PSTU initStu(int num)
{
        int i;
        //要想返回结构体指针,就要先创建并开创空间。
        PSTU p = (PSTU)malloc(sizeof(STU) * num);
        for(i=0;iname = (char* )malloc(16);
          //为字符指针开辟空间才能赋值,否则就等着段错误吧。
                memset(p->name,0,16);
                scanf("%s",p->name);

                printf("请分别输入语文,数学,英语成绩,以逗号隔开,以回车结束n");
                scanf("%d,%d,%d",&p->chinese,&p->math,&p->english);
                p++;
        }
        return p-num;
}

PSTU findMax(PSTU stuSum,int num)
{
        int i;
        PSTU max = stuSum;
        PSTU p = stuSum;
        for(i=0;itotal > max->total){
                        max = p;
                }
                p++;
        }
        return max;
}


void getTotalAndAve(PSTU stuSum,int num,int* ave)
{
        int i;
        int sum = 0;
        PSTU p = stuSum;
        for(i=0;itotal = p->chinese + p->math + p->english;
                p++;
        }
        p -= num;
        for(i=0;itotal;
                p++;
        }

        *ave = sum / num;

//      free(p-num);
//      p=NULL;

}

void print(PSTU stuSum,PSTU stuMax,int ave,int num)
{
        int i;
        PSTU p = stuSum;//这样不会导致stuSum指针偏移
        for(i=0;i>>>语文:%d,数学:%d,英语:%dnn",
            p->name,p->chinese,p->math,p->english);
           p++;
        }
        printf("总分最高分是%s:%dn",stuMax->name,stuMax->total);
        printf("班级平均分是:%dn",ave);

//      free(p-num);
//      p = NULL;
}

int main()
{
        int num;//学生人数
        int ave;//班级均分
        printf("需要录入几人的成绩?n");
        scanf("%d",&num);

        PSTU stuSum = initStu(num);//初始化学生信息
        getTotalAndAve(stuSum,num,&ave);//计算各个学生的总分以及班级均分
        PSTU stuMax = findMax(stuSum,num);//找到总分最高的学生
        print(stuSum,stuMax,ave,num);//打印学生信息,最高分的人,班级均分

        return 0;
}

选票系统

#include "stdio.h"
#include "string.h"
#include 

struct XuanMin
{
	char name[32];
	int tickets;
};

struct XuanMin* initXm(struct XuanMin *p,int *pn)
{
	int i;
	if(p == NULL)
	{
		printf("请输入有几个人参选:n");
		scanf("%d",pn);
		p = (struct XuanMin*)malloc(*pn * sizeof(struct XuanMin));
	}
	
	for(i=0;i<*pn;i++)
	{
		p->tickets = 0;
		printf("请输入第%d个选民的名字:n",i+1);
		scanf("%s",p->name);
		p++;
	}
	return p-*pn;
}

void printXm(struct XuanMin *p,int len)
{
	int i;
	for(i=0;iname,p->tickets);
		p++;
	}
}

int dovot(struct XuanMin *p,int len)
{
	int i;
	int j;
	int feipiao = 0;
	int mark;
	char tempName[32];
	struct XuanMin *pbak = p;
	
	//唱票环节
	for(i=0;i<5;i++)
	{
		mark = 0;
		printf("请输入你投给谁:n");
		memset(tempName,'',sizeof(tempName));//每次清空一下
		scanf("%s",tempName);//输入选中的选民名字,像拆开一个选票,看到名字一样
		p = pbak;
		for(j=0;jname) == 0)
			{
				p->tickets++;
				mark = 1;
			}
			p++;
		}
		if(mark == 0)
		{
			printf("没有此候选人,放弃n");
			feipiao++;			
		}
	}
	
	return feipiao;
}

struct XuanMin* getMax(struct XuanMin* p,int len)
{
	struct XuanMin* max;
	int i;
	
	max = p;
	
	for(i=0;itickets < p->tickets)
		{
			max = p;
		}
		p++;
	}
	
	return max;
}

int main()
{
	struct XuanMin *xm = NULL;
	struct XuanMin *final;
	int total = 0;
	xm = initXm(xm,&total);
	printXm(xm,total);
	
	int feip = dovot(xm,total);
	printf("废票数是:%dn",feip);
	printXm(xm,total);
	
	final = getMax(xm,total);
	printf("%s以%d票当选!!废票是%dn",final->name,final->tickets,feip);
	
	return 0;
}

二级指针 

  

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1019137.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号