C语言之用户自己建立的数据结构

C语言之用户自己建立的数据结构

结构体的声明和使用

结构体的声明
struct 结构体名{
    
      
   ...  
   成员表列  
   ...
}变量名表列
结构体的使用方法

struct 结构体名 变量名 = {成员表列};
可以使用变量名.成员名 来访问某个数据
也可以使用 结构体指针->成员名来访问某个数据
结构体指针变量p用p->field或(*p).field指向结构体里面的内容
结构体变量p用p.field指向结构体里面的内容

结构体变量的使用示例
#include <stdio.h>
#include <string.h>
//根据成绩高低输出结构体
struct student{
    
    
    int id;
    char name[20];
    float score;
};

int main(){
    
    
    //定义结构体变量student1,student2,temp
    struct student student1,student2,temp;
    //定义结构体指针student3指向student1
    struct student *student3 = &student1;
    //输入id name 和score
    //结构体指针用p->field或(*p).field 结构体用p.field指向结构体里面的内容
    //scanf("%d%s%f",&student3->id,student3->name,&student3->score);
    scanf("%d%s%f",&(*student3).id,(*student3).name,&(*student3).score);
    scanf("%d%s%f",&student2.id,student2.name,&student2.score);
    /**
    交换算法 也可以用memcpy方法
    memcpy(&temp,&student1,sizeof(student1));
    memcpy(&student1,&student2,sizeof(student2));
    memcpy(&student2,&temp,sizeof(temp));
    **/
    if(student1.score<student2.score){
    
    
        temp = student1;
        student1 = student2;
        student2 = temp;
    }
    //按大小交换排序后 输出两个结构体的详细内容
    printf("id=%d name=%s score=%.2f\n",student1.id,student1.name,student1.score);
    printf("id=%d name=%s score=%.2f",student2.id,student2.name,student2.score);
	return 0;
}

结构体数组的声明和使用

结构体数组的声明
struct student
{
    
    
   int id;
   char name[20];
   float score;
};
struct student stu[6]= {
    
    {
    
    1001,"LI MING",86},{
    
    1002,"LI HUA",80},{
    
    1003,"LIU MING",79},
       {
    
    1004,"ZHANG MING",85},{
    
    1005,"WANG MING",90},{
    
    1006,"LI LIN",87}};

实际的使用方法和数组的使用是一样的
比如:需要使用第一个成员的score变量 就使用stu[0].score来访问
结构体的拷贝可以直接使用memcpy函数进行拷贝

结构体数组的使用
#include <stdio.h>
#include <string.h>
//根据成绩高低输出学生结构体
struct student
{
    
    
    int id;
    char name[20];
    float score;
};

int main()
{
    
    
    //定义结构体数组stu
    struct student stu[6]= {
    
    {
    
    1001,"LI MING",86},{
    
    1002,"LI HUA",80},{
    
    1003,"LIU MING",79},
        {
    
    1004,"ZHANG MING",85},{
    
    1005,"WANG MING",90},{
    
    1006,"LI LIN",87}
    };
    struct student temp;
    int i,j,k;
    //冒泡排序
    for( i = 0 ; i < 4; i ++)
    {
    
    
        k = i;
        for(j=i+1; j<5; j++)
        {
    
    
            //如果后者的分数比前者高
            if(stu[k].score<stu[j].score)
            {
    
    
                k = j;
            }
        }
        if(k != i)
        {
    
    
            //交换两个结构体
            temp = stu[i];
            stu[i] = stu[k];
            stu[k] = temp;
        }
    }
    //按分数从大到小输出
    for( i = 0 ; i < 6; i ++)
    {
    
    
        printf("id=%d name=%s score=%.2f\n",stu[i].id,stu[i].name,stu[i].score);
    }
	return 0;
}

结构体指针的声明和使用

结构体指针的声明

结构体指针就是一个指向结构体变量的指针变量
使用方法和特点与正常的数组指针是一样的
结构体指针变量p用p->field或(*p).field来指向结构体里面的内容

struct student{
    
    
    int id;
    char name[20];
    float score;
};
struct student stu[6]= {
    
    {
    
