C语言——结构体

一、定义和使用结构体

1.1概述

        前面我们见过的数据类型,比如int,float,char等是在程序中简单的使用,如果我们要根据自己的需求来建立一些复杂的数据,就需要用到结构体。

        例如,一个学生的学号,姓名,性别,年龄等是同属于一个学生的,但是这些变量又属于不同的类型,如果只是利用不同的变量分别进行简单的定义,那很难反应出来它们之间内在的联系。那么我们创建一个变量,能够将这些数据进行组合后放在变量中,这样使用起来就简单的多,这就是引出来结构体的学习;

结构体类型:
        struct Student
        {
              int num;//学号为整形;
              char name[20];//姓名为字符串;
              char sex;//性别为字符型;
              int age;//年龄为整形
              float score;//成绩为浮点型
              char addr[30];//地址为字符型;
        }

其中:

        struct Student  为结构体类型;

        struct是声明结构体类型的关键字。

        Student是结构体名,为了同其他结构进行区分;

        花括号中是该结构体的成员,组在一起称为成员列表,其命名与变量的命名是一致的;

注:结构体类型是可以有多中的;如:struct Student;struct Teacher;struct Worker;

        结构体的成员也可以是另一个结构体的类型;

struct Date

{        

        int month;

        int day;

        int year;      

};

struct Student

{

        int num;

        char name[20];

        char sex;

        int age;

        struct Date birthday;

        char addr[30];

}

1.2结构体变量的定义

        前面我们只定义了一个结构体类型,相当于一个模型,并没有定义变量,下面我们定义结构体变量,并在其中存放具体的数据,3种方法;

  方法1:先声明结构体类型,在定义结构变量

        在前面结构体类型的基础上 struct Student,定义结构体变量;

         struct Student student1,student2;

        这种方式类似于int a,b;只是前提是已经有了结构体类型,在类型的基础上定义结构体变量。

    方法2:在声明类型的同时定义变量

        形式:

                struct 结构体名

                {

                        成员列表;

                }变量名列表;

        举例:

                  struct Student
                {
                      int num;
                      char name[20];
                      char sex;
                      int age;
                      float score;
                      char addr[30];
                }student1,student2;

        方法3:不指定类型名而直接定义结构体类型变量

                形式:

                        struct

                        {

                                成员变量;

                        }变量名列表;

        其为一个无名的结构体类型,不经常使用;

注:1、结构体变量中的成员名可以与程序中的变量名相同;

        2、结构体变量中的成员可以单独使用;他的地位和作用相当于普通变量;

1.3结构体变量的初始化和引用 

        在定义结构体变量的时候顺便对其初始化;

      举例:把一个学生的信息(包括学号、姓名、性别、住址)放在一个结构体变量中,然后输出该学生的信息;

#include <stdio.h>

int main()
{
	struct Student
	{
		int num;
		char name[20];
		char sex;
		char addr[20];
	}student1 = {101,"Li li",'M',"123XiAn"};
	printf("NO:%d,\nname:%s\nssex:%c\naddress:%s\n",student1.num,student1.name,student1.sex,student1.addr);
	return 0;

结果分析:

        在定义结构体变量的时候顺便对其进行成员初始化,初始化列表是用花括号括起来的一些常量,这些常量是一次赋给结构体变量的成员,注意:是对结构体变量初始化,不是对结构体类型初始化。

        结构体变量中成员的值,引用方式为:

 结构体变量名.成员名

 student1.name

        对于结构体成员本是又属于一个结构体类型,则要一级一级地找到最低一级的成员,例如上面所述的struct Student中包含 struct Date birthday;则引用的方式为:

        Student birthday.month

同类型的结构体可以相互赋值: student1= student2;

        举例:输入两个学生的学号、姓名和成绩,输出成绩较高的学生的学号、姓名和成绩;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	struct Student
	{
		int num;
		char name[20];
		float score;
	}student1,student2;
	scanf("%d%s%f", &student1.num, student1.name, &student1.score);
	scanf("%d%s%f", &student2.num, student2.name, &student2.score);
	printf("The higher score is:\n");
	if (student1.score > student2.score)
	{
		printf("%d %s %6.2f\n", student1.num, student1.name, student1.score);
	}
	else if (student1.score < student2.score)
	{
		printf("%d %s %6.2f\n", student2.num, student2.name, student2.score);
	}
	else
	{
		printf("%d %s %6.2f\n", student1.num, student1.name, student1.score);
		printf("%d %s %6.2f\n", student2.num, student2.name, student2.score);
	}
}

        用scanf函数输入结构体变量的时候,必须分别输入,不能在scanf函数中使用结构体变量名一次性输入全部成员的值,注意,scanf函数在student1.name前面没有&,因为数组名本来就代表了地址。 

