前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C/CPP基础知识练习题即分析

C/CPP基础知识练习题即分析

作者头像
CtrlX
发布2022-09-23 15:59:35
1.1K0
发布2022-09-23 15:59:35
举报
文章被收录于专栏:C++核心编程

解答者:IO-CtrlX

解答及供参考,若有更优解请务必告知

1. 运算符

代码语言:javascript
复制
1. 设计一个程序, 输入三位数a, 分别输出个,十,百位.
(0<a<1000)

样例输入: 
251

样例输出: 
2
5
1

代码语言:javascript
复制
2. 设计一个程序, 输入整数l, 求边长为l的正方形面积, 比直径为l的圆形面积大多少.  
(0<l<1000, PI取3.14, 输出结果保留两位小数)

样例输入:
3
样例输出:
1.93

解答

输出个,十,百位

代码语言:javascript
复制
#include<iostream>
using namespace std;

void separate(int num)
{
	cout << num / 100 << endl;
	cout << (num - (num / 100*100))/10 << endl;
	cout << num % 10 << endl;
}

int main()
{
	int num = 0;

	cout << "Input:" ; cin >> num;

	separate(num);

	system("pause"); return 0;
}

2.圆与正方形面积差

代码语言:javascript
复制
#include<iostream>
using namespace std;

#define PI 3.14

void AreaDifference(int num)
{
	cout << num*num - PI*(0.5)*num*(0.5)*num<< endl;
}

int main()
{
	 cout << "Input:" ; int num = 0; cin >> num;

	AreaDifference(num);

	system("pause"); return 0;
}

2. 判断

代码语言:javascript
复制
1. 设计一个程序, 输入a,b,c三个整数, 输出最大的数.
(MIN_INT < a,b,c < MAX_INT)

样例输入:
1 3 2
样例输出:
3

代码语言:javascript
复制
2. 打分系统
在某次考试时, 学生的提交成绩惨不忍睹
云海学长为了让大家及格可谓煞费苦心, 他苦思三天三夜, 终于想出了一套打分方案:
正确数量在0~10时, 每题6分
正确数量在11~20时, 第11~20题, 每题2分
正确数量在21~40时, 第21~40题, 每题1分

但因为需要计分的作业太多了, 希望你能帮帮云海学长, 实现该计分程序.
输入做对的题目数量n, 输出得分.
(0<=n<=40)

样例输入:
23
样例输出:
83
代码语言:javascript
复制
3. 东东哥上班
东东哥在上班途中, 可以选择走路和骑车两种方式
但他不清楚哪种方式比较快, 因为骑车需要找车, 开锁, 停车 需要耽搁很多时间.
设找到自行车, 开锁, 骑上自行车需要花27秒, 停车需要花23秒
步行每秒1.2米, 骑车每秒3.0米
给出东东哥距离公司的距离, 请问是骑车快还是走路快.

输入一个整数n, 表示到公司的距离
如果骑车快, 输出"骑车"
如果走路快, 输出"走路"
如果一样快, 输出"一样快"

样例输入:
60
样例输出:
走路

解答

1.求最大值

代码语言:javascript
复制
#include<iostream>
using namespace std;

void AreaDifference(int a,int b,int c)
{
	a > b ? (a > c ? cout << a : cout << c) : (b > c ? cout << b : cout << c);
}

int main()
{
	cout << "Input:"; 

	int a = 0, b = 0, c = 0; 
	cin >> a; cin >> b; cin >> c;

	AreaDifference(a,b,c);

	system("pause"); return 0;
}
代码语言:javascript
复制
//最大数
void Demo21() {
    //--变量声明--
    //输入值
    int a, b, c;
    //最大值
    int max;

    //--接收输入--
    scanf_s("%d %d %d", &a, &b, &c);

    //--数据处理--
    max = a;
    if (b > max) {
        max = b;
    }
    if (c > max) {
        max = c;
    }

    //--输出--
    printf("%d", max);
}

2.打分系统

代码语言:javascript
复制
#include<iostream>
using namespace std;

int Score(int a)
{
	if (a >= 0 && a <= 10) {
		return a * 6;
	}
	else if (a >= 11 && a <= 20) {
		return a * 2;
	}
	else {
		return a * 1;
	}
}

int main()
{
	cout << "Input:"; 

	int a = 0; cin >> a;
	if (a >= 0 && a <= 40) { cout << Score(a) << endl; }
	else { cout << "输入错误" << endl; }

	system("pause"); return 0;
}
代码语言:javascript
复制
// 打分系统
void Demo22() {
    //--变量声明--
    // 输入
    int n;
    // 输出
    int result;

    //--接收输入--
    scanf_s("%d", &n);

    //--数据处理--
    if (n <= 10) result = n * 6;
    else if (n <= 20) result = 10 * 6 + (n - 10) * 2;
    else result = 10 * 6 + 10 * 2 + (n - 20) * 1;

    //--输出--
    printf("%d", result);
}

3.交通工具选择问题

代码语言:javascript
复制
#include<iostream>
using namespace std;

void Goout(int n)
{
	if ((n / 1.2) == (n / 3 + 27 + 23)) { cout << "一样快"<<endl; }
	else
	{
		(n / 1.2) < (n / 3 + 27 + 23) ? cout << "步行"<<endl : cout << "骑车"<<endl;
	}
}

int main()
{
	cout << "Input:"; 
	int n = 0; cin >> n;

	Goout(n);

	system("pause"); return 0;
}
代码语言:javascript
复制
// 上班
void Demo23() {
    //--变量声明--
    // 输入
    int n;
    // 负数表示骑车快, 正数表示走路快, 0表示一样快
    double result;

    //--接收输入--
    scanf_s("%d", &n);

    //--数据处理--
    //用骑车速度减去走路速度  如果是正数表示骑车耗时多
    result = (27 + 23 + n / 3.0) - (n / 1.2);

    //--输出--
    // 注意double判断会有精度问题  不能直接判断==0
    if (result < 0.0001) printf("骑车");
    else if (result > 0.0001) printf("走路");
    else printf("一样快");
}

3. 简单循环

代码语言:javascript
复制
1. 求平均年龄
01星球有学长若干名, 给出每个学长的年龄, 求01星球学长的平均年龄, 保留小数点后两位
输入: 
第一行: 整数n(1<n<100), 表示人数
之后n行: 每行一个整数a(15<a<55), 表示第n个学长的年龄
输出:
一个浮点数, 保留两位小数. 表示01星球学长平均年龄

样例输入:
3
18
18
17
样例输出:
17.67
代码语言:javascript
复制
2. 张三上课时走神, 在作业上写了很多222222222222222 结果被老师发现了
张三连忙掩饰说自己在算2+22+222+2222+22222的和, 
老师很欣慰, 问他算出来没有
张三很困扰, 因为草稿纸写满了2  已经不够用了

