day12嵌入式(2022.1.18)

简介: day12嵌入式(2022.1.18)

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


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



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


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



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


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



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


练习:


根据proj2,定义结构体数组(长度50),初始化3个用户的信息。


需将usr_login函数移到usr.c中


修改usr_login函数,使得可以判断多个用户。


要求用户uid和密码可多次输入,当超过3次,提示次数过多,结束程序。


登录成功后,显示操作菜单:0: 显示用户信息 usr_show()


1: 修改密码         usr_update()


2: 新增用户 usr_add()


3: 删除用户 usr_del()


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


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



练习:


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


main.c 放入main主函数


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


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


head.h 工程头文件


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



head.h


#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


#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: %d\n", sum);
  int a3=func_cube(a);
  printf("a3: %d\n", a3);
  return 0;
}


square.c


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


sum.c


// 计算两数之和
int func_sum(int a, int b)
{
  return a+b;
}



head.h


#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


#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: %d\n", 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: %d\n", 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


#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("UID\t PWD\n");
  for(i=0; i<sum; i++)
    printf("%d\t %s\n", 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


#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


#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: %d\n", 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


#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("UID\t PWD\n");
  for(i=0; i<sum; i++)
    printf("%d\t %s\n", 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");
}
相关文章
|
11月前
嵌入式day2(2022.1.7)
嵌入式day2(2022.1.7)
59 0
|
11月前
|
存储
day7嵌入式(2022.1.13)
day7嵌入式(2022.1.13)
52 0
|
11月前
|
存储 编译器
day8嵌入式(2022.1.14)
day8嵌入式(2022.1.14)
51 0
|
11月前
|
Linux Windows
day9嵌入式(2022.1.15)
day9嵌入式(2022.1.15)
66 0
|
11月前
嵌入式day6(2022.1.12)
嵌入式day6(2022.1.12)
58 0
|
11月前
嵌入式day1(2022.1.6)
嵌入式day1(2022.1.6)
52 0
|
11月前
|
C语言
嵌入式day4(2022.1.10)
嵌入式day4(2022.1.10)
60 0
|
11月前
|
存储 Java C#
day10嵌入式(2022.1.16)
day10嵌入式(2022.1.16)
86 1
|
11月前
|
自然语言处理 编译器 C语言
day11嵌入式(2022.1.17)
day11嵌入式(2022.1.17)
67 0
|
传感器 设计模式 Ubuntu
嵌入式到底该怎么学
其实一直有人问我嵌入式怎么学,今天跟大家讲讲我的理解。因为嵌入式是一个泛的概念,可能很多人认为嵌入式就是嵌入式Linux。但是其实并不仅仅只有Linux, 像STM32,51单片机也属于这个范畴之内的,它们有的也可以跑协议栈,跑ucos等系统。所以其实嵌入式是有很多方向的,选择一个方向,做好,做精,都是有前途的。接下来,跟大家探讨一下嵌入式的一些方向,和如何去学习。我以前也是摸索着过来的,没人告诉我如何学习,也没有学习线路,所以走了很多弯路。所以希望这篇文章可以帮助到一些正在学习的人,当然这些内容可能有主观的东西,欢迎大家一起探讨吧。