最近在学C,感觉从大一就没有好好入门,很难受,趁无聊,学些知识把。
这一节我学习 结构体与共用体
C语言中将用户自己指定的数据结构称为结构体,它相当于其他高级语言中的记录
结构体是一种构造类型,它是由若干“成员”(基本类型or构造类型)组成的。
结构体是一种新的类型,则就需要先对其构造,这里称这种操作为 声明 一个结构体。
声明结构体的过程就好比生产商品的过程,只有商品生产出来才可以使用该商品。
struct 结构体名
{
成员列表(类型名 成员名;)
};
struct关键字表示声明结构,结构体名标志结构体的类型。struct 结构体名 就是结构体类型名。
结构体变量定义必须放在结构体类型定义之后。
什么时候分配内存呢?定义结构体变量后,系统会为其分配内存单元。(系统在进行编译时,仅对变量进行存储空间的分配,并不对结构体类型进行空间分配)
为了使规模较大的程序更便于修改和使用,经常将结构体类型的声明放在一个头文件中,这样在其他源文件中若需要使用该结构体类型,可以用#include命令将该头文件包含到源文件中。
结构体类型中的成员相当于变量的作用。不是结构体相当于变量的作用。
要对节后提变量进行赋值、存取或运算,实质上就是对结构体成员的操作,结构体变量成员的一般形式为: 结构体变量.成员名。
1.结构体变量的初始化 可以在定义时就初始化。
2.结构体数组
struct 结构体名
{
}student[3];
初始化也可以在定义时初始化。
3.实例
1.
//比较计数
#include<stdio.h>
#define N 5
struct order
{
int num; //数字
int con; //顺序
}a[20];
main()
{
int i,j;
for(i=0;i<N;i++)
{
scanf("%d",&a[i].num);
a[i].con=0;
}
for(i=N-1;i>=1;i--)
{
for(j=i-1;j>=0;j--)
{
if(a[i].num<a[j].num)
a[j].con++;
else
{
a[i].con++;
}
}
}
printf("各数的顺序是:\n");
for(i=0;i<N;i++)
{
printf("%3d%3d\n",a[i].num,a[i].con);
}
}
2.
网路成效
01234567890
大姨妈吗
23456789012
假钱
12345678901
#
//信息查询
//从键盘中输入姓名和电话号码,以“#”结束,编程实现输入姓名之后,查询与之对应的电话,
#include<stdio.h>
#include<string.h>
#define MAX 101
struct aa
{
char name[15];
char tel[15];
};
int readin(struct aa *a)
{
int i=0,n=0;
while(1)
{
scanf("%s",a[i].name);
if(!strcmp(a[i].name,"#"))
break;
scanf("%s",a[i].tel);
i++;
n++; //记录的条数
}
return n;
}
void search(struct aa *b,char *x,int n) //查找数组所对应电话号码
{
int i;
i=0;
while(1)
{
if(!strcmp(b[i].name,x))
{
printf("姓名:%s 电话:%s\n",b[i].name,b[i].tel);
break;
}
else
i++;
n--;
if(n==0)
{
printf("Don't seek it!");
break;
}
}
}
main()
{
struct aa s[MAX];
int num;
char name[15];
num=readin(s);
printf("input name");//输入要查找的名字
scanf("%s",name);
search(s,name,num);
}
4.结构体指针变量的声明
struct 结构体名 *结构体指针变量名;
1.使用点运算符引用结构体指针的引用
struct Student *pStruct; //定义结构体指针变量
(*pStruct).成员名 //引用结构体成员 必须使用括号,因为.运算符优先级最高。==student.成员名;
2.使用指向运算符引用结构成员
pStruct->成员名;
==student.成员名;
struct Student student;
struct Student *pStruct;
pStruct=&student;
3.结构体数组指针
此时指针变量的值就是结构体数组的首地址。
struct Student student[5];
struct Student *pStruct;
pStrudy=student;
pStruct=&student[2];
4.结构体作函数的参数
1》使用结构体变量作为函数的参数
使用结构体变量作为函数参数,采取的是“值传递”,会将结构体变量所占的内存单元的内容全部传递给形参,形参也必须是同类型的结构体的变量。
void Display(struct Student stu);
在形参位置上使用结构体变量,但在函数调用期间,形参也要占用内存单元。这种传递方式在空间时间上消耗比较大。
值传递不会返回主调函数中。
2》使用结构体变量的指针作为函数的参数
void Display(struct Student* stu);
这样使用形参stu指针即可引用结构体变量中的成员,因为传递的是变量的地址,若在函数中改变成员中数据,那么返回主调函数是变量会发生改变。
3》使用结构体变量的成员作为函数参数 Display(student.fScore[0]);
掌握这些基础知识后,给个范例理解
指向数组元素的结构体指针运算
设计一个结构体数组,使用指针指向结构体数组,输出各种运算得到的数组元素值。
#include<stdio.h>
struct student
{
int num;
const char *name;
};
main()
{
int i;
struct student stu[]={{1,"lily"},{2,"lucy"},{3,"lilei"}};
struct student *p=stu;
printf("stu[0].num=%d\tstu[0].name=%s\n",stu[0].num,stu[0].name);
printf("p->num=%d\tp->name=%s\n",p->num,p->name);
for(i=0;i<2;i++)
{
printf("--stu[%d].num=%d\n",i,--stu[i].num);
}
printf("++(p->name)=%s\n",++(p->name));//成员自加
printf("(++p)->name=%s\n",(++p)->name);//得到下一个元素的地址
printf("stu[(p++)->num].name=%s\n",stu[(p++)->num].name);//得到下一个元素的地址
return 0;
}
共用体
1.共用体变量的定义union关键字
2.引用用.
3.初始化
初始化的值放在一对大括号中,对共用体变量初始化时,只需要一个初始化值就足够了,其类型必须和共用体的第一个成员的类型相一致。
共用体结构类型数据特点:
1.同一个内存段可以存放几种不同类型的成员,但是每一次只能存放其中一种类型,而不是同时存放所有类型。
即在共用体中,只有一个成员起作用,其他成员不起作用。
2.共用体变量所占的内存空间等于其中最大成员变量所占的内存空间。
3.共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后,原有的成员就失去作用。
4.共用体变量的地址和其他成员的地址是同一地址
5.不能对共用体变量名赋值,也不能企图引用变量名来得到一个值.
6.不能用共用体变量作为函数的参数或者返回值,当需要在函数间传递共用体时,可以使用指向共用体变量的指针实现。
#include<stdio.h>
union uni
{
char ch[2];
int num;
}word;
main()
{
word.num=0x1234;
printf("十六进制数是:%x\n",word.num);
printf("高字节位的数据是:%x\n",word.ch[1]);
word.ch[1]='b';
printf("现在这个数为:%x\n",word.num);
printf("\n%x\n",98);
}
所以说 共用体可以处理任意类型数据
#include<stdio.h>
union unii
{
int i;
char c;
float f;
double d;
}temp;
main()
{
char TypeFlag;
printf("输入成员类型:\n");
scanf("%c",&TypeFlag);
printf("input a number:\n");
switch(TypeFlag)
{
case 'i':scanf("%d",&temp.i);break;
case 'c':scanf("%c",&temp.c);break;
case 'f':scanf("%d",&temp.f);break;
case 'd':scanf("%lf",&temp.d);
}
switch(TypeFlag)
{
case 'i':printf("%d",temp.i);break;
case 'c':printf("%c",temp.c);break;
case 'f':printf("%f",temp.f);break;
case 'd':printf("%lf",temp.d);
}
printf("\n");
}
说了结构体和共用体,那么下面说一下枚举类型啦
枚举类型
将变量的值一一列举出来。(枚举出的值为常量)
1.定义枚举类型enum
enum weekday
{
sun,mon,tue,wed,thu,fri,sat,
}workday,weekend;
2.定义枚举类型变量 赋值直接赋给其中一个枚举的值
默认初始值从0开始递增,即从上一个标识符开始递增,不管上上一个标识符是多少。
虽然默认值是整数,但是不能使用整数对枚举类型的变量进行赋值,因为他们属于不同的类型,若对他进行强制类型转换,就可以进行赋值了。
eg:workday=(enum weekday)2; <==>workday=tue;
//输出星期几的范例
#include<stdio.h>
enum week{sunday,monday,tuesday,wednesday,thursday,friday,saturday};
main()
{
week day;
printf("input the number of weekday(0-6):\n");
scanf("%d",&day);
switch(day)
{
case sunday:printf("sunday");break;
case monday:printf("monday");break;
case tuesday:printf("tuesday");break;
case wednesday:printf("wednesday");break;
case thursday:printf("thursday");break;
case friday:printf("friday");break;
case saturday:printf("saturday");break;
}
}