AutoLeaders控制组—C语言结构体学习笔记

一.定义结构体

一般采用

1.第一种

struct 结构体名
{
成员表列
}变量名表列;

int main()
{
    struct Student
    {
        int id;
        char* name;
        int age;
        float score;
    }student1, student2;
}


2.第二种

先声明结构体类型 再定义该类型的变量

int main()
{
    struct Student
    {
        int id;
        char* name;
        int age;
        float score;
    };
    struct Student student1, student2;
}


二.初始化和引用结构体

这里需要区分结构体类型和结构体变量 上面的struct Student是结构体类型相当于int double之类,student1, student2相当于定义的变量

1. “.”运算符对成员赋值

student.id=20230110;

“.”的运算优先级最高,所以可以把student.id(结构体变量名.成员名)当作一个变量来看待,就可以进行各种运算。

2.只能对最低级的成员进行运算

如果成员本身属于一个结构体类型,则要使用多个成员运算符直到最低级成员,如

	student1.birthday.month

3.引用结构体变量或变量成员的地址

scanf("%d", &student1.id);//输入成员的值
printf("%o", &student1);//输出结构变量student1的地址

二.结构体数组

1.定义和引用结构体数组

a.struct结构体名
{成员}数组名[N];

struct Student
{
	int id;
	char* name;
	int age;
	float score;
}student[10];

b.先声明struct Student student [10];再引用

2.初始化

在定义数组后面加上={初值表列}

struct Person
{
	char name[20];
	int cnt;
}leader[3];
struct Person leader[3] = { {"Li",0},{"wang",0},{"liu",0 }};

三.结构体指针

1.指向结构体变量的指针

struct Student
{
	int num;
}stu_1;

struct Student* p;//定义一个指向struct Student类型的指针变量
p = &stu_1;//令p指向stu_1
stu_1.num = 100;
printf("%d\n", (*p).num);//输出stu_1中的成员num
printf("%d\n",p->num);
printf("%d\n", stu_1.num);

输出结果均为100,说明(*p).num), p->num ,stu_1.num是等价的, p->num 就是指针p指向num成员,一般采用箭头指向方式更简易清晰

2.指向结构体数组的指针

struct Student {
	int num;
	char name[20];
	int age;
};
struct Student stu[2] = { {01,"Li",20},{03,"Han",18} };
struct Student* p;
for (p = stu; p < stu + 2; p++) //先令p指向stu[0],然后就是指针数组的基本运算
{
	printf("num=%d name=%s age=%d\n", p->num, p->name, p->age);
}

四.typedf定义新类型

基本形式为typedf+数据类型+类型变量名

1.用typedef建立新类型代替原有类型

typedef int Integer;//用Integer代替int型
typedef float Real;//用Real代替float型
int i, j;Integer i,j;//等价
float a, b; Real a, b;//等价

这里Integer代替了int,Real代替了float,作用是一样的。
这里typedf的作用还不太明显,所以下面用typedef定义代替复杂类型就好用多了。

2.typedef建立简单类型代替复杂类型

习惯用typedf声明的类型名的第一个字母用大写字母表示

1)定义新数组类型:

typedef int Num[100];
Num a;//a为包含100个元素的整形数组

2)定义新指针类型:

typedef char* String;
String a;//a为字符型指针数组

3)定义新结构体类型

可以直接定义,引用时就不用struct Date而是直接类型名Date:

typedef struct {
	int month;
	int day;
}Date;//定义了一个Date类型代表上面的结构体类型
Date birthday;//Date是结构体类型 birthday是Date类型的结构体变量
Date* p;

也可以定义完再重新用typedef定义

struct Student {
	int id;
	char* nmae;
};
typedef struct Student Student;
Student a;
Student* p;

五.链表

链表是由多个结点组成的,包括头指针head和表尾,每个结点由数据和下一节点的地址组成

1.静态链表

类似循环的模式,使p不断指向下一个结点的地址,这就需要结构体中的next成员指向另一个结构体(嵌套),直至最后一个NULL停止
如下建立有三位同学的静态链表

struct Student {
	int num;
	float score;
	struct Student* next;
};
struct Student a, b, c, * head, * p;
a.num = 01; a.score = 90;
b.num = 02; b.score = 95;
c.num = 03; c.score = 98;
head = &a;
a.next = &b;
b.next = &c;
c.next = NULL;
p = head;
while (p != NULL) {
	printf("%ld %2.lf\n", p->num, p->score);
	p = p->next;//从最开始的a.next顺次指向下一结点,遍历链表
}

2.动态链表

从无到有一个一个开辟结点和输入数据,涉及到动态内存分配

补:动态内存分配

#include <stdlib.h>
int main()
{
	int num=10;
	int* a;
	a = (int*)malloc(num * sizeof(int));//动态内存分配,让a拥有你想要的空间
	for (int i = 0; i < num - 1; i++) {
		scanf("%d", &a[i]);
	}
	for (int i = num-1; i >=0; i--) {
		printf("%d", a[i]);
	}
	free(a);//释放内存
	return 0;
}

1).(int*)是强制转换数据类型,让malloc函数转为int
2).malloc()括号中的数字为开辟的字节数,如果要存入数据,须以数据个数
数据类型所占用的字节数如:num*sizeof(int/float/char)
3)free()释放指针变量a所指向的空间

动态链表我也不太理解 但是把组建一个动态链表的代码如下表示出来:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct Student)
struct Student {
	int num;
	float score;
	struct Student* next;
};
int n;//全局变量
struct Student* creat(void)
{
	struct Student* head=NULL;
	struct Student* p1, *p2;
	n = 0;
	p1 = p2 = (struct Student*)malloc(LEN);
	scanf("%d ,%f", &p1->num, &p2->score);
	while (p1->num != NULL) {
		n += 1;
		if (n == 1) {
			head = p1;
		}
		else {
			p2->next = p1;
		}
		p2 = p1;
		p1 = (struct Student*)malloc(LEN);
		scanf("%d %f", &p1->num, &p1->score);
	}
	p2->next = NULL;
	return(head);

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值