C语言中结构体与联合体的简单用法
扫描二维码
随时随地手机看文章
摘要:本文简要分析结构体、联合体2种特殊的数据类型,结合链表和结构体的综合运用,详细注释创建链表的计算机执行和处理的过程,并对一些概念结合代码举例分析,指出常见错误和问题。
结构体
结构体是一种特殊的数据类型,它可以将很多数据类型打包,然后只要操作该结构体的指针变量便可以轻松的访问该结构体内其他的数据。
举例如下:
struct student
{
char name[8];
int age;
char depart[20];
float grade;
}freshman ;
student是结构名,大括号内为该结构体打包的数据类型。如果定义 struct student *p=freshman.name,则引用变量p可以指向结构体*p的存储空间首地址。
①成员运算符“.”运行级别高于“*”,所以*p.name表示*(p.name)。
②定义结构体要在末尾加“;”。
例:简单的机构体赋值和应用
#include <stdio.h>
int main()
{ //定义一个结构体a;
struct student
{
char name[8];
int age;
char sex[4];
char depart[20];
float grade1,grade2,grade3;
}a;
printf("nName:"); //输入结构体a中的成员name,接着打印到终端
scanf("%s", a.name); 此处引用的方式是:结构体变量.成员名
printf("n%sn",a.name);
return 0;
}
例:定义结构体数组,调用结构体内数据
结构体数组的成员有三种访问方式:
①结构体变量.成员名
②(*结构体指针变量).成员名
③结构体指针变量->成员
#include <stdio.h>
struct stu //定义结构体数组及结构体的初始化
{
int num;
char *name;
char sex;
float score;
}pupil[5]={
{101,"Tom",'M',45.8},
{102,"Mike",'M',62.5},
{103,"Chris",'F',92.5},
{104,"Rose",'F',87.6},
{105,"Nate",'M',58.8}
};
void avg(struct stu *ps) //声明无返回值的函数avg,定义其参数是一个结构体指针变量。
{
int c=0,i; //定义两个整型c,i;
float ave,s=0; //定义两个浮点型变量ave,s
for(i=0;i<5;i++,ps++) // i表示循环的次数
{
s+=ps->score; //s表示学生成绩的和
if(ps->score<60) c+=1; //c表示不及格的学生数数目
}
printf("s=%.3fn",s); //打印学生成绩的和
ave=s/5; //ave计算学生的平均成绩
printf("average=%.3fncount=%dn",ave,c);
}
int main()
{
struct stu *ps; //定义结构体变量*ps 目的是在内存空间中取一个连续的栈空间,大小是sizeof( struct stu),并将内存的首地址赋值给ps
ps=pupil; //将pupil的地址赋值给ps 将ps的指向定位到具体的结构体数据头处,即给*ps赋值操作,将数据连续写入内存的栈空间中
avg(ps); //将ps赋值,调用函数avg
return 0; //返回mian函数开始执行处
}
结构体指针变量做函数参数的好处:直接减少压栈次数,效率比多次压栈效率高,调用方便。
链表与数组相比:
①链表的数据空间可以任意分配,而数组是一段连续的地址空间
②链表相比数组占用空间大
③链表方便对数据的搜索,删除和插入等
单向链表的创建:
每个节点包含了数据和一个指向下一个节点头的地址
data
pNext
data
pNext
data
pNext
data
NULL
head
例:函数实现:输入一个变量n就能够创建n个节点
struct stu
{
int age;
int num;
struct stu *next;
};
struct stu *creat(int num) //假设将要创建的个数,返回一个结构指针
{
struct stu *head,*pf,*pb;
int n;
for(n=1;n<=num;n++)
{
printf(“please input the %d student’s age and num info:n”n);
pb=(struct stu *)malloc(sizeof(struct stu));//在内存中申请一个大小为 struct stu块空间,并将pb指向这个内存,每次都在指向的内存中的头字节
scanf(“%d %d”,&pb->age,&pb->num); //给内存中输入第n个学生的信息
if(i==1)
head=pb; //第一个学生时,将块空间头指针赋值给head指针, head指向第一个节点,为了返回而不会发生变化
else
pf->next=pb; //其他学生时,将pb赋值给前个空间内的节点指针空间,pf表示的是上一个节点的头指针
pb->next=NULL; //将申请的内存块内的指针变量next赋值为空
pf=pb; //将头指针赋值给pf,和上一个pf的操作综合看来pf指针其实是个交换地址的中间变量
}
return (head); //返回第一个节点的地址
}
计算机中的函数类比数学中的函数:对应于数学中的函数Y=F(X),计算机中的参数和X表示同一种变量,返回值可以类比于Y,我们平时编程序的核心就是实现F的功能。
计算机中和数学中唯一不相同的一点是,计算机更加注重数据的格式,以及返回值类型等,这个源于计算机是二进制数表示形式和硬件性能的有限性。
另外C语言的函数指针和结构体指针等概念将函数的自变量的概念和原理发挥到极点。
联合体
例:定义一个联合体
#include <stdio.h>
int main()
{
union{ //定义联合体变量number
int i;
struct{
char first;
char second;
}half;
}number;
number.i=0x4241; //给联合体变量number.i赋值
printf("%c%cn", number.half.first, number.half.second);
number.half.first='a'; //联合体引用:联合体变量名.成员名
number.half.second='b';
printf("%xn", number.i);
return 0;
}
注意:
1,联合体是共享内存的,若需要改变结构体half的值,可以通过改变联合体内部i的值来改变;
2,X86存储方式为小端模式,高位存低位,低位存高位。
四字节对齐
struct stu1
{
char name; //name字符占1个字节,age占4字节,name和age对齐
int age;
};
struct stu2
{
char name[2]; //name数组占2个字节,age占4字节,name和age对齐
int age;
};
struct stu3
{
char *name; //*name地址占4个字节,age占4字节,name和age对齐
int age;
};
对于这3个结构体所占用的内存空间是8个字节,因为4字节对齐要求
gcc BUG:
在编译函数尾‘}’后边没有空行的文件提示警告信息:warning: no new line at end of file
处理方法:最后一行加个回车
来源:miaomi1次