小白来学C语言之结构体
文章目录
- 概念
- 为什么要有结构体?
- 定义和使用结构体变量
- 自己建立结构体类型
- 定义结构体类型变量
- 结构体变量的初始化和引用
- 使用结构体数组
- 定义结构体数组
- 结构体指针
- 指向结构体变量的指针
- 指向结构体数组的指针
- 用指针处理链表
- 什么是链表
- 建立简单的静态链表
- 共用体类型
- 引用共用体变量的方式
- 共用体类型数据的特点
概念
为什么要有结构体?
因为在实际问题中,一组数据往往有很多种不同的数据类型。例如,登记学生的信息,可能需要用到 char型的姓名,int型或 char型的学号,int型的年龄,char型的性别,float型的成绩。又例如,对于记录一本书,需要 char型的书名,char型的作者名,float型的价格。在这些情况下,使用简单的基本数据类型甚至是数组都是很困难的。而结构体(类似Pascal中的“记录”),则可以有效的解决这个问题。
结构体本质上还是一种数据类型,但它可以包括若干个“成员”,每个成员的类型可以相同也可以不同,也可以是基本数据类型或者又是一个构造类型。
结构体的优点:结构体不仅可以记录不同类型的数据,而且使得数据结构是“高内聚,低耦合”的,更利于程序的阅读理解和移植,而且结构体的存储方式可以提高CPU对内存的访问速度。
定义和使用结构体变量
自己建立结构体类型
用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体
声明一个结构体类型的一般形式为:
struct 结构体名{ 成员表列 }; **************************
struct Student{int num; char name[20]; char sex; int age;float score; char addr[30];
}
上面这个的结构体类型为 :struct Student
它包括num,name,sex,age,score,addr等不同类型的成员
注:结构体的成员可以是结构体
struct Date{int month; int day; int year; };
struct Stu {int num;char name[20];struct Date birthday; };
定义结构体类型变量
定义结构体类型变量有以下几种方法
先声明结构体类型,再定义该类型变量。
声明结构体类型struct Student
struct Student student1,student2;
student1
10001 Zhang Xin 19 Shanghai在声明类型的同时定义变量
struct Student
{ int num; char name[20]; int age; char addr[30];
} student1,student2;
- 不指定类型名而直接定义结构体类型变量
struct{ 成员表列 }变量名表列;
注:
- 结构体类型与结构体变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。
- 结构体类型中的成员名可以与程序中的变量名相同(尽量不要重名),但二者不代表同一对象。
- 对结构体变量中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。
结构体变量的初始化和引用
定义结构体数组一般形式是
① struct 结构体名
{成员表列}
数组名[数组长度];
② 先声明一个结构体类型,然后再用此类型定义结构体数组:
结构体类型 数组名[数组长度];
如:
struct Person leader[3];
直接看例子,就是定义一个学生信息的结构体,然后对他初始化输出
#include <stdio.h>
int main( ){struct Studen{long int num; char name[20];char sex;char addr[20];}a={10101,"Li Lin",'M',"Beijing"}; printf("NO.:%ld\nname:%s\n sex:%c\naddress:%s\n",a.num,a.name,a.sex,a.addr);return 0;
}NO.:10101
name:Li Linsex:M
address:Beijing
下面这些是对上面的补充
a.num=10010; 对printf(“%s\n”,a); 不对struct Student b;
b=a; 对
b.num++; 对scanf(″%ld″,&a.num); 对printf(″%o″,&a); 对scanf(“%ld,%s,%c,%s\n”,&a); 错a.birthday.month=12; 对a.age=10; b.age=9; 对sum=a.age+b.age; 对
使用结构体数组
定义结构体数组
还是从例题入手,理论多没意思啊
例:有3个候选人,每个选民只能投票选一人,要求编一个统计选票的程序,先后输入被选人的名字,最后输出各人得票结果。
#include <string.h>
#include <stdio.h>
struct person // 声明结构体类型struct person{char name[20]; // 候选人姓名int count; // 候选人得票数 }leader[3]={"Li",0,"Zhang",0,"Fun",0}; // 定义结构体数组并初始化
int main(){int i,j;char leader_name[20]; // 定义字符数组 for (i=1;i<=10;i++){scanf("%s",leader_name); // 输入所选的候选人姓名 for(j=0;j<3;j++)if(strcmp(leader_name,leader[j].name)==0) leader[j].count++;}printf("\nResoult:\n");for(i=0;i<3;i++)printf("%5s:%d\n",leader[i].name,leader[i].count);return 0;}
前面设了一个结构体,里面包含name和count,后面leader是数组名3是数组长度
L、Z、S就是三个人的名字,有10个人投票,strcmp是判断两个字符是否i相等,是就为0,不是就为1。
结构体指针
指向结构体变量的指针
指向结构体对象的指针变量既可以指向结构体变量,也可以用来指向结构体数组中的元素。
指针变量的基类型必须与结构体变量的类型相同。例如:
struct Student *pt;
通过指向结构体变量的指针变量输出结构体变量中成员的信息
#include <stdio.h>
#include <string.h>
int main(){struct student{long num;char name[20];char sex;float score;};struct student stu_1; // 定义struct student类型的变量stu_1 struct student * p; // 定义指向struct student 类型数据的指针变量p p=&stu_1; // p指向stu_1 stu_1.num=10101; // 对结构体变量的成员赋值 strcpy(stu_1.name,"Li Lin");stu_1.sex='M';stu_1.score=89.5;printf("No.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",stu_1.num,stu_1.name,stu_1.sex,stu_1.score); // 输出结果 printf("\nNo.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",(*p).num,(*p).name,(*p).sex, (*p).score);return 0;}
可以看到*p也是这个结构体的,p指向同一类型(student类型)的stu_1,下面两种输出方式结果是一样的。*p就是取p存的内容,就是stu_1
指向结构体数组的指针
有3个学生的信息,放在结构体数组中,要求输出全部学生的信息
#include <stdio.h>
struct student{int num;char name[20];char sex;int age;};
struct student stu[3]={{10101,"Li Lin",'M',18},{10102,"Zhang Fun",'M',19},{10104,"Wang Min",'F',20}}; // 定义结构体数组并初始化
int main(){struct student *p; //定义指向struct student结构体的数组 printf(" No. Name sex age\n");for (p=stu;p<stu+3;p++)printf("%5d %-20s %2c %4d\n",p->num, p->name, p->sex, p->age);return 0;
}
为了使用方便和直观,C语言允许把(*p).num用p->num来代替
(*p).name等价于p->name
用指针处理链表
什么是链表
链表是一种常见的重要的数据结构
它是动态地进行存储分配的一种结构
链表必须利用指针变量才能实现
建立简单的静态链表
建立一个如图所示的简单链表,它由3个学生数据的结点组成,要求输出各结点中的数据。
#include <stdio.h>
struct student // 声明结构体类型struct student {int num;float score;struct student *next;};
int main(){struct student a,b,c,*head,*p; // 定义3个结构体变量作为链表的结点 a.num=10101; a.score=89.5; // 对结点a的num和score成员赋值 b.num=10103; b.score=90; // 对结点b的num和score成员赋值 c.num=10107; c.score=85; // 对结点c的num和score成员赋值 head=&a; // 将结点a的起始地址赋给头指针head a.next=&b; // 将结点b的起始地址赋给a结点的next成员 b.next=&c; // 将结点c的起始地址赋给a结点的next成员 c.next=NULL; // c结点的next成员不存放其他结点地址 p=head; // 使p也指向a结点 do {printf("%ld %5.1f\n",p->num,p->score); // 输出p指向的结点的数据 p=p->next; // 使p指向下一结点 }while(p!=NULL); // 输出完c结点后p的值为NULL,循环终止 return 0;}
共用体类型
有时想用同一段内存单元存放不同类型的变量。
使几个不同的变量共享同一段内存的结构,称为 “共用体”类型的结构。
定义共用体类型变量的一般形式为:
union 共用体名
{ 成员表列
}变量表列;
union Data
{ int i;char ch;float f;
};
union Data a,b,c;
“共用体”与“结构体”的定义形式相似,但它们的含义是不同的。
结构体变量所占内存长度是各成员占的内存长度之和,每个成员分别占有其自己的内存单元。而共用体变量所占的内存长度等于最长的成员的长度。
引用共用体变量的方式
只有先定义了共用体变量才能引用它,但应注意,不能引用共用体变量,而只能引用共用体变量中的成员。
例如,前面定义了a,b,c为共用体变量,下面的引用方式是正确的:
a.i a.ch a.f
共用体类型数据的特点
- 同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一个成员,而不是同时存放几个。
- 可以对共用体变量初始化,但初始化表中只能有一个常量。
- 共用体变量中起作用的成员是最后一次被赋值的成员,在对共用体变量中的一个成员赋值后,原有变量存储单元中的值就取代。
- 共用体变量的地址和它的各成员的地址都是同一地址。
- 不能对共用体变量名赋值,也不能企图引用变量名来得到一个值
- 以前的C规定不能把共用体变量作为函数参数,但可以使用指向共用体变量的指针作函数参数。C99允许用共用体变量作为函数参数。
- 共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。
有若干个人员的数据,其中有学生和教师。学生的数据中包括:姓名、号码、性别、职业、班级。教师的数据包括:姓名、号码、性别、职业、职务。要求用同一个表格来处理。
#include <stdio.h>
#include <malloc.h>
#define LEN sizeof(struct student)
struct student{long num;float score; struct student *next;};
int n;
struct student *creat(){struct student *head;struct student *p1,*p2;n=0;p1=p2=( struct student*) malloc(LEN);scanf("%ld,%f",&p1->num,&p1->score);head=NULL;while(p1->num!=0){n=n+1;if(n==1)head=p1;else p2->next=p1;p2=p1;p1=(struct student*)malloc(LEN);scanf("%ld,%f",&p1->num,&p1->score);}p2->next=NULL;return(head);
}void print(struct student *head){struct student *p;printf("\nNow,These %d records are:\n",n); p=head;if(head!=NULL)do{printf("%ld %5.1f\n",p->num,p->score);p=p->next;}while(p!=NULL);}int main(){struct student *head ;head=creat();print(head); return 0;}
算了我也没懂嘿嘿这个用到再仔细研究吧。
毕竟是小白,从小白视角看可能不会太深,但像我一样的小白应该都能看懂。
这篇博客主要是写给新手的,希望大家都能学懂学好,嘿嘿,写的不好还望大佬勿喷。
小白来学C语言之结构体相关推荐
- c语言printf结构体,小白来学C语言之结构体
定义和使用结构体变量 自己建立结构体类型 用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体 声明一个结构体类型的一般形式为: struct 结构体名 { 成员表列 }; ******** ...
- 【Golang第8章:面向对象编程】Go语言的结构体是什么,怎么声明;Golang方法的调用和声明;go语言面向对象实例,go语言工厂模式;golang面向对象的三大特性:继承、封装、多态
介绍 这个是在B站上看边看视频边做的笔记,这一章是Glang面向对象编程 这一章内容较多,内容有Go语言的结构体是什么,怎么声明:Golang方法的调用和声明:go语言面向对象实例,go语言工厂模式: ...
- c语言结构体成员变量私有化,C语言中结构体变量私有化详解
C语言中结构体变量私有化详解 背景介绍 操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 什么是结构体? 在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚 ...
- c语言将结构体转换为字符串,[流畅的 C]C语言将结构体转化为字符串
[流畅的 C] C语言将结构体转化为字符串 本文并非标题的具体实现.而是提供一种编程方式,习惯,一种探讨. 本文有一点点门槛,有 socket,开源协议栈学习/开发经验者阅读更佳. Overview ...
- C 语言编程 — 结构体的数据类型转换
目录 文章目录 目录 数组类型强制类型转换为结构体 结构体之间的强制类型转换 数组类型强制类型转换为结构体 先看一个例子: #include <stdio.h>int main(void) ...
- 【C 语言】结构体 ( 结构体 数组 作为函数参数 | 数组 在 堆内存创建 )
文章目录 一.结构体 数组 作为函数参数 ( 数组 在 堆内存创建 ) 二.完整代码示例 一.结构体 数组 作为函数参数 ( 数组 在 堆内存创建 ) 在上一篇博客 [C 语言]结构体 ( 结构体 数 ...
- 【剑仙教程】易语言的结构体。自定义数据类型。
1楼. [剑仙教程]易语言的结构体.自定义数据类型. 在易语言中,有基本数据类型,自定义数据类型. 自定义数据类型,在C语言/C++中称为结构体.这是面向对象和类的编程. . . 先上代码.打开易语言 ...
- C 语言中结构体强制转换--实验
2019独角兽企业重金招聘Python工程师标准>>> 对于C语言中结构体强制转换做了如下实验, 或许可以解惑一些问题 对于结构体, 我理解的属性有: 成员的顺序, 成员的类型,成员 ...
- java接收c语言的结构体
java接收c语言的结构体 DataInputStream inputStream = new DataInputStream(s.getInputStream()); int read = 0; i ...
最新文章
- Jackson 框架,轻易转换JSON
- Android权限处理,Android校招面试指南
- 【bzoj2434】[Noi2011]阿狸的打字机 AC自动机+Dfs序+树状数组
- AutoCAD 2013
- 【Python】Python时间序列之calendar模块
- php七牛分片上传_利用七牛的php SDK分片上传时如何处理Notify?
- 元祖python_python---tuple元祖
- C语言数组越界导致无限循环
- Delta3d组件机制
- php ios支付宝不回调,支付宝 支付成功 ios 不回调
- xtrabackup 备份
- iBatis 基础知识
- VS2010中配置OpenGL的一些问题小结
- python 多行字符串缩进_Python多行字符串的正确缩进
- 限时,字节Java程序性能优化宝典大全,这才叫真正的性能优化
- SanDisk cz48 16G TLC U盘量产经验分享
- 浙江大学三位一体招生?
- linux oracle实例名查看,Linux环境下oracle数库库改名,实例改名
- 怎么看计算机内存和独显,电脑独立显卡或集成显卡的显存大小怎么查看?
- 带着孩子学数学--经验总结1:乘法怎么教,小学数学阶段等等
热门文章
- 思科计算机网络题目及翻译3,思科计算机网络题目及翻译1.doc
- php检查运算是否错误,用PHP中的@运算符抑制错误
- 一份完整的问卷模板_如何写出一份优秀的个人简历?
- centos php mcrypt_Centos 建议使用epel源
- mysql 级联 binlog_MySQL binlog详解
- day43,使用朋友pyMySQL连接数据库
- 如何用golang获取linux上文件的访问/创建/修改时间
- ASP.NET的学习之asp.net整体运行机制
- Entity Framework ---初见
- ACM MM 2021 北航鹏城实验室提出 SOD 新方法:互补三边解码器网络(CTDNet),兼顾高性能和高效率...