二、使用结构体数组

2.1定义结构体数组

        我们前面在定义结构体变量的时候,是一个一个进行定义的,但是,如果是一组有关联得数据需要参与运算,显然就需要用到数据,例如10名同学的信息,这就是结构体数组,结构体数组的每一个数组元素都是一个结构体。

举例:有3名候选人,每一个选民只能投票选一个人,要求编写一个统计票数的程序,先输入备选人的姓名,最后显示各人得票的结果。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

struct Person
{
	char name[20];
	int count;
}leader[3] = { "wang", 0, "zhang", 0, "li", 0 };
int main()
{
		int i, j;
		char lead_name[20];
		for (i = 0; i < 10; i++)
		{
			scanf("%s", lead_name);
			for (j = 0; j < 3; j++)
			{
				if (strcmp(lead_name, leader[j].name) == 0)
					leader[j].count++;
			}
		}
		printf("\nResult\n");
		for (i = 0; i < 3; i++)
		{
			printf("name:%s,count:%d\n", leader[i].name, leader[i].count);
		}
		return 0;
	}

定义结构体数组的一般形式:

        struct 结构体名

        {

                变量列表

        } 数组名[数组长度];

        先声明一个结构体类型,如:struct student,然后在定义结构体数组;

        结构体类型 数组名[数组长度];

对于结构体数组初始化的形式是在定义后加:

        ={初值列表};     

2.2使用结构体数组

        举例:有n个学生的信息(包括学号、姓名、成绩),要求按照成绩的高低顺序输出各个学生的信息;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

struct Student
{
	int num;
	char name[20];
	float score;
};

int main()
{
	struct Student stu[5] = { 1001, "Wangwei", 98.25, 1002, "Liuliu", 91, 1003, "Zhangli", 98, 1004, "Xiaozhao", 85, 1005, "Baibai", 94 };
	struct Student temp;
	printf("The order id:\n");
	int i, j,k;
	for (i = 0; i < 4; i++)
	{
		k = i;
		for (j = i + 1; j < 5; j++)
		{
			if (stu[j].score>stu[k].score)
			{
				k = j;
			}
		}
			temp = stu[k]; 
			stu[k] = stu[i]; 
			stu[i] = temp;	
	}
	for (i = 0; i < 5; i++)
	{
		printf("%d  %s  %5.2f", stu[i].num, stu[i].name, stu[i].score);
		printf("\n");
	}
	return 0;
}

三、结构体指针

3.1指向结构体变量的指针

          所谓的结构体指针就是指向结构体变量的指针,一个结构体变量的起始地址就是这个结构体变量的指针。   

        指向结构体对象的指针变量既可以指向结构体变量,也可以指向结构体数组的元素,指针变量的基类型必须与结构体变量的类型相同。

如:struct Student * pt;   

举例:通过指向结构体变量的指针变量输出结构体变量中成员的信息;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

struct Student
{
	long num; 
	char name[20];
	char sex;
	float score;
};

int main()
{
	struct Student stu1;
	struct Student *pt;
	pt = &stu1;
	stu1.num = 10001;
	strcpy(stu1.name, "Lili");
	stu1.sex = 'M';
	stu1.score = 96.5;
	printf("No:%d\nname:%s\nsex:%c\nscore:%5.1f\n", stu1.num, stu1.name, stu1.sex, stu1.score);
	printf("\n");
	printf("No:%d\nname:%s\nsex:%c\nscore:%5.1f\n", (*pt).num, (*pt).name, (*pt).sex, (*pt).score);
	printf("\n");
	printf("No:%d\nname:%s\nsex:%c\nscore:%5.1f\n", pt->num, pt->name, pt->sex, pt->score);
	return 0;
}