大家快帮帮张三吧
设计一个程序, 输入n和a 求Sn
Sn = a + aa + aaa + … + aaaaa(n个a)

输入: 两个整数n, a
(1<n<9), (1<=a<=9)
输出:
Sn的值

样例输入:
5 2
样例输出:
24690
样例解析: Sn = 2 + 22 + 222 + 2222 + 22222 = 24690

样例输入:
4 5
样例输出:
6170
样例解析: Sn = 5 + 55 + 555 + 5555
代码语言:javascript
复制
3. super家养了一对刚出生的兔子, 兔子出生3个月起每月都会生一对小兔子, 小兔子出生后三个月起也会每月生一对兔子
super想知道 如果兔子不死 n月后家里会有多少对兔子
设计一个程序: 输入n, 输出兔子数量
(2<n<30)

样例输入: 7
样例输出:13

样例输入: 12
样例输出: 144
代码语言:javascript
复制
4. 云海学长为了探究神秘的物理现象, 从高楼抛下一个弹球 但由于高空抛物被警察抓了, 请各位小伙伴完成他未完成的心愿
小球从某一高度落下,每次落地后反跳回原来高度的一半,再落下。
输入弹球的初始高度M和回弹次数N, 输出弹球第N次回弹后的高度 和达到该高度后所经过的距离(保留两位小数)
(0<M<1000, 0<N<50)

样例输入
1000 5
样例输出
31.25
2906.25

解答

1.求平均年龄

代码语言:javascript
复制
#include<iostream>
using namespace std;

float Age(int n)
{
	float num = 0;
	for (int i = 0; i < n; i++)
	{
		float age = 0;cin >> age;
		num += age;
	}
	return num/n;
}

int main()
{
	cout << "Input:"; 
	int n = 0; cin >> n;

	cout<<Age(n)<<endl;

	system("pause"); return 0;
}
代码语言:javascript
复制
// 求平均年龄
void Demo31() {
    //--变量声明--
    // 人数, 临时记录变量, 学长的年龄总和
    int n, temp = 0;
    double age = 0;

    //--接收输入--
    // 注意这里age+=temp   也就是存储了所有学长年龄的和
    scanf_s("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf_s("%d", &temp);
        age += temp;
    }

    //--数据处理--
    age /= n;

    //--输出--
    printf("%.2lf", age);
}

✨2.数列求和

代码语言:javascript
复制
#include<iostream>
using namespace std;

int Sum(int a, int n)
{
	int num = 0;
	for (int i = 1; i <= a; i++)
	{
		int b = 1;
		for (int j = 0; j < i; j++)
		{
			b *= 10;
		}
		num += b / 9;
	}
	return num * n;
}

int main()
{
	cout << "Input:"<< endl; 
	int a = 0,n = 0; cin >> a; cin >> n;
	cout << Sum(a, n) << endl;

	system("pause"); return 0;
}
代码语言:javascript
复制
#include<iostream>
using namespace std;

int Sum(int a, int n)
{
	int num = 0,count = n;
	for (int i = 1; i <= a; i++)
	{
		num += count;
		count = count * 10 + n;
	}
	return num ;
}

int main()
{
	cout << "Input:" << endl;
	int a = 0, n = 0; cin >> a; cin >> n;
	cout << Sum(a, n) << endl;

	system("pause"); return 0;
}
代码语言:javascript
复制
// 求2222222
void Demo32() {
    //--变量声明--
    // 输入n, 输入a, 累加数存储变量, 答案存储变量
    int n, a;
    int num, result = 0;

    //--接收输入--
    scanf_s("%d %d", &n, &a);
    num = a;

    //--数据处理--
    /*
        num用于存储a,aa,aaa这样的数字

        num = aaa
        num*10 = aaa0
        num*10+a = aaaa
    */  
    for (int i = 0; i < n; i++) {
        result += num;
        num = num * 10 + a;
    }


    //--输出--
    printf("%d", result);

}

3.斐波那契数列

代码语言:javascript
复制
#include<iostream>
using namespace std;

int Sum(int n)
{
	int a = 0, b = 1;
	if (n == 1 && n == 2) { return 1; }
	else 
	{
		for (int i = 0; i < n; i++)
		{
			int temp = a + b;
			a = b;
			b = temp;
		}
		return a;
	}
}

int main()
{
	cout << "Input:"; 
	int n = 0; cin >> n;
	cout << Sum( n) << endl;

	system("pause"); return 0;
}
代码语言:javascript
复制
// 数兔子
void Demo33() {
    //--变量声明--
    // 用户输入值  月数
    int n;
    // 用于存储当月 以及前1,2个月的兔子数
    int m1 = 1, m2 = 1, m3 = 0;;

    //--接收输入--
    scanf_s("%d", &n);

    //--数据处理--
    //前两个月不生兔子
    // 每个月的兔子数量   =  上一个月兔子数 + 上上一个月兔子数
    n -= 2;
    while (n--) {
        m3 = m1 + m2;
        m1 = m2;
        m2 = m3;
    }

    //--输出--
    printf("%d", m3);
}

✨4.抛物问题

代码语言:javascript
复制
#include<iostream>
using namespace std;

float YunHai(float m,float n)
{
	
}

int main()
{
	cout << "Input:"; 
	float m = 0, n = 0; cin >> m; cin >> n;
	cout << YunHai( m,n ) << endl;

	system("pause"); return 0;
}

4.嵌套循环

代码语言:javascript
复制
1. 使用程序打印九九乘法表
样例输出: 
1 * 1 = 1
1 * 2 = 2    2 * 2 = 4
1 * 3 = 3    2 * 3 = 6    3 * 3 = 9
….
代码语言:javascript
复制
2. 求素数
设计一个程序,  输入N, 输出0~N之间的所有素数
(0<N<MAX_INT)
样例输入: 
100
样例输出:
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
代码语言:javascript
复制
3.小游戏: 猜数字
输入整数n(0<n<100), 想让程序猜到的值
如果程序没有猜中, 则提示太大/太小  并让程序接着猜测
程序通过二分法不断缩小猜测范围, 直到猜中n

例如n = 39
程序第一次猜测50, 判断数值太大
第二次猜测25, 判断数值太小
第三次猜测37 判断数值太小
43 大
40 大
38 小
39 正确

输入: n 表示被猜测值
输出: 每行输出一个整数, 表示程序当前猜测的数字
最终行输出猜测的次数

样例输入:
39
样例输出:
50
25
37
43
40
38
39
最终猜测了7次
代码语言:javascript
复制
4.打印菱形
输入菱形的边长n, 打印一个对应大小的菱形
(1<n<100)

样例输入: 5
样例输出:
     *
    ***
   *****
  *******
 *********
  *******
   *****
    ***
     *

解答

1.打印九九乘法表

代码语言:javascript
复制
#include<iostream>
using namespace std;