    1001,"LI MING",86},{
    
    1002,"LI HUA",80},{
    
    1003,"LIU MING",79},
        {
    
    1004,"ZHANG MING",85},{
    
    1005,"WANG MING",90},{
    
    1006,"LI LIN",87}
    };
struct student *temp=stu;
结构体指针的使用
#include <stdio.h>
#include <string.h>
//根据成绩高低输出结构体
struct student{
    
    
    int id;
    char name[20];
    float score;
};
//定义一个结构体数组
struct student stu[6]= {
    
    {
    
    1001,"LI MING",86},{
    
    1002,"LI HUA",80},{
    
    1003,"LIU MING",79},
        {
    
    1004,"ZHANG MING",85},{
    
    1005,"WANG MING",90},{
    
    1006,"LI LIN",87}
    };
int main(){
    
    
    //用结构体指针去循环输出结构体数组中的全部内容 p->field等价于(*p).field
    for(struct student *temp=stu ;temp<stu+6;temp++){
    
    
        //printf("id=%d name=%s score=%.2f\n",temp->id,temp->name,temp->score);
        printf("id=%d name=%s score=%.2f\n",(*temp).id,(*temp).name,(*temp).score);
    }
	return 0;
}

链表及相关应用

单链表及相关应用

单链表:本质上是一个含有一个结构体指针的结构体
这个结构体指针在没有后继节点的时候指向为NULL
一旦有后继节点 则该结构体指针指向后继节点的首地址
单链表判断队尾 就是该节点的指向后继节点的指针指向为NULL 这就是达到了队尾的标志 此时p->next=NULL
以下代码为单链表的基础用法 包括 单链表节点的声明/交换/遍历

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//单链表及相关应用
//定义单链表
struct student{
    
    
    int id;
    char name[20];
    float score;
    struct student *next ;
};
char *str[] = {
    
    "1st" , "2nd" , "3rd"};
int main(){
    
    
    //先初始化第一个节点 next值为空
    struct student stu1 = {
    
    1001,"LI MING",86,NULL};

    printf("1st node is id=%d name=%s score=%.2f\n",stu1.id,stu1.name,stu1.score);
    //初始化第二个节点 next值为空 使用malloc 动态分配内存给temp指向的结构体变量
    struct student *temp =(struct student *) malloc(sizeof(struct student));
    temp->id=1002;
    strcpy(temp->name,"LI HUA");
    temp->score=95;
    temp->next=NULL;
    //第一个节点的next值设置为第二个节点
    stu1.next=temp;
    printf("2nd node is id=%d name=%s score=%.2f\n",stu1.next->id,stu1.next->name,stu1.next->score);
    //初始化第三个节点 next值为空
    struct student *temp1 =(struct student *) malloc(sizeof(struct student));
    temp1->id=1003;
    strcpy(temp1->name,"LIU QIANG");
    temp1->score=90;
    temp1->next=NULL;
    //将第一个节点的next指向的第二个节点的next值设置为第二个节点
    stu1.next->next=temp1;
    printf("3rd node is id=%d name=%s score=%.2f\n",stu1.next->next->id,stu1.next->next->name,stu1.next->next->score);
    //交换第二个节点和第三个节点
    //保存头节点地址
    struct student head = stu1;
    //存储两个节点的值
    //拿temp2储存一个节点
    struct student *temp2 =(struct student *) malloc(sizeof(struct student));
    temp2 = head.next;
    head.next = head.next->next;
    head.next->next=temp2;
    head.next->next->next=NULL;
    //遍历链表
    struct student *p;
    int i=0;
    //如果p指向NULL那就表示遍历结束 到达链表尾部
    for(p=&head;p!=NULL;p=p->next,i++){
    
    
        printf("%s node is id=%d name=%s score=%.2f\n",str[i],p->id,p->name,p->score);
    }
	return 0;
}

交换两个节点需要按照如上代码 修改两个节点的next指针的指向 还要用中间变量保存一个节点的内容

双链表及相关应用