结果分析:

         在函数中,第一个printf函数是通过结构体变量名stu1进行成员的访问;

        第二个printf函数是通过指向结构体变量的指针变量访问他的成员的,(* pt)表示指向的结构体变量,(*pt).num表示指向的结构体成员。

        此外,在c语言中,允许将(*pt).num用pt->num代替;

3.2指向结构体数组的指针

        可以用指针变量指向结构体数组的元素。

举例:有三个学生的信息,放在结构体数组中,要求输出学生的信息;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

struct Student
{
	long num; 
	char name[20];
	char sex;
	float score;
};

int main()
{
	struct Student stu[3] = { 1001, "wangle", 'M', 95, 1002, "chengcai", 'M', 99.9, 1003, "shangmin", 'F', 85.2 };
	struct Student *pt;
	printf("No.  name       sex  score\n");
	for (pt = stu; pt < stu + 3; pt++)
	{
		printf("%d %s %c %5.2f\n", pt->num, pt->name, pt->sex, pt->score);
	}
	return 0;
}

        程序中pt是一个指向struct Student类型结构体变量的指针变,它用来指向的是结构体变量,不是用来指向结构体中某一个成员,pt=stu[1].name是不合法的,因为一个是结构体变量,一个是结构体成员变量。p++,p的值增加的是结构体的长度。

3.3用结构体变量和结构体变量的指针作为函数参数

将一个结构体变量的值传递给函数,共有三种方法;

1、将结构体变量的成员作为参数,这种方法就是相当于传递了普通的变量,应该注意形参与实参(结构体成员)的类型相同;

2、用结构体变量作为实参。用结构体变量作为实参时,也是值传递,将结构体变量所占的内存单元的内容全部传递给形参,形参必须也是结构体变量。

3、利用指向结构体变量(数组)的指针作为实参,将结构体变量(数组)的地址传递给形参。

举例:

        有n个结构体,包括学生学号,姓名和3门课程的成绩,要求输出平均成绩最高学生的信息(包括学号、姓名、3门课程成绩、平均成绩)。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void print(struct Student stud);
struct Student Max(struct Student stu[]);
void input(struct Student stu[]);
struct Student
{
	int num; 
	char name[20];
	float score[3];
	float aver;
};