void ChengFaKJ()
{
	for (int i = 1; i <= 9; i++)
	{
		for (int j = 1; j <= i; j++)
		{
			cout << j << " * " << i << " = " << i * j<<" ";
		}
		cout << endl;
	}
}

int main()
{

	ChengFaKJ();
	system("pause"); return 0;
}
代码语言:javascript
复制
// 乘法表
void Demo41() {
    //--变量声明--

    //--接收输入--

    //--数据处理--
    
    //--输出--
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= i; j++) {
            printf("%d * %d = %d\t", j, i, i * j);
        }
        printf("\n");
    }

}

✨2.求素数

代码语言:javascript
复制
#include<iostream>
using namespace std;

void ChengFaKJ(int n)
{
	int i, j;
	for (i = 2; i <= n; i++)
	{
		for (j = 2; j < sqrt(i); j++)
		{
			if (i % j == 0) break;
		}
		if (j == int(sqrt(i)) + 1)
			cout << i << endl;
	}
}

int main()
{
	int n = 0; cin >> n;
	if (n < 2) cout << "NULL";
	else if (n == 2)cout << 2 <<endl;
	else 
	{ 
		ChengFaKJ(n);
	}
	system("pause"); return 0;
}
代码语言:javascript
复制
// 求素数
void Demo42() {
    //--变量声明--
    // 输入值
    int N;
    // 标识符  值为1表示素数  值为0表示非素数
    int flag;
    //--接收输入--
    scanf_s("%d", &N);
    //--数据处理--
    //--输出--
    for (int i = 2; i <= N; i++) 
    {
        flag = 0;
        for (int j = 2; j < i/*sqrt(i)*/; j++) 
        {
            // 如果i%j为0  则该数字是非素数   0表示假  !取反为真
            if (!(i % j)){
                flag = 1;
                break;
            }
        }
        //如果flag是0  表示是素数 打印
        if (!flag) printf("%d\n", i);
    }
}

PS:

sqrt()函数在c语言中用于计算一个非负实数的平方根,开根号;其语法为double sqrt(double)。在sqrt()函数中没有sqrt (int),但是返回值可以为int,返回值可以与int类型进行运算。

等同用法:j*j<i

代码语言:javascript
复制
for(int j=2;j*j<=i;j++)//j*j<i;相当于对i开了根号,j只用加到i的平方根,而不用加到i-1减少了计算量
           {
               if((i%j)==0)
               {
                   flag++;//如果有因数,flag+1
                   break;//有因数,直接结束内层循环,减少计算量
               }
           }

详细分析:

质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。“1”既不是素数,也不是合数。

因为如果一个数不是素数是合数,那么一定可以由两个自然数相乘得到,其中一个大于或等于它的平方根,一个小于或等于它的平方根。并且成对出现,所以只用计算到该数的平方根以下看除了1有没有该数的因数,若没有,则是素数。

代码语言:javascript
复制
(1)质数p的约数只有两个:1和p。
(2)初等数学基本定理:任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的。
(3)质数的个数是无限的。
(4)大于10的质数中,个位数只有1,3,7,9。

✨3.猜数字

代码语言:javascript
复制
// 猜数字
void Demo43() {
    //--变量声明--
    // 用户输入 让程序猜的数字
    int n;
    // 程序猜测的次数, 二分猜测法的上下限
    int count = 0, max = 100, min = 0;
    //猜测值
    int mid;

    //--接收输入--
    scanf_s("%d", &n);
    do{
        //--数据处理--
        /*
            猜测值 = (上限 + 下限) /2
            如上限100  下限0   猜测值=50
            上限100  下限50  猜测值=75

            如果猜测值比n小,  则下限 = 猜测值+1
            如果猜测值比n大,  则上d限 = 猜测值-1
        */
        count++;
        mid = (max + min) / 2;
        if (mid > n) {
            max = mid - 1;
        }
        else if (mid < n) {
            min = mid + 1;
        }

        //--输出--
        printf("%d\n", mid);

    } while (mid != n);
    printf("最终猜测了%d次", count);

}

✨4.打印菱形

