day12嵌入式(2022.1.18)

2022-12-02 14:34:10 浏览数 (2)

多文件(工程)编译常见问题:

  1. 隐式声明:没有声明该函数。

解决方式:在工程头文件head.h中,添加该函数的声明。

  1. gcc链接器未发现函数(未定义函数)(全局变量同理)

解决方式:寻找所有编译的.c文件中是否存在该函数。

  1. gcc链接器发现多个同名函数(多重定义)(全局变量同理)

解决方式:打开提示的2个文件,删除掉其中的无用函数,或者修改其中一个的函数名。

练习:

  1. 根据proj2,定义结构体数组(长度50),初始化3个用户的信息。
  2. 需将usr_login函数移到usr.c中
  3. 修改usr_login函数,使得可以判断多个用户。
  4. 要求用户uid和密码可多次输入,当超过3次,提示次数过多,结束程序。
  5. 登录成功后,显示操作菜单:0: 显示用户信息 usr_show()

1: 修改密码     usr_update()

2: 新增用户 usr_add()

3: 删除用户 usr_del()

先完成修改密码功能,完成后思考一下如何实现用户新增、删除?

(可以添加显示信息功能,查看密码是否修改成功。)

练习:

  1. 参考proj1文件夹,创建一个自己的工程,放入4个文件:

main.c 放入main主函数

square.c 放入计算平方、立方函数。

sum.c 放入加减乘除的4个函数

head.h 工程头文件

在main函数中都使用子函数,计算一下。

head.h

代码语言:javascript复制
#ifndef _HEAD_H
#define _HEAD_H

#include <stdio.h>

/********** square.c函数声明 ***********/
// 计算a的平方
extern int func_square(int a);
// 计算a的立方
extern int func_cube(int a);

/********** sum.c函数声明 ***********/
// 计算两数之和
extern int func_sum(int a, int b);

#endif

main.c

代码语言:javascript复制
#include "head.h"

int main()
{
	int a=3, b=4;

	int a2=func_square(a);
	int b2=func_square(b);
	int sum = func_sum(a2, b2);
	printf("sum: %dn", sum);

	int a3=func_cube(a);
	printf("a3: %dn", a3);

	return 0;
}

square.c

代码语言:javascript复制
// 计算a的平方
int func_square(int a)
{
	return a*a;
}

// 计算a的立方
int func_cube(int a)
{
	return a*a*a;
}

sum.c

代码语言:javascript复制
// 计算两数之和
int func_sum(int a, int b)
{
	return a b;
}

head.h

代码语言:javascript复制
#ifndef _HEAD_H
#define _HEAD_H

// 系统头文件
#include <stdio.h>
#include <string.h>

// 类型声明
typedef unsigned int u32;

// 用户信息结构体声明
struct usr{
	u32 uid;	// 1.用户ID
	char pwd[20];		// 2.用户密码(长度限定20字符)
};

	// 子函数外部声明
// 用户登录功能
extern int usr_login(int sum, struct usr *info);
// 显示用户信息
extern void usr_show(int sum, struct usr *info);
// 修改密码
extern void usr_update(int i, struct usr *info);
// 新增用户
extern void usr_add(void);
// 删除用户
extern void usr_del(void);

#endif

 main.c

代码语言:javascript复制
#include "head.h"

int main()
{
	// 定义1个结构体数组
	struct usr info[50] = {
		{	.uid=1,
			.pwd="123456"
		},
		{	.uid=2,
			.pwd="223456"
		},
		{	.uid=100,
			.pwd="323456"
		}
	};
	int sum=3;	//当前人数(当前有效数据个数)

// goto pos1;		// 直接跳转到44行(调试结束后记得删除!)
	// 1.用户登录功能
	int cnt=0;
	int ret;
	while(1)
	{
		ret = usr_login(sum, info);
		// printf("ret: %dn", ret);
		if(ret >= 0)
			break;
		else if(ret == -1)
			printf("No Such User!n");
		else if(ret == -2)
			printf("Password ERROR!n");
		
		cnt  ;
		printf("ERROR count: %dn", cnt);
		if(cnt>3)
		{
			printf("byebye~n");
			return -1;	//结束程序
		}
	}
	printf("[%d] Success!n", info[ret].uid);

// pos1:
	// 2.用户操作
	int cmd;
	while(1)
	{
		printf("=============CMD==============n");
		printf("0: 显示用户信息n");
		printf("1: 修改密码 n");
		printf("2: 新增用户n");
		printf("3: 删除用户n");
		printf("==============================n");
		printf("Pls Input CMD: ");
		scanf("%d", &cmd); while(getchar()!='n');
		switch(cmd)
		{
			case 0:	//显示用户信息
				usr_show(sum, info); break;
			case 1:	//修改密码
				usr_update(ret, info); break;
			case 2: //新增用户
				usr_add(); break;
			case 3: //删除用户
				usr_del(); break;
		}
	}


	return 0;
}

usr.c

代码语言:javascript复制
#include "head.h"

// 用户登录功能
int usr_login(int sum, struct usr *info)
{
	// 1.用户输入uid和密码
	struct usr input_info;
	printf("Pls Input uid: ");
	scanf("%d", &input_info.uid); while(getchar()!='n');
	printf("Pls Input pwd: ");
	scanf("%s", input_info.pwd); while(getchar()!='n');

	// 2.循环判断用户输入
	int i;
	for(i=0; i<sum; i  )
	{
		if(input_info.uid == info[i].uid)	// ID判断
		{
			// 进一步判断密码
			if(strcmp(input_info.pwd, info[i].pwd) == 0)
				return i;	// ID、密码正确,返回正确用户的下标
			else
				return -2;	// 密码错误
		}
	}

	// 如果for正常循环完毕,说明不存在该ID
	if(i==sum)
		return -1;
}