int main()
{
	struct Student stu[3], *pt;
	pt = stu;
	input(pt);
	print(Max(pt));
	return 0;
}
void input(struct Student stu[])
{
	int i;
	printf("请输入各学生的信息:学号、姓名、3门成绩:\n");
	for (i = 0; i < 3;i++)
	{
		scanf("%d%s%f%f%f", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
		stu[i].aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;	
	}
}

struct Student Max(struct Student stu[])
{
	int i, m = 0;
	for (i = 0; i < 3; i++)
	{
		if (stu[i].aver > stu[m].aver)
			m = i;
	}
	return  stu[m];
}
void print(struct Student stud)
{
	printf("成绩最好的学生是:\n");
	printf("学号:%d 姓名:%s 三门课程:%5.2f %5.2f %5.2f平均成绩:%5.2f\n", stud.num, stud.name, stud.score[0], stud.score[1], stud.score[2], stud.aver);
}

 1、调用input函数时,实参是指针变量pt,形参是结构体数组,传递的是结构体元素的起始地址,函数无返回值;

2、调用Max函数时,实参是指针变量pt,形参是结构体数组,传递的是结构体元素的起始地址,函数返回值为结构体类型数据。

3、调用print函数时,实参是结构体变量(结构体数组元素),形参是结构体变量,传递的是结构体变量中各成员的值,函数无返回值。

四、链表

4.1概述

        链表是一种常见的数据结构,它是动态进行存储分配的一种结构。

        数组在存放数据的时候,必须事先定义好数组长度(多个数组),如果有的班级有100人,有的班级有30人,若用同一个数组存放不同的班级学生的数据,则必须定义长度为100的数组,但是这样往往会存在资源的浪费,链表没有这样的缺点,他根据需要开辟内存单元。

        链表有一个“头指针”变量,图中用head表示,它存放一个地址,该地址指向一个元素,链表中每一个元素称为“结点”,每个节点应该包括两个部分:

        1、用户需要的实际数据;

        2、下一个元素的地址;

         可以看见链表中各元素在内存中的地址可以是不连续的,要找到某一元素,必须先找到前一个元素,根据前一个元素的地址才能找到下一个元素。如果不提供“头指针”,则整个链表都无法访问。

        那这样来说,用结构体建立链表是最合适的,一个结构体包含若干个成员,用指针类型成员来存放下一个节点的地址。

struct Student

        {

                int num;

                int score;

                struct Student *next;

        }

               其中,num,score用来存放用户数据,next用于存放下一个节点的地址。

4.2静态链表

案例:

        建立一个静态链表,由3个学生的数据的节点组成,要求输出各个节点的数据;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

struct Student
{
	int num; 
	float score;
	struct Student * next;
};

int main()
{
	struct Student a, b, c, *head, *p;
	a.num = 1001; a.score = 85.5;
	b.num = 1002; b.score = 95.5;
	c.num = 1003; c.score = 84.5;
	head = &a;
	a.next = &b;
	b.next = &c;
	c.next = NULL;
	p = head;
	do
	{
		printf("%d %5.2f\n", p->num, p->score);
		p = p->next;
	} while (p != NULL);
	return 0;
}

        为例建立链表,使head指向a结点,a.next指向b结点,b.next指向c结点,c.next指向null,这就构成了链表关系。

        在输出链表的时候,要先借助p,先使p指向a,然后输出a中的数据,p=p->next是输出位下一个结点做准备。

4.3动态链表       

4.3.1 动态内存分配 

        在说动态链表之前我们先给大家介绍,动态内存分配。

        在前面我们说变量分为全局变量与局部变量,全局变量分配在内存的静态存储区,非静态存储的局部变量是分配在内存中的动态存储区,这个存储区被称为

        此外,C语言还允许建立内存动态分配区域,以存放一些临时用的数据,这些数据需要时开辟,不需要时释放,这些数据是临时存放在一个特别的自由存储区,这个存储区被称为

        对于内存的动态分配,是通过系统提供的函数来实现的:malloc、calloc、free以及realloc函数。

1、用malloc函数开辟动态存储区

函数: void *malloc (unsigned int size);

功能:

        在内存的动态存储区分配一个长度为size的连续空间(单位:字节)。

返回值:

        所分配的第一个字节的地址;此地址没有类型,只是一个纯地址;

2、用calloc函数开辟动态存储区

函数:void * calloc(unsigned n,unsigned size);

功能:

        在内存的动态存储区分配n个字节长度为size的连续空间。这个空间比较大足以保存一个数组;

        用calloc函数可以为一维数组开辟动态存储空间,n为数组元素个数,size为元素长度。

返回值:

        所分配的第一个字节的地址;此地址没有类型,只是一个纯地址;

3、用realloc函数重新分配动态存储区

函数:void * realloc(void *p ,unsigned int size);

功能:

        对已经分配的动态内存进行重新分配。

        用recalloc函数将p所指向的动态空间的大小改为size。p的值保持不变;

返回值:

        更新后动态内存的第一个字节的地址,实质上也就是p所指向的地址。

4、用free函数释放动态存储区

函数: void free(void *p);

功能:

        释放指针变量p所指向的动态空间,使这部分空间能被其他变量使用,

        p是最近一次调用malloc、calloc函数所得的返回值;

返回值:

        无;

:以上4个函数的声明都在stdlib.h头文件中。      

 void指针类型:

        在上面的函数malloc函数与calloc函数的返回值都是void *类型,它表示不指向任何类型的数据,不要把其理解为指向任何的类型,而是指向空类型或者不指向确定类型的数据。

        在调用动态内存的时候,程序只是利用了该函数带回来的纯地址,并没有用到指向哪一个数据类型的属性,如果要使用这个地址,必须将其进行转化。

例如:

        int *p;

        p=(int*)malloc(100);

案例:

        建立一个动态数据,输入5个学生的成绩,另外用一个函数检车其中有无低于60分的,输出不合格的成绩;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	void check(int * p);
	int *p1, i;
	p1 = (int *)malloc(5 * sizeof(int));
	for (i = 0; i < 5; i++)
	{
		scanf("%d", p1 + i);
	}
	check(p1);
	return 0;
}
void check(int * p)
{
	int i;
	printf("they are fail:\n");
	for (i = 0; i < 5; i++)
	{
		if (*(p+i) < 60)
			printf("%d  ", *(p + i));
	}
}

