菜鸟[0]_结构、联合和typedef(C语言)

本文详细介绍了C语言中的结构体、联合和typedef的概念及使用方法。结构体可以存储不同类型的变量,而联合在同一时间只能存储一个成员,它们在内存分配上存在显著差异。typedef则用于为数据类型创建别名,简化代码。通过示例代码展示了如何声明、实例化和操作结构体和联合,以及typedef的应用。

1、结构
结构是一个或多个变量的集合,该集合有一个单独的名称,便于操作。与数组不同,结构可以储存不同类型的变量。结构中的变量被称为结构的成员。在进行实例化之后我们就可以对其内部变量(成员)进行赋值操作。

#include<stdio.h>
int main()
{
	/*struct student
	{
		int number;  注释内部被称为结构的声明和定义,我们在这里声明里一个为student的 
		char *name;  结构,其中包括一个整型number来存储学生的学号name来存储学生的名字 。 
	}*/               
	struct student
	{
		int number;
		char *name;
	} student_1,student_2;
	
	/*
		student_1,student_2;       这两行都是对结构的实例化,实例 
		struct student student_3;  化之后我们可以对其进行操作 .
	*/
	struct student student_3; 
	student_1.number=20902134;
	student_1.name="曹家先";
	
	printf("%d %s",student_1.number,student_1.name);
	
	
	 
	student_3.number=20903124;
	student_3.name="李老二";
	
	printf("\n%d %s",student_3.number,student_3.name);
	return 0;
}

2、联合
联合与结构类似,它的声明方式与结构相同,联合和结构不同的是,同一时间内只能用一个联合成员。因为他的每一个成员都存储在相同的位置上,其分配内存大小可以容纳所需内存最大的成员。

#include<stdio.h>
int main() 
{
	union student
	{
		char *name;
		int number;
	}student;
	student.name="李老二";
	printf("%s",student.name);
	student.number=20903125;
	printf("%d",student.number);
	
	printf("\n%d",student.name);//studeng.name内的数据已经变成20903125 
	return 0; 
}

3、typedef
使用typedef关键字可以创建结构或联合类型的别名。

#include<stdio.h>
int main()
{
	typedef struct
	{
		int number;
		char *name;
	}student;
	student student_1;
	student_1.number=20134567;
	student_1.name="李老二";
	printf("%s %d",student_1.name,student_1.name);
	return 0;
 } 

总结:
结构和联合的区别,结构的成员可以同时存在很多个不同类型,每一个成员可以同时存在,并且互不影响。联合内部的成员可以是不同类型,但是同时只能存在一个,修改了一个其余的成员跟着一起改变,同时只能存在一个成员其余的成员均编程最近被修改的成员。typedef定义的结构和联合声明起来比较简单。
结构内部成员,分配的存储地址不同,联合内部的成员分配的存储地址相同,且分配地址大小为字节数最大的成员。

