c语言如何建立工程6,c语言解析系列(6)用户建立自己的数据类型

H:用户建立自己的数据类型

(一)结构体

定义结构体

Struct结构体名

{

类型 数据1

类型 数据2

……

类型 数据N

}结构体变量名;

可以把结构体看做一个特殊的int类型的数据,只不过它里面又包含了多个类型的数据,结构体的初始化,引用如下所示。

方式一:#include

struct student

{

int num;

char name[10];

double math;

};

int main()

{

struct student a;

char name[20]="qwert";//初始化姓名

a.num=1;

strcpy(a.name,name);/*用复制函数将姓名复制进入结构体,在初学时易a.name=”qwert”的错误*/

a.math=80.5;

printf("num=%d name=%s math=%lf",a.num,a.name,a.math);

getch();

return 0;

}

方式二:

#include

struct student

{

int num;

char name[10];

double math;

}a={1,"qwert",80.5};

int main()

{

printf("num=%d name=%s math=%lf",a.num,a.name,a.math);

getch();

return 0;

}

方式三:

#include

struct student

{

int num;

char name[10];

double math;

};

int main()

{

struct student a,*b;

char name[20]="qwert";

a.num=1;

strcpy(a.name,name);

a.math=80.5;

b=&a;

printf("num=%d name=%s math=%lf",b->num,b->name,b->math);

getch();

return 0;

}

解析:1):方式一和方式二差别不是太大,一看就懂了,方式三是结构体和指针的结合使用。

2):要学会”.”运算符和在引用含有指针变量的结构体时用“->”运算符。

3):此外还要知道结构体所占字节数;上面例子中的结构体所占字节是24,它是基本数据类型的整数倍。在此例子中double类型数据为基本类型,4+10+8=22,它是基本类型的整数倍,所以结果是24。

4):知道了结构体如何定义、引用就会知道公用体和枚举的定义引用方法,因为它们是相同的。

(二)共用体(联合体)

共用体的定义,引用方式和结构体相同。

共用体的特殊之处

1):所谓共用体,就是申请一块内存,一起共享这块内存。

2):这块内存的大小是共用体中最大类型的数据所占的内存。

#include

union student

{

int num;

char name[10];

double math;

};

int main()

{

unionstudent a,*b;

char name[20]="qwert";

a.num=1;

strcpy(a.name,name);

a.math=80.5;

b=&a;

printf("num=%d name=%s math=%lf\n",b->num,b->name,b->math);

printf("%d ",sizeof(union student));

getch();

return 0;

}

在该例子中试图给该公用体所有的变量赋值,但结果以最后一次赋值的结果为最终结果,这就是共用体的妙处。它是以最后一次赋值的结果为最终结果,因为它们公用一块内存,当该内存再次写入以前写入的就被覆盖了。

它所占内存的大小是16字节,以为char name[10]为10个字节,但它是基本数据类型double的整数倍,所以是16字节

(三)枚举

枚举的定义,引用方式和结构体相同。

枚举的特殊之处

1):编译系统把枚举元素当做常量处理,从零开始,如果对某个枚举元素赋值,该枚举元素就为所赋的值,它以后的枚举元素就在它的基础上依次增加。

2)它可以用做判断比较。

(四)链表

所谓链表,就是一个数据链,它能把数据穿在一起,可以做到抓住头,找到尾,能把所有数据过滤一遍,它非常重要。

在学习链表的过程中,要结合例子,理解链表。理解某些主要程序语句的意思,这些主要程序语句是把链表穿起来的关键,其他的能看懂就可以,因为这些主要程序语句的逻辑新很强,理解起来很有难度,我在学习链表的过程中,曾把例子抄写下来,一遍又一遍,每一遍的抄写都是我对链表的理解更深一层。把这个链表模板给出以便学习思考。

蓝色部分为主要程序语句,它是和动态内存分配结合在一起的,用到结构体,指针,循环,等的知识。

#include

#include

//保留数据的节点

typedef struct node

{

int data;

struct node *next;

}Node;

//链表的管理节点,包括表头和链表节点的数量

typedef struct nodectrl

{

Node *head;

int num;

}NodeCtrl;