代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	cout << "Input:";
	int n;cin >> n;
	for (int i = 0; i < n; i++)                    
	{
		for (int j = 0; j < (n - 1 - i); j++)          
		{
			cout << " ";                      
		}                                      
		for (int j = 0; j < 2 * i + 1; j++)// *号是等差序列的公式2n+1          
		{
			cout << "*";                      
		}
		cout << endl;
	}
    //难点:下方三角形:思路一
	for (int i = 0; i < n - 1; i++)//打印店层数一定是奇数,最大的一层在上面被打印   
	{
		for (int j = 0; j < i + 1; j++)
		{
			cout << " ";
		}
		for (int j = 0; j < 2 * (n - 1) - (2 * i + 1); j++)//2(n-1)是菱形分割线往下的第一行,是个定值,把下面的部分看成是一个由*组成的矩形,矩形的每一行减去递增的等差数列2i+1个*形成递减的等差数列。
		{
			cout << "*";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}
代码语言:javascript
复制
#include<iostream>
using namespace std;
int main()
{
	cout << "Input:";
	int n; cin >> n;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < (n - 1 - i); j++)
		{
			cout << " ";
		}
		for (int j = 0; j < 2 * i + 1; j++)// *号是等差序列的公式2n+1          
		{
			cout << "*";
		}
		cout << endl;
	}

	//另一思路:
	for (int i = n - 2 ; i >= 0; i--)//打印店层数一定是奇数,最大的一层在上面被打印   
	{
        //与上面完全相同
		for (int j = 0; j < (n - 1 - i); j++)
		{
			cout << " ";
		}
		for (int j = 0; j < 2 * i + 1; j++)
		{
			cout << "*";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}
代码语言:javascript
复制
// 打印菱形
void Demo44() {
    //--变量声明--
    //菱形边长
    int n;
    //--接收输入--
    scanf_s("%d", &n);

    //--数据处理--
    //坐标系思路
    
    //--输出--
    // 当n为5时, 坐标系的上下限分别是-4~4  最大高/宽度为9
    for (int i = -n+1; i < n; i++) {//层数。-4(包括-4本身)到4,共9层。
        for (int j = -n+1; j < n; j++) {//每一层内的元素数。-4(包括-4本身)到4,共9个元素。
            // i的绝对值+j的绝对值 小于n  则在菱形范围内
            if (abs(i) + abs(j) < n) {
                printf("*");
            }
            else {
                printf(" ");
            }
        }
        printf("\n");
    }
}

详细分析:

用坐标系的思路: 设坐标点(x,y),以菱形的中心为坐标原点。 当x的绝对值 + y的绝对值 小于n时, 这个坐标点在菱形内 当x的绝对值 + y的绝对值 大于等于n时, 这个坐标点在菱形外

代码语言:javascript
复制
以边长为5的菱形为例:
    y
    ^
    |
    |
    *(0,4)
   ***
  *****
 *******
****.****(4,0)——————————>x
 *******
  *****
   ***
    *
    
在第一象限中的菱形边长为y = -x + 4,这个直线就是临界,y + x = 4,当y + x > 4时这个坐标点在菱形外。如: (2,2)在菱形内, (3,2)在菱形外, (-4,0)在菱形内, (4,1)在菱形外。
同理,当配合绝对值 也就是正负号就可以画出4条线,构成菱形。

5.一维数组

代码语言:javascript
复制
1. 删除重复值
阿伟学长在开发一款游戏, 他希望玩家已经获得的道具会降低爆率, 避免玩家获得太多重复的道具
但玩家背包中道具是乱序且不确定的, 为了减小判断的运算量, 需要先对数据进行去重.

设计一个程序, 输入数据数量N, 以及N个整数Ni. 将该组数据去重后打印
(1<N<100,  0 <= Ni <= MAX_INT)
样例输入:
10
1 3 2 6 2 6 4 8 2 6
样例输出:
1 3 2 6 4 8
代码语言:javascript
复制
2. 数字环
有一个长度为n的数字环, 将每个数字往后移动m位, 使其成为一个新的数字环
输入: 
第一行: 整数n  表示有n个数字
第二行: n个整数Ni, 表示数字环的每个元素
第三行: 整数m  表示每个元素需要往后移动m位
输出: 移动后的新数字环
(1<=m<n<100, MIN_INT<Ni<MAX_INT)

样例输入:
10
1 2 3 4 5 6 7 8 9 10
2
样例输出:
9 10 1 2 3 4 5 6 7 8 
代码语言:javascript
复制
3. 排队枪毙
小约参与了犹余游戏, 在这个游戏中最后活下来的人才能获得胜利.
游戏规则是这样的, n个玩家们围成一个圈, 从第一个玩家开始报数
报到m的人被枪毙, 下一个人接着从1开始报数.
直到最后一个活下来的人获得胜利.

小约现在开始选编号了, 已知参与的玩家数量为n, 被枪毙的数是m. 小约要选到几号位置才会活下来.
(1<m<n<100)

设计一个程序, 输入n和m, 输出最后的胜利者

样例输入: 10 3
样例输出: 4

解答

✨1.数组去重

代码语言:javascript
复制
#include<iostream>
#include<algorithm>
using namespace std;


void SortShuZ(int n,int a[])
{
	sort(a, a + n); //将数组从小到大排序 

	for (int i = 0; i < n; i++)
	{
		if (a[i] != a[i + 1]) cout << a[i] << " ";
	}
}

int main()
{
	int n;cin >> n;
    
	int a[100] = {0};
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
    
	SortShuZ(n,a);

	system("pause"); return 0;
}
代码语言:javascript
复制
// 去重
void Demo51() {
    //--变量声明--
    //数据总数, 去重后的数量
    int N, len;
    //待去重的数据
    int arr[100];

    //--接收输入--
    scanf_s("%d", &N);
    len = N;
    for (int i = 0; i < N; i++) {
        scanf_s("%d", &arr[i]);
    }
    //--数据处理--
    /*
        将每个元素都和后面的元素进行判断
            如果[i]和[j]值重复, 将[j]的值设为-1.  并且len--
        {1,3,2,6,-1,-1,4,8,-1,-1}

        都判断一遍后, 将值为-1的元素  用后一个元素值进行覆盖
        {1,3,2,6,4,8}
    */
    for (int i = 0; i < N; i++) 
    {
        for (int j = i + 1; j < N; j++) 
        {
            if (arr[i] == -1) break;

            if (arr[i] == arr[j]) 
            {
                arr[j] = -1;
                len--;
            }
        }
    }

    
    for (int i = 0, j = 0;j < j++) 
    {

        arr[i] = arr[j];
        if (arr[i] != -1) 
        {
            i++;
        }
        
    }


    //--输出--
    for (int i = 0; i < len; i++) 
    {
        printf("%d ", arr[i]);
    }

}

代码语言:javascript
复制
/*
        快慢指针思路

        i表示慢下标, j表示快下标
        快下标: 每次循环往后移动一位
        慢下标: 条件符合时往后移动一位

        每次循环时, arr[i] = arr[j]
        慢下标条件: 覆盖后, 如果当前[i]的值不为-1  则i++(往后移动一位)

        下面样例的截取点是在arr[i] = arr[j]后  i++前

        ij
        1       2       -1      3       -1      4       -1      5       6

                ij
        1       2       -1      3       -1      4       -1      5       6

                        ij
        1       2       -1      3       -1      4       -1      5       6

                        i       j
        1       2       3       3       -1      4       -1      5       6

                                i       j
        1       2       3       -1      -1      4       -1      5       6

                                i               j
        1       2       3       4       -1      4       -1      5       6

                                        i               j
        1       2       3       4       -1      4       -1      5       6

                                        i                       j
        1       2       3       4       5       4       -1      5       6

                                                i                       j
        1       2       3       4       5       6       -1      5       6
*/

✨2.数字环

代码语言:javascript
复制
#include<iostream>
using namespace std;

//移动数组
void ShuZiH(int n,int a[])
{
	int temp = a[0];
	for (int i = 0; i < n; i++)
	{
		a[i] = a[i + 1];
	}
	a[n - 1] = temp;
}

//输出数组
void Print(int n,int a[])
{
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << " ";
	}
}

int main()
{
	int n;cin >> n;

	//输入数组
	int a[100] = {0};
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	//循环移动次数
	int m; cin >> m;
	for (int i = 0; i < m; i++)
	{
		ShuZiH(n, a);
	}
	//打印移动后的数组
	Print(n,a);

	system("pause"); return 0;
}
代码语言:javascript
复制
// 数字环
void Demo52() {
    //--变量声明--
    // 数字环存储数组, 长度, 移动位数
    int arr[100], len, m;
    // 转换后数组
    int result[100];
    

    //--接收输入--
    scanf_s("%d", &len);
    for (int i = 0; i < len;i++) {
        scanf_s("%d", &arr[i]);
    }
    scanf_s("%d", &m);


    //--数据处理--
    for (int i = 0; i < len; i++) {
        result[(i + m) % len] = arr[i];
    }
    //巧妙之处(i + m) % len,例如当123456六个数移动m=5位,以3为例,当3向后移动5位后到了2的位置,(3+5)%6=2
    //注意这种处理越界的方法!
    


    //--输出--
    for (int i = 0; i < len; i++) {
        printf("%d ", result[i]);
    }

}

巧妙之处(i + m) % len,注意这种处理越界的方法!

详细分析:

最终数组result[(i + m) % len]目标原始数组arr[i]

例如当123456六个数移动m=5位,最后顺序应是234561

在for循环中arr[i]从1-6按顺序赋值给result,需要排序的是result,