双链表:本质上是一个含有两个结构体指针的结构体
一个结构体指针head指向前一个节点的首地址
另一个结构体指针next指向后一个节点的首地址
双链表判断队头 就是该节点的指向前一个节点的指针指向为NULL 这就是达到了队头的标志 此时p->head=NULL
双链表判断队尾 就是该节点的指向后继节点的指针指向为NULL 这就是达到了队尾的标志 此时p->next=NULL
以下代码为双链表的基础用法 包括 双链表节点的声明/交换/遍历

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//双链表及相关应用
//定义双向链表
struct student{
    
    
    int id;
    char name[20];
    float score;
    struct student *next,*head;
};
char *str[] = {
    
    "1st" , "2nd" , "3rd"};

int main(){
    
    
    //先初始化第一个节点 next值为空
    struct student stu1 = {
    
    1001,"LI MING",86,NULL,NULL};
    printf("1st node is id=%d name=%s score=%.2f\n",stu1.id,stu1.name,stu1.score);
    //初始化第二个节点 next值为空 head值也为空
    struct student *temp =(struct student *) malloc(sizeof(struct student));
    int i=0;
    temp->id=1002;
    strcpy(temp->name,"LI HUA");
    temp->score=95;
    temp->next=NULL;
    temp->head=NULL;
    //第一个节点的next值设置为第二个节点
    stu1.next=temp;
    stu1.next->head=&stu1;
    printf("2nd node is id=%d name=%s score=%.2f\n",stu1.next->id,stu1.next->name,stu1.next->score);
    //初始化第三个节点 next值为空 head值也为空
    struct student *temp1 =(struct student *) malloc(sizeof(struct student));
    temp1->id=1003;
    strcpy(temp1->name,"LIU QIANG");
    temp1->score=90;
    temp1->next=NULL;
    temp1->head=NULL;
    //将第一个节点的next指向的第二个节点的next值设置为第二个节点
    stu1.next->next=temp1;
    stu1.next->next->head=stu1.next;
    printf("3rd node is id=%d name=%s score=%.2f\n",stu1.next->next->id,stu1.next->next->name,stu1.next->next->score);
    //交换第二个结点和第三个结点
    //保存头节点地址
    struct student head = stu1;
    //存储两个节点的值
    //拿temp储存一个节点
    //依次交换head和next的值
    printf("swap 2nd node with 3rd node\n");
    struct student *temp2 =(struct student *) malloc(sizeof(struct student));
    temp2 = head.next;
    head.next = head.next->next;
    head.next->head=&head;
    head.next->next=temp2;
    head.next->next->head=head.next;
    head.next->next->next=NULL;
    //遍历链表
    struct student *p,*rare;
    //如果p指向NULL那就表示遍历结束 到达链表尾部
    printf("traversal from head to rear\n");
    for(i=0,p=&head;p!=NULL;p=p->next,i++){
    
    
        printf("%s node is id=%d name=%s score=%.2f\n",str[i],p->id,p->name,p->score);
        if(p->next==NULL){
    
    
            rare = p;
        }
    }
    printf("traversal from rear to head\n");
    for(i=0;rare!=NULL;rare=rare->head,i++){
    
    
        printf("%s node is id=%d name=%s score=%.2f\n",str[i],rare->id,rare->name,rare->score);
    }
	return 0;
}

交换两个节点需要按照如上代码 修改两个节点的next和head指针的指向 还要用中间变量保存一个节点的内容

循环链表及相关应用

循环链表:本质上是一个含有一个结构体指针的结构体
这个一个结构体指针一般指向后一个节点的首地址
循环链表和单链表的不同之处在于 该表中最后一个结点的指针域指向头结点,整个链表形成一个环,故称循环链表。
判断循环链表为空的标准在于 head==head->next; 头节点等于头结点的后继节点
以下代码为循环链表的基础用法 包括 循环链表节点的声明/交换/遍历

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//循环链表及相关应用
//定义循环链表
struct student{
    
    
    int id;
    char name[20];
    float score;
    struct student *next;
};
char *str[] = {
    
    "1st" , "2nd" , "3rd"};
