一.结构体的定义
结构体是一种用户自定义的数据类型,用于将多个不同类型的数据组合在一起形成一个新的数据类型。结构体由多个成员变量组成,每个成员变量可以是不同的数据类型,可以是基本数据类型(如整型、浮点型、字符型等)或其他结构体类型。结构体的成员变量在内存中是按照声明的顺序依次存储的。
1.结构体的声明初始化:
结构体是一种数据类型,也就是说可以用它来定义并且存储变量。
结构体是一种数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据、需要存储空间;
struct 结构体名 {
类型 成员1;
类型 成员2;
...
};
1.第一种方式:
struct 结构体名 结构体变量名;
#include <stdio.h>
struct date {
int month;
int year;
int tall;
};
int main()
{
struct date ax1;
ax1.month = 5;
ax1.tall = 180;
ax1.year = 2024;
struct date ax2 = { 5,2024,180 };
struct date ax3 = { ax3.month = 5,ax3.year = 2024,ax3.tall = 180 };
printf("%i\n%i\n%i\n", ax1.month, ax1.tall, ax1.year);
printf("%i\n%i\n%i\n", ax2.month, ax2.tall, ax2.year);
printf("%i\n%i\n%i\n", ax3.month, ax3.tall, ax3.year);
return 0;
}
2.第二种方式:
struct 结构体名{
类型 成员;
类型 成员;
}结构体变量;
#include <stdio.h>
struct date {
int month;
int year;
int tall;
}ax1,ax2,ax3;
int main()
{
// struct date ax1;
ax1.month = 5;
ax1.tall = 180;
ax1.year = 2024;
// struct date ax2 = { 5,2024,180 };
ax2={5,2024,180};
// struct date ax3 = { ax3.month = 5,ax3.year = 2024,ax3.tall = 180 };
ax3={ax3.month = 5,ax3.year = 2024,ax3.tall=100};
printf("%i\n%i\n%i\n", ax1.month, ax1.tall, ax1.year);
printf("%i\n%i\n%i\n", ax2.month, ax2.tall, ax2.year);
printf("%i\n%i\n%i\n", ax3.month, ax3.tall, ax3.year);
return 0;
}
2.结构体与指针的羁绊:
结构体类型指针访问成员的获取和赋值形式:
(1)(*p). 成员名(.的优先级高于*,(*p)两边括号不能少)
(2) p->成员名(->指向符)
1.我们可以在结构体中存储指针:
#include <stdio.h>
struct Node
{
int data;
struct Node* next;
}n1;
int main()
{
n1={10,NULL};
struct Node n2 = {20 , NULL};
printf("%d %p\n",n1.data,n1.next);
printf("%d %p",n2.data,n2.next);
return 0;
}
2结构体类型也可以定义为结构体类型指针:
#include<stdio.h>
struct Inventory
{
char description[10];
int quantity;
};
int main()
{
struct Inventory ax={"anxian",30
};
struct Inventory *stp=&ax;
printf("%s %d\n", stp->description, stp->quantity);
printf("%s %d\n", (*stp).description, (*stp).quantity);
return 0;
}
3.与数据结构的羁绊
1.typedef----首先我们先介绍一个数据结构常客--
它的英文翻译是 “类型定义”。下面就来看看它的用法。
typedef int anxian
此时我们就可以将anxian,来代表int这个数据类型。我们来看代码实现:
#include<stdio.h>
typedef int anxian;
int main()
{
anxian a = 6;
printf("%d",a);
return 0;
}
2.在结构体中的使用:
typedef struct people {
int age;
char sex;
} chinese;
前面的是
typedef int anxian
而这里同理
typeddef struct people chinese
3.现在我们来看单链表
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode* next;
} LinkNode;
在这个单链表的结构体声明中,struct LNode表示链表的结点结构体,包含两个成员变量:
1.ElemType data
:用于存储结点中的数据元素。在这里,ElemType
被定义为 int
类型,因此 data
是一个整型数据成员,用于存储结点中的数据。
2.struct LNode* next
:指向后继结点的指针。这个成员变量是一个指针类型,指向下一个结点的地址。通过这个指针,可以实现链表中结点之间的连接,从而形成链表的数据结构。
因此,整体来看,这个单链表的结点结构体 struct LNode
包含了一个数据成员 data
用于存储数据,以及一个指针成员 next
用于指向下一个结点,从而实现链表中结点之间的连接。这种结构体嵌套结构体的方式,可以方便地表示链表的逻辑结构,使得链表的操作更加方便和灵活。
在这里我补充一点:
结构体里面是有一个数据域和一个指针域 是由数据类型和变量名构成。
int data
struct Lnode * next
#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode* next; //指向后继结点
} LinkNode; //声明单链表结点类型
void CreateListF(LinkNode*& L, ElemType a[], int n)
//头插法建立单链表
{
LinkNode* s;
L = (LinkNode*)malloc(sizeof(LinkNode)); //创建头结点
L->next = NULL;
for (int i = 0; i < n; i++)
{
s = (LinkNode*)malloc(sizeof(LinkNode));//创建新结点s
s->data = a[i];
s->next = L->next; //将结点s插在原开始结点之前,头结点之后
L->next = s;
}
}
void CreateListR(LinkNode*& L, ElemType a[], int n)
//尾插法建立单链表
{
LinkNode* s, * r;
L = (LinkNode*)malloc(sizeof(LinkNode)); //创建头结点
L->next = NULL;
r = L; //r始终指向终端结点,开始时指向头结点
for (int i = 0; i < n; i++)
{
s = (LinkNode*)malloc(sizeof(LinkNode));//创建新结点s
s->data = a[i];
r->next = s; //将结点s插入结点r之后
r = s;
}
r->next = NULL; //终端结点next域置为NULL
}
void InitList(LinkNode*& L)
{
L = (LinkNode*)malloc(sizeof(LinkNode)); //创建头结点
L->next = NULL;
}
void DestroyList(LinkNode*& L)
{
LinkNode* pre = L, * p = pre->next;
while (p != NULL)
{
free(pre);
pre = p;
p = pre->next;
}
free(pre); //此时p为NULL,pre指向尾结点,释放它
}
bool ListEmpty(LinkNode* L)
{
return(L->next == NULL);
}
int ListLength(LinkNode* L)
{
LinkNode* p = L; int i = 0;
while (p->next != NULL)
{
i++;
p = p->next;
}
return(i);
}
void DispList(LinkNode* L)
{
LinkNode* p = L->next;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
bool GetElem(LinkNode* L, int i, ElemType& e)
{
int j = 0;
LinkNode* p = L;
if (i <= 0) return false; //i错误返回假
while (j < i && p != NULL)
{
j++;
p = p->next;
}
if (p == NULL) //不存在第i个数据结点
return false;
else //存在第i个数据结点
{
e = p->data;
return true;
}
}
int LocateElem(LinkNode* L, ElemType e)
{
LinkNode* p = L->next;
int n = 1;
while (p != NULL && p->data != e)
{
p = p->next;
n++;
}
if (p == NULL)
return(0);
else
return(n);
}
bool ListInsert(LinkNode*& L, int i, ElemType e)
{
int j = 0;
LinkNode* p = L, * s;
if (i <= 0)
return false; //i错误返回假
while (j < i - 1 && p != NULL) //查找第i-1个结点p
{
j++;
p = p->next;
}
if (p == NULL) //未找到位序为i-1的结点
return false;
else //找到位序为i-1的结点*p
{
s = (LinkNode*)malloc(sizeof(LinkNode));//创建新结点*s
s->data = e;
s->next = p->next; //将s结点插入到结点p之后
p->next = s;
return true;
}
}
bool ListDelete(LinkNode*& L, int i, ElemType& e)
{
int j = 0;
LinkNode* p = L, * q;
if (i <= 0)
return false; //i错误返回假
while (j < i - 1 && p != NULL) //查找第i-1个结点
{
j++;
p = p->next;
}
if (p == NULL) //未找到位序为i-1的结点
return false;
else //找到位序为i-1的结点p
{
q = p->next; //q指向要删除的结点
if (q == NULL)
return false; //若不存在第i个结点,返回false
e = q->data;
p->next = q->next; //从单链表中删除q结点
free(q); //释放q结点
return true;
}
}
int main()
{
LinkNode* L;
ElemType e;
ElemType a[] = { 1,2,3,4 };
CreateListF(L, a, 4); //尾插法建立链表
printf("尾插法所得顺序为: ");
DispList(L);
DestroyList(L);
CreateListR(L, a, 4); //头插法建立链表
printf("头插法所得顺序为:");
DispList(L);
printf("链表的长度为:%d\n", ListLength(L));
ListInsert(L, 4, 5); //在链表第四个元素前插入5
printf("插入一个元素后链表的元素为:");
DispList(L);
ListDelete(L, 1, e); //删除链表中第一个元素,并将它的值赋给e
printf("删除的元素为:%d\n", e);
printf("删除一个元素后链表的元素为:");
DispList(L);
printf("当前链表是否为空:%d\n", ListEmpty(L));
GetElem(L, 1, e);
printf("链表第一个元素为:%d\n", e);
printf("值为2的元素在链表中的位置为:%d\n", LocateElem(L, 2));
return 0;
}
标签:结点,单链,struct,int,C语言,printf,next,LinkNode,结构
From: https://blog.csdn.net/2302_79847831/article/details/139720847