结构体和共用体

最近在学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;
		
	}
 } 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值