c语言之特殊类型

本文章对c语言的特殊类型:结构体枚举共同体typedef类型进行讲解

1、结构体

(1)、结构体变量

定义和使用

struct 结构体名称{
    数据类型 变量名;
};
//定义
struct 结构体名称 结构体变量名或者指针;
//使用
结构体变量.变量名
    eg:		student.name;

(2)、结构体数组

定义和使用

struct 结构体名称{
    数据类型 变量名;
}结构体数组名[长度];
eg: 
struct Student{
    int number;
    char name[20];
}stu[3];
//使用
for(int i=0;i<3;i++){
    scanf("%d%s",stu[i].number,stu[i].name);
}

(3)、结构体指针

定义和使用

struct Student(结构体名称){
    数据类型 变量名;
};
//在函数中调用
struct Student stu;

struct Student *p;
p=&stu;
*p2=stu2;
//使用时
p->变量名
    

做参数使用时

struct Student(结构体名称){
    数据类型 变量名;
};
//在函数中调用
void input(struct Student stu2[]);
struct Student stu[10];
struct Student *p;
p=stu;
input(p2);

(4)、结构体链表

一、静态链表

//定义结构体
struct Student{
	int number;
	char name[20];
	struct Student *next;//指向下一个
};

int main(){
	struct Student a,b,c,*head,*p;//假设有三个结构体,是静态的
	//对结构体的变量赋值
	a.number=10101;
	b.number=10103;
	c.number=10106;
	//将链头指向第一个结构体的地址;根据地址连接
	head=&a;
	//将其他的指向下一个
	a.next=&b;
	b.next=&c;
	//最后一个结构体的next指向NULL,说明链表结束 
	c.netx=NULL;
	
//遍历链表
    //先将链头指向一个空的结构体指针
    p=head;
    //设置循环条件!至关重要
	while(p!=NULL){
		//输出链表排列的内容
		printf("%d ",p->number);
		//将链指向下一个链
		p=p->next;
	}
	return 0;
}

二、动态链表(很重要)

#include <stdlib.h>  //这个很重要,因为这里使用了动态存储malloc,free
#include <stdio.h>
//宏定义,定义一个结构体的长度空间
#define KJ sizeof(struct Student)//sizeof(struct Student)是获取一个结构体Student的长度
//定义结构体
struct Student{
	int number;
	char name[20];
	struct Student *next;//指向下一个
};
//因为是动态创建链的内容,所以写一个创建函数,并返回一个链头
struct Student *create(void){
    //定义结构体指针
    struct Student *head,*p1,*p2;
    int n=0;
    //给两个指针变量各自分配一个结构体空间
    p1=p2=(struct Student *)malloc(KJ);
    //有空间了,那就将内容存储进去,动态输入
    //给p1结构体输入内容 
	scanf("%d,%s",&p1->number,&p1->name);
    //现在结构体p1有内容了,要将内容做成一个链
    //首先将链头置为NULL
    head=NULL;
    //设置约定俗成,如果输入的number为0时,则不创建链表
    //循环条件
    while(p1->number!=0){
        n=n+1;
        //将链头指向p1这个结构体
        if(n==1){
            head=p1;
        }
		else{
            //这里比较绕,作用是下一步的p2.next指向最新的链,这里的p1是最新的链
           p2->next=p1;
        }
        //这里很关键!当n=1时,链头实际是指向了p2,p2做为上一个链,然后链接下一个时,是p2.next指向最新的链
        p2=p1;
        p1=(struct Student *)malloc(KJ);
        scanf("%d,%s",&p1->number,&p1->name);
    }
    //结束后,给p2的尾链指向NULL,意味着链表结束,创建完成。
    p2->next=NULL;//如果上面的循环理解了,这一步就知道为什么不是p1.next=NULL。p1表示新输入的链,p2表示原链。
    
    //创建一个链表完成了,只需要返回链头就可以了
    return (head);
}
//主函数的使用
int main(){
    //设置一个结构体链头指针变量,接收创建传过来的链头
    struct Student *head;
    head=create();
    //打印链表(遍历链表)
    while(head!=NULL){
        printf("number=%d\nname=%s\n",head->number,head->name);
        //将当前链指向下一个链
        head=head->next;
    }
    //用完要释放空间
    free(head);
    return 0;
}

2、共用体

(1)、共用体的定义

共用体变量所占的内存长度等于最长的成员的长度。

​ 也就是说:共用一个空间,取最长的长度。第二次输入的内容会覆盖第一次输入的内容。

//定义的方法,和结构体一样,但是功能却不相同。
union 共用体名{//共用体名要遵循标识符命名规则,且一般首字母大写用于区分变量名
    成员列表
}变量列表;

注意:不能初始化几个成员,因为占同一段存储单元!

(2)、共用体的使用

一般用于同一单元,却有不用的内容。例如:把学生所属班级和老师的职务放在同一给存储单元,但因为存储的类型不一致,则需要共同体。

#include <stdio.h>
#include <stdlib.h>
struct{
	int num;
	char name[10];
	char job;
	union{
		int clas;
		char position[10];
	}category;
}person[2];
int main(){
	int i;
	for(i=0;i<2;i++){
		printf("please enter the data of person:\n");
		scanf("%d %s %c",&person[i].num,&person[i].name,&person[i].job);
		if(person[i].job=='s'){
			scanf("%d",&person[i].category.clas);
		}
		else if(person[i].job=='t'){
			scanf("%s",&person[i].category.position);
		}
		else {
			printf("Input error");
		}
	} 
	printf("\n");
	printf("No.  name      sex job class/position\n");
	for(i=0;i<2;i++){
		if(person[i].job=='s'){
			printf("%-6d%-10s%-4c%-10d\n",person[i].num,person[i].name,person[i].job,person[i].category.clas);
		}
		else{
			printf("%-6d%-10s%-4c%-10s\n",person[i].num,person[i].name,person[i].job,person[i].category.position);
		}
	}
	return 0;
} 

3、枚举类型

枚举类型的特殊之处

  1. 一个变量表示几个可能出现的值,比如抽奖活动,变量代表 ’‘票’‘ ,枚举的值代表 ’‘是否中奖,中了几等奖’‘,把可能出现的值一 一列举出来,就是枚举。
  2. 枚举的按顺序第一个元素的值为0,后面一个元素的值都是前面一个元素的值+1;
  3. 枚举类型的元素不能当做变量赋值,只能在内部赋值,且为整数
  4. 枚举的变量可以赋值,但只能赋值为整数

代码演示:

enum 枚举名{枚举元素列表};
enum Weekday{
    sun,mon,tue,wed,thu,fri,sat	//注意:这里用逗号隔开,并且末尾没有分号
};
//定义枚举变量名
enum Weekday weekday;
//以下是错误的赋值写法!
sun=1;
//以下的写法是正确的
weekday=sun;//这里的意思是weekday=0
weekday=1;//这个写法也是正确的

//给枚举类型的元素赋值,只能在内部赋值,也就是定义的时候就赋值了
enum Weekday{
    sun=7,mon=1,tue,wed,thu,fri,sat	//从mon开始,后面一个元素的值都是前面一个元素的值+1;
};

4、typedef 声明新类型名

特点是用新的类型名代替原有的类型名,用简单的类型名代替复杂的类型,使代码更加的精洁

代码演示

//typedef声明普通类型
typedef int Integer;//将Integer做为类型名,作用与int相同
typedef float Fu;//将Fu做为类型名,作用与float一致

//typedef声明结构体
	//原结构体
	struct Student{
        int num;
    }stu;
//用typedef声明	
typedef struct{
    int num;
}Stu;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值