代码语言:javascript
复制
(0+5)%6 = 5 result[5] = 1//向后移动5位,没有超出长度,所以余数还是5

(1+5)%6 = 0 result[0] = 2

(2+5)%6 = 1 result[1] = 3

(3+5)%6 = 2 result[2] = 4//向后移动8位,超出了长度6,即超出了界限,超出了2,余数为2

(4+5)%6 = 3 result[3] = 5

(5+5)%6 = 4 result[4] = 6

核心不过如此:向后移动几位,除以这个数组的长度,余数就是多出了这个数组长度的值,相当于你要移动的位数减去原数组的长度。

进阶玩法见下面的密码加密题目

✨3.约瑟夫环

代码语言:javascript
复制
// 约瑟夫环
void Demo53() {
    //--变量声明--
    // 玩家数量, 被枪毙数, 玩家当前状况
    // 值为1表示存活  值为0表示被枪毙了
    int n, m, arr[100];
    // 目前活着的人数, flag用于标记当前数到几
    int num, flag = 0;

    //--接收输入--
    scanf_s("%d %d", &n, &m);
    num = n;
    for (int i = 0; i < n; i++) {
        arr[i] = 1;
    }

    //--数据处理--
    for (int i = 0; num - 1; i++)//for循环运行过程中的判断条件是num - 1,当for循环1号位置(num - 1)为0时for循环不成立,退出。 
    {
        if (i == n) i = 0;//在循环运行过程中i++,当i等于总人数时将i归零,防止下面的数组越界(注意是n,不是n - 1,因为arr[n]就是越界了,arr[n - 1]是修后一个人,不能让i = n)
        if (arr[i]) //arr[i]是0或者1,是0则跳过,是1运行if语句
        {
            flag++;//1代表人未被枪毙,在存活的人里报数
            if (flag == m)
            {
                arr[i] = 0;
                flag = 0;//并且重新报数
                num --;//未被枪毙的人的数量减去1,当num = 1时代表只有一个人,此时num - 1 = 0,退出。
            }
        }
    }


    //--输出--
    for (int i = 0; i < n; i++) {
        if (arr[i]) printf("%d", i + 1);
    }

}

6.多维数组

代码语言:javascript
复制
1. 矩阵转置
输入一个数字构成的矩形, 将矩形的值进行转置后打印

输入:
第一行 正整数n(1<n<10), 表示矩阵的边长
随后输入一个矩阵
输出:
转置后的矩阵

样例输入: 
3
1 2 3
4 5 6
7 8 9
样例输出:
1 4 7
2 5 8
3 6 9

代码语言:javascript
复制
2. 颈椎病治疗
最近云海学长一直对着电脑改bug, 颈椎不舒服, 希望各位小伙伴帮云海学长治治
提供一张图片, 将图片旋转后再发给云海学长, 这样学长看图的时候就需要歪着脖子, 时间久了, 颈椎病就治好了

输入一个数字构成的矩形, 将矩形的值进行90度旋转后打印

输入:
第一行 正整数n(1<n<10), 表示矩阵的边长
随后输入一个矩阵
输出:
90度旋转后的矩阵

样例输入: 
3
1 2 3
4 5 6
7 8 9
样例输出:
7 4 1
8 5 2
9 6 3
代码语言:javascript
复制
3. 杨辉三角
输入n(1<n<10), 打印高度为n的杨辉三角
样例输入: 5
样例输出:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
代码语言:javascript
复制
*4. 包围圈
东东哥在一场军事演练中, 需要对一片正方形森林进行排查, 
为了防止被包围, 东东哥需要先排查外围才能进一步深入
输入: 正整数n(1<n<10),  表示森林的边长
输出: 东东哥排查森林的顺序

样例输入:
4
样例输出:
1   2   3   4
12 13 14  5
11 16 15  6
10   9  8   7

解答

1.矩阵转置

代码语言:javascript
复制
#include<iostream>
using namespace std;

const int N = 10;

//按数字顺序生成二维数组
void FuZhi(int n,int a[][10])
{
    int k = 0; 
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            k++;
            a[i][j] = k;
        }
    }
}

//转置,行和列互换
void ZhuanZ(int n,int a[][N])
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (i > j)
            {
                int t = a[i][j];
                a[i][j] = a[j][i];
                a[j][i] = t;
            }
        }
    }
}

//打印
void Print(int n,int a[][10])
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cout<<a[i][j];
        }
        cout << endl;
    }
}

int main()
{
    int n; cin >> n;
    if (n > 1 && n <= N) 
    {
        int a[N][N];
        
        FuZhi(n, a);
        Print(n, a);
        cout << "转置后:" << endl;
        ZhuanZ(n, a);
        Print(n, a);
    }

    system("pause"); return 0;
}
代码语言:javascript
复制
// 矩阵转置
void Demo61() {
    //--变量声明--
    // 矩阵边长, 矩阵本身, 转置后数组
    int size, arr[10][10], result[10][10];
    //--接收输入--
    scanf_s("%d", &size);
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            scanf_s("%d", &arr[i][j]);
        }
    }
    //--数据处理--
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            result[j][i] = arr[i][j];
        }
    }


    //--输出--
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%d ", result[i][j]);
        }
        printf("\n");
    }

}

✨2.矩阵90°转置

代码语言:javascript
复制
// 颈椎病
void Demo62() {
    //--变量声明--
    // 矩阵边长, 矩阵本身, 转置后数组
    int size, arr[10][10], result[10][10];
    //--接收输入--
    scanf_s("%d", &size);
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            scanf_s("%d", &arr[i][j]);
        }
    }

    //--数据处理--
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            result[j][size - i - 1] = arr[i][j];
        }
    }

    //--输出--
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%d ", result[i][j]);
        }
        printf("\n");
    }
}

详细分析:

代码语言:javascript
复制
//数组下标变化:
    
	假设size为3
      0 1 2                     
    0 1 2 3
    1 4 5 6       
    2 7 8 9
    ->
      0 1 2 
    0 7 4 1
    1 8 5 2    
    2 9 6 3
        
 x1 y    y  x2
[0][0]->[0][2]
[0][1]->[1][2]
[1][2]->[2][1]
[2][1]->[1][0]
    
//规律:
x转y ,y转x

x转y时 size - x = y,由于下标开始值为0,所以size - 1 - x = y
y转x时 y = x

如上,y下标原封替换x坐标,但是x下标需要被size - 1 减后才能作为新数组的y下标。

3.杨辉三角

代码语言:javascript
复制
#include<iostream>
using namespace std;

void Print(int n, int a[][10]);

void YH(int n)
{
	int a[10][10];
	//计算杨辉三角, 以下三角矩阵的形式存放在二维数组
	for (int i = 0; i < n; i++) {
		a[i][0] = 1;
		a[i][i] = 1;
		for (int j = 1; j < i; j++)
			a[i][j] = a[i - 1][j - 1] + a[i - 1][j];	//i不可能取值为0导致地址越界 
	}
	Print(n,a);
}