运行结果:

结果分析:

        在程序中并没有定义数组,只是开辟了一段的动态自由分配区,作为数组使用。

        在malloc函数中,并没有直接传递具体的数值用来分配动态空间,而是利用sizeof计算此系统整型的字节数,然后创建5个元素。利用p指向第一个字节地址,并将其转化为int类型,p+1指向下一个元素。

4.3.2动态链表建立

        写一函数建立一个有4名学生数据的动态链表。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define LEN sizeof(struct Student)

struct Student
{
	long num;
	float score;
	struct Student * next;
};

int n;
struct Student * creat(void)
{
	struct Student * head, *p1, *p2;
	n = 0; p1 = p2 = malloc(LEN);
	scanf("%ld%f", &p1->num, &p1->score);
	head = NULL;
	while (p1->num != 0)
	{
		n = n + 1;
		if (n == 1)
			head = p1;
		else  p2->next = p1;
		p2 = p1;
		p1 = (struct Student *)malloc(LEN);
		scanf("%ld%f", &p1->num, &p1->score);
	}
	p2->next = NULL;
	return (head);
	}

int main()
{
	struct Student * pt;
	pt = creat();
	printf("\n num:%ld score:%5.2f\n", pt->num, pt->score);
	return 0;
}


运行结果: 

结果分析:动态链表的创建先指定了三个结构体指针,然后利用malloc函数先创建了一个节点,将三个结构体指针都指向这个结点,然后p1再去利用malloc函数进行创建节点,并将p2的next指向创建的结点,指向后p2=p1,p1再去创建p2的next指向创建的结点,p2=p1....直到p1中元素的值为0,p2的next不指向新创建的结点,指向NULL,这样一个动态链表就创建完毕,head指向最开始的结点,自己就是头结点。

动态链表的输入与输出:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define LEN sizeof(struct Student)

struct Student
{
	long num;
	float score;
	struct Student * next;
};
int n;
struct Student * creat(void)
{
	struct Student * head, *p1, *p2;
	head = NULL;
	n = 0;
	p2 = p1 = malloc(LEN);
	scanf("%ld%f", &p1->num, &p1->score);
	while (p1->num != 0)
	{
		n = n + 1;
		if (n == 1)
			head = p1;
		else
			p2->next = p1;
		p2 = p1;
		p1 = malloc(LEN);
		scanf("%ld %f", &p1->num, &p1->score);
	}
	p2->next = NULL;
	return head;
}

void print(struct Student * p)
{
	do
	{
		printf("%ld %5.2f\n", p->num ,p->score);
		p=p->next;
	} while (p->num != NULL);
}

int main(void)
{
	struct Student * pt;
	pt = creat();
	print(pt);
	return 0;
}

 运行结果:

五、共用体类型 

5.1概述    

    在有些时候,希望再通一段内存单元中存放不同类型的变量,例如,将整型变量,字符型变量以及浮点型变量放在同一个地址开始的内存单元中,这使得几个变量共享同一段内存结构,称为“共用体”。

定义共用体的一般形式:

        union 共用体名

        {

                成员列表;

        }变量列表;

例如:

        union Data

        {

                int i;

                char ch;

                float f;

        }a,b,c;

        结构体变量所占的内存长度是各成员占的内存长度之和;而共用体所占的内存长度是最长成员的长度。

5.2引用

        只有事先定义好共用体变量,才能引用,注意,我们引用的不是共用体变量而是引用的共用体变量中的成员。

a.i   引用共用体变量中的整形变量;

a.ch   引用共用体变量中的字符变量;

a.f   引用共用体变量中的实型变量;

5.3特点

1、在内存段中可以用来存放几种不同类型的成员,但是在每一瞬间只能存放其中的一个成员,而不是同时存放几个。

2、可以对共用体变量初始化,但是初始化表中只能有一个常量。