// 显示用户信息(用于调试)
void usr_show(int sum, struct usr *info)
{
	int i;
	printf("============INFO============n");
	printf("UIDt PWDn");
	for(i=0; i<sum; i  )
		printf("%dt %sn", info[i].uid, info[i].pwd);
}

// 修改密码
void usr_update(int i, struct usr *info)
{
	// 1.用户输入新密码
	char input_pwd[20];
	printf("Pls Input new pwd: ");
	scanf("%s", input_pwd); while(getchar()!='n');

	// 2.将新密码替换旧密码
	// info[i].pwd = input_pwd;		// 字符串不能直接赋值到数组中!需使用字符串拷贝函数
	strcpy(info[i].pwd, input_pwd);
}

// 新增用户
void usr_add(void)
{
	printf("usr_add 功能待完善...n");
}

// 删除用户
void usr_del(void)
{
	printf("usr_del 功能待完善...n");
}

 head.h

代码语言:javascript复制
#ifndef _HEAD_H
#define _HEAD_H

// 系统头文件
#include <stdio.h>
#include <string.h>

// 类型声明
typedef unsigned int u32;

// 用户信息结构体声明
struct usr{
	u32 uid;	// 1.用户ID
	char pwd[20];		// 2.用户密码(长度限定20字符)
};

	// 子函数外部声明
// 用户登录功能
extern int usr_login(int sum, struct usr *info);
// 显示用户信息
extern void usr_show(int sum, struct usr *info);
// 修改密码
extern void usr_update(int i, struct usr *info);
// 新增用户
extern void usr_add(void);
// 删除用户
extern void usr_del(void);

#endif

main.c

代码语言:javascript复制
#include "head.h"

int main()
{
	// 定义1个结构体数组
	struct usr info[50] = {
		{	.uid=1,
			.pwd="123456"
		},
		{	.uid=2,
			.pwd="223456"
		},
		{	.uid=100,
			.pwd="323456"
		}
	};
	int sum=3;	//当前人数(当前有效数据个数)

// goto pos1;		// 直接跳转到44行(调试结束后记得删除!)
	// 1.用户登录功能
	int cnt;
	int ret;
	for(cnt=2; cnt>=0; cnt--)	// 2 1 0
	{
		ret = usr_login(sum, info);
		// printf("ret: %dn", ret);
		if(ret >= 0)	// 如正确,直接跳出
			break;
		else if(ret == -1)
			printf("ERROR: 无此用户![还剩%d次机会.]n", cnt);
		else if(ret == -2)
			printf("ERROR: 密码错误![还剩%d次机会.]n", cnt);
	}
	if(cnt<0)
	{
		printf("3次错误! 程序结束!n");
		return -1;
	}
	printf("欢迎登陆! 用户ID: [%d]!n", info[ret].uid);

// pos1:
	// 2.用户操作
	int cmd;
	while(1)
	{
		printf("=============CMD==============n");
		printf("0: 显示用户信息n");
		printf("1: 修改密码 n");
		printf("2: 新增用户n");
		printf("3: 删除用户n");
		printf("==============================n");
		printf("Pls Input CMD: ");
		scanf("%d", &cmd); while(getchar()!='n');
		switch(cmd)
		{
			case 0:	//显示用户信息
				usr_show(sum, info); break;
			case 1:	//修改密码
				usr_update(ret, info); break;
			case 2: //新增用户
				usr_add(); break;
			case 3: //删除用户
				usr_del(); break;
		}
	}


	return 0;
}

usr.c

代码语言:javascript复制
#include "head.h"

// 用户登录功能
int usr_login(int sum, struct usr *info)
{
	// 1.用户输入uid和密码
	struct usr input_info;
	printf("Pls Input uid: ");
	scanf("%d", &input_info.uid); while(getchar()!='n');
	printf("Pls Input pwd: ");
	scanf("%s", input_info.pwd); while(getchar()!='n');

	// 2.循环判断用户输入
	int i;
	for(i=0; i<sum; i  )
	{
		if(input_info.uid == info[i].uid)	// ID判断
		{
			// 进一步判断密码
			if(strcmp(input_info.pwd, info[i].pwd) == 0)
				return i;	// ID、密码正确,返回正确用户的下标
			else
				return -2;	// 密码错误
		}
	}

	// 如果for正常循环完毕,说明不存在该ID
	if(i==sum)
		return -1;
}

// 显示用户信息(用于调试)
void usr_show(int sum, struct usr *info)
{
	int i;
	printf("============INFO============n");
	printf("UIDt PWDn");
	for(i=0; i<sum; i  )
		printf("%dt %sn", info[i].uid, info[i].pwd);
}

// 修改密码
void usr_update(int i, struct usr *info)
{
	// 1.用户输入新密码
	char input_pwd[20];
	printf("Pls Input new pwd: ");
	scanf("%s", input_pwd); while(getchar()!='n');

	// 2.将新密码替换旧密码
	// info[i].pwd = input_pwd;		// 字符串不能直接赋值到数组中!需使用字符串拷贝函数
	strcpy(info[i].pwd, input_pwd);
}

// 新增用户
void usr_add(void)
{
	printf("usr_add 功能待完善...n");
}

// 删除用户
void usr_del(void)
{
	printf("usr_del 功能待完善...n");
}

0 人点赞