void Print(int n,int a[][10])
{
	for (int i = 0; i < n; i++) {
		for (int j = 1; j <= n - 1 - i; j++)		//打印每行开始的空格 
			cout << " ";
		for (int j = 0; j <= i; j++)			//每行打印的数据个数
			cout << a[i][j] << " ";
		cout << endl;
	}
}

int main() {
	int n; cin >> n;
	YH(n);
	system("pause"); return 0;
}
代码语言:javascript
复制
// 杨辉三角
void Demo63() {
    //--变量声明--
    // 杨辉三角的高度
    int n;
    // 存储用数组,  注意杨辉三角只会占用一半的空间, 所以这里可以用malloc动态分配来避免空间浪费
    int arr[10][10];
    
    //--接收输入--
    scanf_s("%d", &n);
    arr[0][0] = 1;

    //--数据处理--
    // 左右两侧数据直接填充即可
    for (int i = 1; i < n; i++) {
        arr[i][0] = arr[i][i] = 1;
        for (int j = 1; j < i; j++) {
            arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
        }
    }
    //--输出--
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <= i; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}

✨4.包围圈

代码语言:javascript
复制
// 包围圈
void Demo64() {
    //--变量声明--
    int size, tree[10][10];
    // 当前坐标xy, 移动方向toward 0左 1下 2右 3上, 填充数
    // 注意 由于第一次探查前会先移动 x++  所以x需要修正为-1
    int x = -1, y = 0, toward = 0, num = 0;
    // 一个方向的移动步数
    int s;

    //--接收输入--
    scanf_s("%d", &size);
    s = size;

    //--数据处理--
    // 移动规律  如果是4  则是4+3+3+2+2+1+1 = 16  同理 如果是5  5+4+4+3+3+2+2+1+1
    // 外部循环: 每奇数次循环,  最大步数-1.  一个方向移动完后 对方向进行修改
    // 内部循环: 循环(步数)次, 每次移动根据方向对xy进行修改

    for (int i = 0; num<size*size; i++) {
        // 奇数次循环 最大步数-1
        if (i % 2 == 1) s--;
        for (int j = 0; j < s; j++) {
            // 获取方向并移动
            switch (toward) {
            case 0:
                x++;
                break;
            case 1:
                y++;
                break;
            case 2:
                x--;
                break;
            case 3:
                y--;
                break;
            }
            
            tree[y][x] = ++num;
        }

        //  改变方向  注意 当toward为3  也就是向上时, 需要取模操作 也就是变为0
        // (1+1) %4 = 2   (3+1) %4=0
        toward = (toward + 1) % 4;
    }


    //--输出--
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%d ", tree[i][j]);
        }
        printf("\n");
    }
}

7.字符/字符串

代码语言:javascript
复制
1. 大小写转换
设计一个程序, 输入一行字符串, 将其中大写转为小写, 小写转为大写. 其余字符不变
(字符串长度<100)
样例输入: hELLO wORLD!
样例输出: Hello World!
代码语言:javascript
复制
2. 转反串符字
累很天聊他和长学海云 ,话说着倒欢喜三张
身彼施还道之彼以算打长学海云是于

出输后列排序反串符字个这将 ,串符字串一入输 ,序程个一计设
(001>度长串符字)

!dlroW olleH :入输例样
Hello World!  :出输例样
代码语言:javascript
复制
3. 开挂很危险
最近网络盗号严重, 张三又喜欢开外挂(大家不要学)
于是张三打算出一个安全的密码, 避免开外挂后被盗号
请各位小伙伴帮忙, 判定一下张三的密码是否安全

安全密码的判定:
1. 长度在8~16之间
2. 开头必须是大写
3* 密码最少包含一个小写字母, 一个数字, 一个特殊符号
特殊符号包括~!@#$%*

设计一个程序 输入密码字符串
如果密码安全, 打印true, 否则打印false
(字符串长度<100)

样例输入: 
Aa123!!!!!
样例输出: 
true
代码语言:javascript
复制
4. 密码加密
自从上次张三密码变复杂后, 再也没有被盗过号
但他觉得密码还是不够复杂, 于是又进行了二次加密
然后..他忘记二次加密后的密码了
小伙伴赶紧帮他找找

张三的加密方式是这样的:
对于每个字母和数字, 按字母表/数字顺序往后挪5位
(如果超过了 则从头开始, 比如'z'转换后变成'e', '9'转换后变成'4')
符号不变

如密码: AaZz09!!!
加密后: FfEe54!!!

设计一个程序, 输入加密前的密码  打印加密后的密码
(密码长度 <= 16)

样例输入: AaZz09!!!
样例输出: FfEe54!!!

解答

1.大小写反转

代码语言:javascript
复制
#include<iostream>
#include<string>
using namespace std;

void SwapStr(string char1)
{
	int n = strlen(char1.c_str());
	for (int i = 0; i < n; i++)
	{
		if ((int)char1[i] > 65 && (int)char1[i] < 90) { cout << (char)(char1[i] + 32); }
		else if ((int)char1[i] > 97 && (int)char1[i] < 122){cout << (char)(char1[i] - 32); }
		else { cout << char1[i]; }
	}
}

int main()
{
	string n; getline(cin, n);;
	SwapStr(n);
	system("pause"); return 0;
}
代码语言:javascript
复制
// 大小写转换
void Demo71() {
    //--变量声明--
    // 存放字符串的数组
    char str[100];

    //--接收输入--
    gets_s(str, 100);

    //--数据处理--
    // 判断ascii码是否在大小写范围内  如果在  则手动转换
    for (int i = 0; str[i] != '\0'; i++) {
        if (str[i] >= 65 && str[i] <= 90) {
            str[i] += 32;
        }
        else if (str[i] >= 97 && str[i] <= 122) {
            str[i]-= 32;
        }
    }

    //--输出--
    printf("%s", str);
}

2.字符串反转

代码语言:javascript
复制
#include<iostream>
#include<string>
using namespace std;

void SwapStr(string char1)
{
	int n = strlen(char1.c_str());
	for (int i = 0; i < n; i++)
	{
		cout << char1[n - 1 - i] ;
	}
}

int main()
{
	string n; getline(cin, n);;
	SwapStr(n);
	system("pause"); return 0;
}
代码语言:javascript
复制
// 字符串反转
void Demo72() {
    //--变量声明--
    // 存放字符串的数组, 存放答案的数组
    char str[100], result[100];
    // 字符串的长度
    int len;
    //--接收输入--
    gets_s(str, 100);

    //--数据处理--
    // 获取长度  
    for (len = 0; str[len] != '\0'; len++);
    
    // 倒序填入result字符串
    for (int i = 0; i < len; i++) {
        result[i] = str[len - i - 1];
    }
    result[len] = '\0';

    //--输出--
    printf("%s", result);
}