int main(){
    
    
    //先初始化第一个节点 next值为空
    struct student stu1 = {
    
    1001,"LI MING",86,NULL};
    struct student *headnode= &stu1;
    printf("1st node is id=%d name=%s score=%.2f\n",stu1.id,stu1.name,stu1.score);
    //初始化第二个节点 next值为空
    struct student *temp =(struct student *) malloc(sizeof(struct student));
    temp->id=1002;
    strcpy(temp->name,"LI HUA");
    temp->score=95;
    temp->next=NULL;
    //第一个节点的next值设置为第二个节点
    stu1.next=temp;
    stu1.next->next=&stu1;
    printf("2nd node is id=%d name=%s score=%.2f\n",stu1.next->id,stu1.next->name,stu1.next->score);
    //初始化第三个节点 next值为空
    struct student *temp1 =(struct student *) malloc(sizeof(struct student));
    temp1->id=1003;
    strcpy(temp1->name,"LIU QIANG");
    temp1->score=90;
    temp1->next=NULL;
    //将第一个节点的next指向的第二个节点的next值设置为第二个节点
    stu1.next->next=temp1;
    stu1.next->next->next=&stu1;
    printf("3rd node is id=%d name=%s score=%.2f\n",stu1.next->next->id,stu1.next->next->name,stu1.next->next->score);
    //交换第二个节点和第三个节点
    //保存头节点地址
    struct student head = stu1;
    //存储两个节点的值
    //拿temp储存一个节点
    struct student *temp2 =(struct student *) malloc(sizeof(struct student));
    temp2 = head.next;
    head.next = head.next->next;
    head.next->next=temp2;
    head.next->next->next=&head;
    //遍历循环链表
    struct student *p=&head;
    int i=0;
    //如果p的next指向循环链表的头那就表示遍历结束 即到达链表尾部
    do{
    
    
        printf("%s node is id=%d name=%s score=%.2f\n",str[i],p->id,p->name,p->score);
        p=p->next;
        i++;
    }
    while(p!=&head);
	return 0;
}
链表的小结
  1. 链表就是含有结构体指针的一个有序的结构体串
  2. 链表主要分为三种 单链表/双链表/循环链表
  3. 因为单链表是顺序储存的 所以单链表适合顺序查找和顺序遍历
  4. 因为双链表是顺序储存的 所以双链表也适合顺序查找和双向的遍历
  5. 因为循环链表是顺序储存的 所以循环链表也适合顺序查找和顺序遍历
  6. 单链表和双链表本质都是差不多的 唯一需要注意的地方就是交换新增节点时的指针的修改
  7. 循环链表和单/双链表的区别就是 循环链表是一个环形结构,整个链表头尾相连,成环

栈及相关应用

栈的基本性质
  1. 栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。
  2. 栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为先进后出表。
  3. 栈具有先入后出的性质 栈内元素具有FILO(先入后出)的特性
  4. 在计算机中 通常用来保存程序的入口和参数 以及函数内的临时变量
  5. 栈有大小 栈中存放的数据数量不能超过栈中可以存放的数目 超过就会出现栈的溢出的问题 导致程序乃至系统崩溃
栈的基本应用

以下代码为栈的基础用法 包括 栈的进栈函数push()/出栈函数pop()/返回栈顶函数top()/清空栈的函数clear()

#include <stdio.h>
//用数组模拟栈 FILO 先入后出

//元素elem进栈
int push(int* a,int top,int elem){
    
    
    a[++top]=elem;
    return top;
}
//数据元素出栈
int pop(int * a,int top){
    
    
    if (top==-1) {
    
    
        printf("空栈");
        return -1;
    }
    printf("出栈元素:%d\n",a[top]);
    top--;
    return top;
}
//tops方法返回栈顶元素
int tops(int * a,int top){
    
    
    if (top==-1) {
    
    
        printf("空栈");
        return -1;
    }
    return a[top];
}
int main() {
    
    
    int a[100];
    int top=-1;
    //通过push入栈 通过top查看入栈情况
    top=push(a, top, 1);
    printf("栈顶元素 %d\n",tops(a,top));
    top=push(a, top, 2);
    printf("栈顶元素 %d\n",tops(a,top));
    top=push(a, top, 3);
    printf("栈顶元素 %d\n",tops(a,top));
    top=push(a, top, 4);
    printf("栈顶元素 %d\n",tops(a,top));
    //通过pop函数 按先入后出的顺序弹出入栈的元素
    top=pop(a, top);
    top=pop(a, top);
    top=pop(a, top);
    top=pop(a, top);
    top=pop(a, top);
    return 0;
}

队列及相关应用