<think>嗯,用户想了解如何用C语言实现菜鸟驿站的用户登录注册功能,涉及到链表文件操作。首先,我需要明确需求。菜鸟驿站的基本用户系统通常包括注册、登录、信息存储等功能。用户信息可能包括用户名、密码、手机号等。接下来,我得考虑数据结构的设计,链表适合动态管理用户数据,而文件用于持久化存储。 首先,结构体定义。用户信息结构体应该包含用户名、密码、手机号,还有链表需要的指针。比如struct User,里面有char数组存用户名、密码、手机号,然后一个指向下一个节点的指针。 然后是文件操作。程序启动时需要从文件中读取用户数据到链表中,退出时再将链表数据写回文件。这里要注意文件的打开方式,读取用"r",写入用"w"。同时,要处理文件不存在的情况,比如第一次运行程序时,文件可能不存在,这时候需要创建。 接下来是注册功能。用户输入用户名、密码、手机号,需要检查用户名是否已存在。遍历链表,比较用户名,如果存在则提示错误,否则创建新节点,添加到链表末尾。这里要注意内存分配,使用malloc,并检查是否成功。 登录功能的话,用户输入用户名密码,遍历链表查找匹配的节点。找到则登录成功,否则失败。这部分相对简单,但需要确保字符串比较正确,比如使用strcmp函数。 链表的管理,包括初始化、添加节点、释放内存。初始化链表时,头指针设为NULL。添加节点分两种情况,链表为空时直接作为头节点,否则找到尾节点插入。释放链表内存需要在程序结束时,逐个节点释放,避免内存泄漏。 文件读取写入的函数需要正确处理数据格式。比如,fprintf写入时按照一定格式,比如每行存储用户名、密码、手机号,用空格分隔。读取时使用fscanf,但要注意返回值,确保读取正确数量的数据。同时,循环读取直到文件结束。 可能遇到的问题包括文件读写错误,比如无法打开文件,这时候需要提示用户。还有内存泄漏的问题,确保每次分配的内存都被正确释放。此外,用户输入处理时,要注意缓冲区溢出,使用安全的输入函数,比如fgets代替scanf,但示例中可能为了简化用了scanf,实际应用中需要注意。 代码结构方面,主函数里先加载文件数据到链表,然后显示菜单,根据用户选择调用注册或登录功能,退出时保存数据并释放链表。菜单循环使用while循环,直到用户选择退出。 测试时需要考虑各种情况,比如重复注册、错误密码、文件损坏等。确保程序健壮性,比如输入过长的用户名或密码时,程序不会崩溃,但示例中可能没有做长度检查,实际需要添加。 最后,示例代码可能需要进一步优化,比如加密存储密码,而不是明文,增加其他用户信息,或者错误处理更完善。但作为基础示例,已经涵盖了链表文件操作的核心部分。</think>以下是用C语言实现菜鸟驿站用户系统的示例代码,包含链表文件操作的核心实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> /* 用户信息结构体 */ typedef struct User { char username[20]; char password[20]; char phone[15]; struct User* next; } User; User* head = NULL; // 链表头节点 /* 函数声明 */ void loadFromFile(); void saveToFile(); void registerUser(); int loginUser(); void freeList(); int main() { loadFromFile(); // 启动时加载数据 int choice; do { printf("\n1.注册\n2.登录\n3.退出\n请选择: "); scanf("%d", &choice); switch(choice) { case 1: registerUser(); break; case 2: if(loginUser()) printf("登录成功!\n"); else printf("用户名或密码错误!\n"); break; case 3: printf("正在退出...\n"); break; default: printf("无效选项!\n"); } } while(choice != 3); saveToFile(); // 退出时保存数据 freeList(); // 释放内存 return 0; } /* 从文件加载数据到链表 */ void loadFromFile() { FILE* fp = fopen("users.dat", "r"); if(!fp) return; User* tail = NULL; while(1) { User* newUser = (User*)malloc(sizeof(User)); if(fscanf(fp, "%s %s %s", newUser->username, newUser->password, newUser->phone) != 3) { free(newUser); break; } newUser->next = NULL; if(!head) head = newUser; else tail->next = newUser; tail = newUser; } fclose(fp); } /* 保存链表数据到文件 */ void saveToFile() { FILE* fp = fopen("users.dat", "w"); if(!fp) { printf("文件保存失败!\n"); return; } User* current = head; while(current) { fprintf(fp, "%s %s %s\n", current->username, current->password, current->phone); current = current->next; } fclose(fp); } /* 用户注册 */ void registerUser() { User* newUser = (User*)malloc(sizeof(User)); printf("请输入用户名: "); scanf("%s", newUser->username); // 检查用户名是否存在 User* current = head; while(current) { if(strcmp(current->username, newUser->username) == 0) { printf("用户名已存在!\n"); free(newUser); return; } current = current->next; } printf("请输入密码: "); scanf("%s", newUser->password); printf("请输入手机号: "); scanf("%s", newUser->phone); // 插入链表 newUser->next = head; head = newUser; printf("注册成功!\n"); } /* 用户登录 */ int loginUser() { char username[20], password[20]; printf("用户名: "); scanf("%s", username); printf("密码: "); scanf("%s", password); User* current = head; while(current) { if(strcmp(current->username, username) == 0 && strcmp(current->password, password) == 0) { return 1; } current = current->next; } return 0; } /* 释放链表内存 */ void freeList() { User* current = head; while(current) { User* temp = current; current = current->next; free(temp); } head = NULL; } ``` 代码特点说明: 1. **数据结构**:使用单向链表存储用户信息,每个节点包含: - 用户名(最大20字符) - 密码(最大20字符) - 手机号(最大15字符) - 指向下一个节点的指针 2. **文件操作**: - `users.dat`文件存储用户数据 - 启动时自动加载数据到链表 - 退出时自动保存链表到文件 - 使用文本格式存储,每行保存一个用户信息 3. **核心功能**: - 用户注册:检查用户名冲突 - 用户登录:验证用户名密码 - 数据持久化:自动保存/加载用户数据 4. **内存管理**: - 使用`malloc`动态分配节点内存 - 退出时通过`freeList()`释放所有内存 - 防止内存泄漏 5. **扩展建议**: ```c // 可添加以下功能: // 1. 密码加密存储 // 2. 用户信息修改功能 // 3. 管理员模式 // 4. 输入有效性验证 ``` 使用说明: 1. 编译运行后会自动创建`users.dat` 2. 注册时用户名不能重复 3. 数据在程序退出后自动保存 注意:实际开发中需要添加更多安全措施(如密码加密、输入验证等),此示例主要展示链表文件操作的核心实现逻辑。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值