//申请管理节点的空间,并初始化表头和节点数量值

NodeCtrl *CreateCtrl()

{

NodeCtrl *nc = (NodeCtrl*)malloc(sizeof(NodeCtrl));

if(nc == NULL)

{

puts("Create NodeCtrl failed!");

return NULL;

}

//由于刚建立管理节点,链表中没有任何节点

nc->head = NULL;

nc->num = 0;

return nc;

}

//根据管理节点内存位置,加入一个新的数据(数据节点)

int AddData(NodeCtrl *nc,int data)

{

Node *p,*q;

if(nc == NULL)

return -1;

//新申请一个Node节点,用来保留data数据

q = (Node*)malloc(sizeof(Node));

if(q == NULL)

return -1;

//保留数据

q->data = data;

q->next = NULL;

//找到链表的头节点,准备插入数据

p = nc->head;

//插入数据(头插法)

if(p != NULL)

q->next = nc->head;

nc->head = q;

//由于增加了一个节点,所以节点数量需要加1

nc->num++;

return 0;

}

//根据管理节点,显示表头所在链表中的所有存储值

void Display(NodeCtrl *nc)

{

Node *p = NULL;

if(nc == NULL)

return;

printf("Current list has %d data!\n",nc->num);

//num记录的是节点数量,如果为0,表示是空表,否则有数据

if(nc->num > 0)

{

//找到表头

p = nc->head;

//如果节点不空

while(p != NULL)

{

printf("%d\n",p->data);

p = p->next;

}

}

}

//释放管理节点保留的链表,先释放链表,在释放管理节点

void FreeNodeCtrl(NodeCtrl *nc)

{

//定义两个临时指针,q负责保留上次的节点,p负责向下寻找下一个节点

Node *p,*q;

if(nc == NULL)

return;

//如果num大于0,表示链表中有大于等于1个节点,所以必须释放

if(nc->num > 0)

{

//找到管理节点保存的链表表头

p = nc->head;

//如果节点不空

while(p != NULL)

{

//先保留p节点的地址

q = p;

//p节点向下移动,此时q在p上一个节点位置

p = p->next;

//释放p节点的上一个节点

free(q);

}

}

//链表节点释放完毕,将管理节点的数据清0

nc->head = NULL;

nc->num = 0;

//释放管理节点

free(nc);

}

int main()

{

int i,data;

NodeCtrl *nc1 = CreateCtrl();

NodeCtrl *nc2 = CreateCtrl();

for(i=0;i<3;i++)

{

scanf("%d",&data);

AddData(nc1,data);

}

for(i=0;i<20;i++)

AddData(nc2,i);

Display(nc1);

FreeNodeCtrl(nc1);

Display(nc2);

FreeNodeCtrl(nc2);

return 0;

}

(五)宏定义和typedef类型

typedef可以创造新的数据类型,用以避免数据类型不足时产生的尴尬。就我现在所接触到的最多的就是这样的类型:

1):Typedefstructstudent

{

Int num;

Double score;

Charname;

}stu;

这定义了一个结构体类型,stu内包含了多个数据类型,在程序中若出现stu,就表示这样的一个数据类型;

#include

typedef int (*fp) (int x,int y);

int call(fp p,int x,int y)

{

return p(x,y);

}

int add(int x,int y)

{

return x+y;

}

int main()

{

fp p;

printf("%d",call(add,2,3));

getch();

return 0;

}

此例子用到typedef创建新类型,和函数回调以及指针的知识

2):#definen100;

宏定义的define是典型的“后替前”,即当程序中出现n时,就会用100代替,用在程序中可以做到“一改全改”的效果,避免了程序在某些情况下繁琐的修改过程,节省了时间,提高了效率。

简单的代换

#include

#define MYINTint x,

int main()

{//当遇到MYINT时,int x,就代替了MYINT

MYINT a,b;//后代替前

x=2;

printf("x=%d\n",++x);

getch();

return 0;

}

通过下面这个例子大家可以理解代替的深层含义

#include

#define swap(x,y)x*y

int main()

{

int a=3,b=7;

printf("a=%d\na=%d",swap(a,b),swap(a+1,b));

getch();

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值