队列的基本性质
  1. 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。
  2. 进行插入操作的端称为队尾,进行删除操作的端称为队头。
  3. 队列具有先入先出的性质 队列内元素具有FIFO(先入先出)的特性
  4. 在计算机中 用于调节不同读写数据的部分的工作情况 例如:打印机依照打印序列顺序打印缓冲区的多个文件 CPU调度算法中的时间片轮转算法 就是队列在计算机方面的多种应用
  5. 队列是现用现申请存储区间的线性链表 因而也不存在溢出等问题。
队列的基本应用

以下代码为队列的基础用法 包括 队列的进队列函数push()/出队列函数pop()/返回队列顶函数top()/清空队列的函数clear()

#include <stdio.h>
#include <string.h>
//用数组模拟队列 FLFO 先入先出

//入队 返回队列尾部位置
int push(int *a,int rear,int data){
    
    
    a[rear]=data;
    rear++;
    return rear;
}
//出队 返回目前的队列头位置
int pop(int *a,int front,int rear){
    
    
   if(front==rear){
    
    
    return 0;
   }
    printf("出队元素:%d\n",a[front]);
    return front+1;
}
//返回队顶元素
int top(int *a,int front,int rear){
    
    
    if(front==rear){
    
    
    return 0;
    }
    else{
    
    
        return a[front];
    }
}
void clear(int *a,int front,int rear){
    
    
    //如果 front==rear,表示队列为空
    while (front!=rear) {
    
    
        printf("出队元素:%d\n",a[front]);
        front++;
    }
    //全部初始化
    memset(a,'\0',100*sizeof(int));
}
int main() {
    
    
    int a[100];
    int front,rear;
    //设置队头指针和队尾指针,当队列中没有元素时,队头和队尾指向同一块地址
    front=rear=0;
    //入队
    rear=push(a, rear, 1);
    rear=push(a, rear, 2);
    rear=push(a, rear, 3);
    rear=push(a, rear, 4);
    //top 输出队列顶部元素
    top(a,front,rear);
    //出队方法1 pop 一次出一个
    front = pop(a,front,rear);
    front = pop(a,front,rear);
    //出队方法2 clear 一次出完
    clear(a, front, rear);
    return 0;
}

共用体类型的声明和使用

共用体类型的声明

共用体类型的声明

扫描二维码关注公众号,回复: 17341528 查看本文章
union 共用体名{
    
      
   ...  
   成员表列  
   ...
}变量表列

共用体的使用方法和结构体一样的
就是用共用体的变量名p p.filed指向p中的某个成员变量
共用体和结构体的区别在于
共用体共用一段内存空间 大小为该结构体内占用内存最大的成员变量的内存大小 在使用之前的最后一次赋值的内容才能启用 之前赋值的会被后续的赋值覆盖
而结构体声明时就开辟了能存放全部的成员变量的内存空间 各个成员之间的赋值和使用互不干扰

共用体类型的使用

以下代码为共用体类型的基础用法 包括 共用体类型的声明/赋值/输出等操作

#include <stdio.h>
//共用体公用一段内存空间 在使用之前的最后一次赋值的内容才能启用 之前赋值的没用
union data{
    
    
    char c;
    int i;
    float f;
    long long l;
};
int main(){
    
    
    union data d;
    d.c='b',d.i=97;
    //此时共用体内最后一次赋值为97 ASCII码对应a
    printf("c is %c and i is %d and f is %f\n",d.c,d.i,d.f);
    //此时共用体大小为最大的成员的大小 long long 64位 字节数为8
    printf("size of union is %d\n",sizeof(union data));
    d.c='g',d.i=101;
    //此时共用体内最后一次赋值为101 ASCII码对应e
    printf("c is %c and i is %d and f is %f\n",d.c,d.i,d.f);
    //此时共用体大小为最大的成员的大小 long long 64位 字节数为8
    printf("size of union is %d",sizeof(union data));
	return 0;
}

枚举类型的声明和使用

枚举类型的声明

枚举类型的声明

enum 枚举名{
    
      
   枚举元素列表
}

比如 enum weekdays{mon,tue,wed,thu,fri,sat,sun};
可以定义一系列合法的枚举类型变量并赋值

 enum weekdays{
    
    mon,tue,wed,thu,fri,sat,sun};
 enum weekdays weekend,weekday;
 weekend = mon ;//mon是枚举类型中定义的枚举元素 赋值合法
 weekday = sunday ;//sunday不是枚举类型中定义的枚举元素 赋值不合法