3.密码安全检测

代码语言:javascript
复制
#include<iostream>
#include<string>
using namespace std;

bool MiMa(string char1)
{
	int n = strlen(char1.c_str());//字符串长度

	if (n < 8 || n > 16 || (int)char1[0] < 65 || (int)char1[0] > 90)return 0;

	for (int i = 1; i < n; i++)
	{
		int j = (int)char1[i];
		if ((j >= 48 && j <= 57) || (j <= 97 && j >= 65) || j == 126 || j == 33 || j == 64 || j == 35 || j == 36 || j == 37 || j == 42) return 1;
	}
}

int main()
{
	string n; cin >> n;
	MiMa(n) == 1 ? cout << "true" << endl : cout << "false" << endl;
	system("pause"); return 0;
}
代码语言:javascript
复制
// 安全密码
void Demo73() {
    //--变量声明--
    // 用户输入
    char password[100];
    // 用于验证是否合法, 0:长度, 1:开头大写, 2:包含小写, 3:包含数字, 4:包含特殊符号
    int flag[5] = { 0 };

    //--接收输入--
    gets_s(password,100);

    //--数据处理--
    //开头大写判断
    if (password[0] >= 65 && password[0] <= 90) flag[0] = 1;
    
    for (int i = 1; password[i] != '\0';i++) {
        //小写字母
        if (password[i] >= 97 && password[i] <= 122) flag[2] = 1;
        //数字
        else if (password[i] >= 48 && password[i] <= 57) flag[3] = 1;
        //特殊符号
        else if (password[i] == '~' ||
            password[i] == '!' ||
            password[i] == '@' ||
            password[i] == '#' ||
            password[i] == '$' ||
            password[i] == '%' ||
            password[i] == '*'
            ) flag[4] = 1;

        // 长度
        flag[1] = (i >= 8 && i <= 16);
    }

    //--输出--
    if (flag[0] && flag[1] && flag[2] && flag[3] && flag[4]) {
        printf("true");
    }
    else {
        printf("false");
    }
}

✨4.密码加密

代码语言:javascript
复制
#include<iostream>
#include<string>
using namespace std;

void SwapStr(string char1)
{
	int n = strlen(char1.c_str());
	for (int i = 0; i < n; i++)
	{
		if ((int)char1[i] >= 65 && (int)char1[i] <= 90)
		{ 
			(int)char1[i] > 85 ? cout << (char)((int)char1[i] - 21) : cout << (char)(char1[i] + 5);
		}
		else if ((int)char1[i] >= 97 && (int)char1[i] <= 122) 
		{
			(int)char1[i] > 117 ? cout << (char)(char1[i] - 21) : cout << (char)(char1[i] + 5);
		}
		else if ((int)char1[i] >= 48 && (int)char1[i] <= 57)
		{
			(int)char1[i] > 52 ? cout << (char)(char1[i] - 5) : cout << (char)(char1[i] + 5);
		}
		else { cout << char1[i]; }
	}
}

int main()
{
	string n; getline(cin, n);;
	SwapStr(n);
	system("pause"); return 0;
}
代码语言:javascript
复制
// 加密
void Demo74() {
    //--变量声明--
    char password[17];
    
    //--接收输入--
    gets_s(password, 16);

    //--数据处理--
    /*
        思路: 先减到0~25  然后+5取模
        如果超过25了(字母xyz), 则会因为取模成bcd

        比如z
        90 - 65=25
        25 + 5 = 30  %26 = 4
        4+65 = 69  = e;

        数字同理
    */
    for (int i = 0; password[i] != '\0'; i++) {
        //大写字母
        if (password[i] >= 65 && password[i] <= 90) {
            password[i] = (password[i] - 65 + 5) % 26 + 65;
        }
        //小写字母
        else if (password[i] >= 97 && password[i] <= 122) {
            password[i] = (password[i] - 97 + 5) % 26 + 97;
        }
        //数字
        else if (password[i] >= 48 && password[i] <= 57) {
            password[i] = (password[i] - 48 + 5) % 10 + 48;

        }
    }

    //--输出--
    printf("%s", password);
}

详细分析:

越界问题:如果超过25了(字母xyz), 则会因为取模成bcd

代码语言:javascript
复制
//防止越界处理思路: 	
先减到0~25(思路与上面题目数字环相同,直接使用数组长度取模的前提是数组的初始值是0),然后+5取模,余数就是超出的长度。

比如z
90 - 65=25
25 + 5 = 30  %26 = 4

4+65 = 69  = e;
代码语言:javascript
复制
//等同思路:
先+5,然后在取模时用(该数组长度26 + 该数组初始长度65)取模

比如z
90 + 5 = 95
95 % (26 + 65) = 4

4+65 = 69  = e;

8.函数

代码语言:javascript
复制
1. 根据以下要求, 实现一套登录功能

已知有全局变量
int ids[5] = {10001,10002,10003,10004};
char names[5][10] = {"张三", "李四", "王五", "赵六"};
char passwords[5][16] = {"aaaaa","bbbbb","ccccc","ddddd"};
int uNum = 4;

其中 每个下标对应一套用户数据(id, 名称, 密码)
如下标[1]: 对应10002, 李四, bbbbb

根据以下的函数声明和注释, 写出相应的函数实现
/*
    功能: 根据id 查询用户是否存在, 如果存在返回用户名,  如果不存在返回空
    参数: 
        uid: 用户id
    返回值: 
        如果用户存在, 返回用户名. 
        如果用户不存在, 返回NULL
*/
char* selectUserById(int uid);

/*
    功能: 根据id 查询用户密码, 如果存在返回用户密码,  如果不存在返回空
    参数: 
        uid: 用户id
    返回值: 
        如果密码存在, 返回密码. 
        如果密码不存在, 返回NULL
*/
char* selectPassById(int uid);
----------------------------------------------------
/*
    功能: 传入用户id和密码, 根据上面两个函数(selectUserById, selectPassById)来获取相应用户数据, 并判断是否登录成功
        传入用户id 查询用户名是否存在, 并获取用户密码
        如果用户存在  则判断密码是否正确
    参数:
        uid: 用户账户
        password: 用户密码
    返回值:
        如果账号不存在, 返回1
        如果密码错误, 返回2
        如果登录成功, 返回0
*/
int login(int uid, char* password);
-----------------------------------------------------
/*
    功能: 提示用户输入账号密码, 根据login函数判断是否登录成功, 
    如果登录成功提示正在进入首页
    如果登录失败
        密码错误: 提示密码错误, 并让用户重新登录
        账号不存在: 提示账号不存在, 并提示正在进入注册界面
    参数: 无
    返回值: 无
*/
void showLoginPage();