3、共用体变量中其作用的成员,是最后一次被赋值的成员,前面原有的变量被覆盖取代。

4、共用体变量的地址和它的各成员的地址都是一样的。

5、不能对共用体变量名称赋值,也不能企图引用变量名来得到一个值。

六、枚举类型

        如果有的变量的取值只有几种可能性,则可以定义为枚举类型;所谓的枚举就是将可能出现的值一一进行列举。

        声明枚举类型用enum开头;例如

        eunm Weekday{sun,mon,tue,wed,thu,fri,sat};

        以上声明了一个枚举类型enum Weekday。然后可以用此类型来定义变量。

        enum Weekday workday,weekend;

其中,workday与weekend被定义为枚举变量,花括号中称为枚举元素或枚举常量。

声明枚举类型的一般形式:

        enum [枚举名] {枚举元素列表};

举例:

        口袋中有红黄蓝白黑5种小球,每次从口袋中先后取出3个,问得到3种不同颜色的球的可能取法并进行排列;

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	enum Color {red,yellow,bule,white,black};
	enum Color i, j, k, pri;
	int n, loop;
	n = 0;
	for (i = red; i <= black; i++)
		for (j = red; j <= black; j++)
			if (i != j)
			{
		for (k = red; k <= black; k++)

			if ((k != i) && (k != j))
			{
			n++;
			printf("%d ", n);
			for (loop = 1; loop <= 3; loop++)
			{
				switch (loop)
				{
				case 1:pri = i; break;
				case 2:pri = j; break;
				case 3:pri = k; break;
				default:break;
				}

				switch (pri)
				{
				case red:printf("%s ", "red"); break;
				case yellow:printf("%s ", "yellow"); break;
				case bule:printf("%s ", "bule"); break;
				case white:printf("%s ", "white"); break;
				case black:printf("%s ", "black"); break;
				default:break;
				}
			}
			printf("\n");
				}
			}
	printf("\n total:%d\n", n);
	return 0;
}

运行结果:

七、用typedef声明新类型名

 利用typedef指定新的类型名代替已有的类型名;

1、简单地用一个新的类型名代替原有的类型名

      例如:

        typedef int Integer;

        typedef float Real;

        这样,下面两行是等价的:

        int i,j;———   Integer i,j;

2、命名一个简单的类型名代替复杂的类型表示方法

     命名新的类型名代表结构体类型:

        typedef struct

        {

                int mun;

                ......

        }  Data; 

        则用新的类型名Data去定义变量;

        Data brithday;

        Data * p;

      命名一个新的类型名代替数组类型:

        typedef int Num[100];

        Num a;

       命名一个新的类型名代表指针类型

        typedef char * String;

        String p,a[10];

       命名一个新的类型名代表指向函数的指针;

        typedef int (* Pointer)();

        Pointer p1,p2;

           归纳:按照定义变量的方式,把变量名换成新的类型名,并且在最前面加typedef,就声明了新类型名代表原来的类型。

typetef只是对已经存在的类型指定一个新的类型名,而并没有创造新的类型。

typetef和#define表面上有相似之处。

typedef int Count

#define Count int

        他们的作用都是用Count代替int,但是事实上他们两者是不同的,#define是在预编译是处理的,他只能作为简单的字符串替换,而typedef是在编译阶段处理。实际上并不是简单的替换。而是生成了一个新的类型名,再去定义变量。

相关推荐

  1. c语言-结构

    2024-07-11 23:28:05       61 阅读
  2. 结构(C语言)

    2024-07-11 23:28:05       52 阅读
  3. C语言结构

    2024-07-11 23:28:05       48 阅读
  4. C语言----结构

    2024-07-11 23:28:05       49 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 23:28:05       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 23:28:05       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 23:28:05       57 阅读
  4. Python语言-面向对象

    2024-07-11 23:28:05       68 阅读

热门阅读

  1. C#如何从中级进阶到高级开发

    2024-07-11 23:28:05       26 阅读
  2. 【Layui】Layui表格动态生成列

    2024-07-11 23:28:05       19 阅读
  3. Windows系统服务器远程教程

    2024-07-11 23:28:05       22 阅读
  4. 前端文件下载的方式

    2024-07-11 23:28:05       21 阅读