枚举类型需要注意的内容和特点:

  1. 枚举能够使代码更清晰,更优雅,能清辨的进行循环或者遍历
  2. 枚举使代码更易于维护,能限定变量能使用的值域和范围
  3. 枚举类型的值并不属于任何基础数据类型,不能直接输出到printf语句中,需要转换后才能输出
枚举类型的使用

以下代码为枚举类型的基础用法 包括 枚举类型的声明/赋值/输出等操作

#include <stdio.h>
//枚举相关操作
//从星期六和星期天选一天休息日 和从星期一到星期五选一天非休息日 输出所有可能的排列
// 排列数C52 = 10 所以一共有十种排列
//声明枚举类型weekdays 储存非字符型数据 使用枚举类型主要方便遍历
enum weekdays{
    
    mon,tue,wed,thu,fri,sat,sun};
enum Num{
    
    };
int main(){
    
    
    //定义枚举类型变量
    enum weekdays weekend,weekday ,p;
    int n=0;
    //使用两个枚举类型变量 作为循环的相关参数
    for(weekend=sat;weekend<=sun;weekend++){
    
    
        for(weekday=mon;weekday<=fri;weekday++){
    
    
            if(weekend!=weekday){
    
    
                n++;
                printf("case %d ",n);
                for(int i=0;i<2;i++){
    
    
                    switch(i){
    
    
                        case 0:p=weekend,printf(" weekend is ");break;
                        case 1:p=weekday,printf(" weekday is ");break;
                        default:break;
                    }
                    //枚举类型数据不能直接输出,只能转化后再输出
                    switch(p){
    
    
                        case sun:printf("%s ","SUNDAY");break;
                        case mon:printf("%s ","MONDAY");break;
                        case tue:printf("%s ","TUESDAY");break;
                        case wed:printf("%s ","WEDNESDAY");break;
                        case thu:printf("%s ","THURSDAY");break;
                        case fri:printf("%s ","FRIDAY");break;
                        case sat:printf("%s ","SATURDAY");break;
                        default:break;
                    }
                }
                printf("\n");
            }
        }
    }
	return 0;
}

使用typedef声明新类型名

typedef的定义

既可以简单的用typedef声明一个新类型名来代替原来的数据类型
typedef char Line[81];Line text, secondline;
typedef char* PCHAR;PCHAR pa, pb;
也可以使用typedef来代替一个复杂的数据类型

typedef struct tagPOINT
 {
    
    
    int x;
    int y;
}point;
 point p2 ={
    
    1,2};
 //而不用使用 struct tagPOINT p2 = {1,2};来定义
  1. 使用typedef 可以杜绝声明变量时可能遇到的错误
  2. 用typedef只是对已经存在的类型增加一个类型名,而没有创造新的数据类型
  3. 用typedef与#define 宏定义的效果类似 但是不一样 #define是预编译时期进行文本替换 而typedef只是简单的为数据类型取个别名而已
typedef的使用

以下代码为typedef的基础用法

#include <stdio.h>
//typedef 关键字可以自行定义数据类型
//效果和#define类似 但是不是预编译时期进行文本替换
struct tagPOINT1
 {
    
    
    int x;
    int y;
};
//使用typedef修饰结构体 必须加上别名 不加就不通过编译
typedef struct tagPOINT
 {
    
    
    int x;
    int y;
}point;

int main(){
    
    
    typedef char* PCHAR;
    //char *pa,pb;可能会以为定义了pa pb两个字符指针 容易错误
    //PCHAR pa, pb;就不会出错
    PCHAR pa, pb;
    //正常情况初始化 结构体 需要多输一个struct
    struct tagPOINT1 p1 = {
    
    1,2};
    //使用typedef 每次可以减少一个struct
    point p2 ={
    
    1,2};
    printf("%d\n",sizeof(point));
    //避免重复定义复杂变量
    //不用每次都声明一个字符数组
    typedef char Line[81];
    Line text, secondline;
    gets(text);
    puts(text);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/a695415974/article/details/122525176