样例输入: 
10001 
aaaaa
样例输出: 
登录成功, 正在进入首页

样例输入: 
10001 
aaaab
样例输出: 
密码错误, 请重新登录

提示: 先输入数字再输入回车, 可能会出现回车符号被%s或者gets接收的情况, 导致密码无法被接收,  
可以用getchar接收回车来解决.
对应知识点: 键盘缓冲区

代码语言:javascript
复制
2. 上面有用虚线将函数划分为3种,  这三种函数有哪些区别(可以百度查询"三层架构").  根据这种思路 实现一套注册功能.

解答

✨1.登录功能

非常容易出错的点!:如何比较两个字符串是否相等?直接==?错误!

使用strcmp函数来比较!

代码语言:javascript
复制
#include<iostream>

using namespace std;

int ids[5] = { 10001,10002,10003,10004 };
char names[5][10] = { "张三", "李四", "王五", "赵六" };
char passwords[5][16] = { "aaaaa","bbbbb","ccccc","ddddd" };
int uNum = 4;

char* selectUserById(int uid)
{
	for (int i = 0; i < uNum; i++)
	{
		if (ids[i] == uid)  return names[i];
	}return NULL;
}

char* selectPassById(int uid)
{

	for (int i = 0; i < uNum; i++)
	{
		if (ids[i] == uid)  return passwords[i]; 
	}return NULL;
}

int login(int uid, char* password)
{
	if (selectUserById(uid) != NULL)
	{
		if (strcmp(password, selectPassById(uid)) == 0)return 0;
		return 2;
	}
	return 1;
}

void showLoginPage()
{
	cout << "请输入账号和密码:" << endl;
	int u; cin >> u;
	char p[16] = { 0 }; cin >> p;
	switch (login(u, p))
	{
	case 1:cout << "账号不存在,进入注册界面"; break;
	case 0:cout << "登录成功"; break;
	case 2:cout << "密码错误, 并让用户重新登录"; break;
	}
}

int main()
{
	showLoginPage();
	system("pause"); return 0;
}
代码语言:javascript
复制
/*
    功能: 根据id 查询用户是否存在, 如果存在返回用户名,  如果不存在返回空
    参数:
        uid: 用户id
    返回值:
        如果用户存在, 返回用户名.
        如果用户不存在, 返回NULL
*/
char* selectUserById(int uid) {
    for (int i = 0; i < uNum; i++) {
        if (ids[i] == uid) {
            return names[i];
        }
    }
    return NULL;
}

/*
    功能: 根据id 查询用户密码, 如果存在返回用户密码,  如果不存在返回空
    参数:
        uid: 用户id
    返回值:
        如果密码存在, 返回密码.
        如果密码不存在, 返回NULL
*/
char* selectPassById(int uid) {
    for (int i = 0; i < uNum; i++) {
        if (ids[i] == uid) {
            return passwords[i];
        }
    }
    return NULL;
}


/*
    功能: 传入用户id和密码, 根据上面两个函数(selectUserById, selectPassById)来获取相应用户数据, 并判断是否登录成功
        传入用户id 查询用户名是否存在, 并获取用户密码
        如果用户存在  则判断密码是否正确
    参数:
        uid: 用户账户
        password: 用户密码
    返回值:
        如果账号不存在, 返回1
        如果密码错误, 返回2
        如果登录成功, 返回0
*/
int login(int uid, char* password) {
    if (selectUserById(uid) == NULL) {
        return 1;
    }
    char* pass = selectPassById(uid);
    if (strcmp(password, pass) != 0) {
        return 2;
    }
    return 0;

}

/*
    功能: 提示用户输入账号密码, 根据login函数判断是否登录成功,
    如果登录成功提示正在进入加载界面
    如果登录失败
        密码错误: 提示密码错误, 并让用户重新登录
        账号不存在: 提示账号不存在, 并提示正在进入注册界面
    参数: 无
    返回值: 无
*/
void showLoginPage() {
    //--变量声明--
    //用户id
    int uid;
    //用户密码
    char password[17];
    //结果选项  
    /*  如果账号不存在, 返回1
        如果密码错误, 返回2
        如果登录成功, 返回0
        */
    int result;

    //--接收输入--
    scanf_s("%d", &uid);
    //处理掉输入的回车符号
    getchar();
    gets_s(password, 16);

    //--数据处理--
    result = login(uid, password);

    //--输出--
    switch (result) {
    case 1:
        printf("账号不存在, 正在进入注册界面");
        break;
    case 2:
        printf("密码错误, 请重新登录");
        break;
    case 0:
        printf("登录成功, 正在进入首页");
        break;
    }
    
}

2.三角架构实现注册功能

代码语言:javascript
复制
#include<iostream>
using namespace std;

int ids[5] = { 10001,10002,10003,10004 };
char names[5][10] = { "张三", "李四", "王五", "赵六" };
string passwords[5] = { "aaaaa","bbbbb","ccccc","ddddd" };
int uNum = 4;

int BLL_U(int& u);
void DAL(int& u, string p);
//(UI)UI界面
void UI()
{
	cout << "注册>>" << endl << "请输入账号:" << endl;
	int u; cin >> u; string p; cin >> p;

	if (BLL_U(u) > 0) cout << "用户名已存在!" << endl;
	else
	{
		DAL(u, p);
		cout<<"用户注册成功!" << endl;
	}
}

//(BLL)检测用户名是否存在
int BLL_U(int &u)
{
	int flag = 0;
	for (int i = 0; i < uNum; i++)
	{
		if (ids[i] == u)flag ++;
	}
	return flag;
}

//(DAL)修改数据
void DAL(int& u, string p)
{
	ids[uNum] = u;
	passwords[uNum] = p;
}

int main()
{
	UI();
	system("pause"); return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 运算符
    • 解答
      • 输出个,十,百位
      • 2.圆与正方形面积差
  • 2. 判断
    • 解答
      • 1.求最大值
      • 2.打分系统
      • 3.交通工具选择问题
  • 3. 简单循环
    • 解答
      • 1.求平均年龄
      • ✨2.数列求和
      • 3.斐波那契数列
      • ✨4.抛物问题
  • 4.嵌套循环
    • 解答
      • 1.打印九九乘法表
      • ✨2.求素数
      • ✨3.猜数字
      • ✨4.打印菱形
  • 5.一维数组
    • 解答
      • ✨1.数组去重
      • ✨2.数字环
      • ✨3.约瑟夫环
  • 6.多维数组
    • 解答
      • 1.矩阵转置
      • ✨2.矩阵90°转置
      • 3.杨辉三角
      • ✨4.包围圈
  • 7.字符/字符串
    • 解答
      • 1.大小写反转
      • 2.字符串反转
      • 3.密码安全检测
      • ✨4.密码加密
  • 8.函数
    • 解答
      • ✨1.登录功能
      • 2.三角架构实现注册功能
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档