查看: 104|回复: 0

零基础学习C++系列课程(四) 持续更新中

[复制链接]

5

主题

10

帖子

20

积分

新手上路

Rank: 1

积分
20
发表于 2022-12-1 17:01:56 | 显示全部楼层 |阅读模式
项目三 黑客攻击系统-用户输入的优化

为看书困难的小伙伴推荐视频教程:百度网盘 提取码:r59a
第 1 节 项目需求


  • 用户登录时,用户可能输入很长的用户名。
  • 使用 char 类型和 int 类型,表示用户名和密码,不安全。
第 2 节 项目实现

#include <iostream>
#include <Windows.h>
#include <string>

using namespace std;

int main(void) {
     //char name;
     string name;

     //int pwd;
     string pwd;

     std::cout << "请输入账号:";
     std::cin >> name;

     std::cout << "请输入密码:";
     std::cin >> pwd;

     system("pause");
     return 0;
}
第 3 节 项目精讲-字符串的概念

什么是字符串
字符串就是 0 个或多个“字符”组成的“有序”序列。


IT 史上的“神翻译”-字符串
1)由“字符”组成
2)按照特定的顺序组成


字符串长度
字符串包含的字符个数(不是指中文)。
空字符串的长度是 0
""是空字符串常量,没有一个字符,长度是 0
""是空格字符串常量,包含 1 个空格,长度是 1
"god" 的字符串长度是 3
"我爱你" 的字符串长度不是 3 ,是 6 或 9
(在某些编码中,一个汉字占用 2 个直接,有些编码中占 3 个字节)
""的字符串长度是 0(空串)
""的字符串长度是 1(含有一个空格)
字符串常量
"字面型"字符串常量,要求用""扩起来。
printf("name=%s", "Rock"); //C 语言方式输出字符串,%s 用来匹配字符串
cout << "Rock"; //C++方式输出字符串
字符串结束符
在 c 语言中,为了便于存储字符串,要求在最后一个字符的后面存储一个 0(一个字节)。
这个 0, 称为"字符串结束符",常用 '\0' 表示。
"China"  =>'C' 'h' 'i''n''a''\0'
""           =>'\0'


在 C++语言中,字符串的最后并没有字符串结束符!
实际存储时,根据编译器的不同,最后可能存储一个字符串结束符,也可能没有。
字符串变量的表示
在 C 语言中,使用 char 类型的数组,来存储字符串变量
注:C 语言中,没有专用的字符串类型。
在 C++中,使用 std::string 类型来表示字符串变量。
第 4 节 项目精讲-C++风格的字符串 string

4.1 string 变量的定义、初始化

    //定义了一个字符串变量,此时,该字符串是空字符串。
    string girlFriend1;
    girlFriend1 = "王菲"; //把字符串常量"王菲"拷贝到 girlFriend1
    cout << "girlFriend1 = " << girlFriend1 << endl;

    string girlFriend2;
    girlFriend2 = girlFriend1; //把字符串变量 girlFriend1 的值拷贝到 girlFriend2
    cout << "girlFriend2 = " << girlFriend2 << endl;

    //定义 girlFriend3 的同时,使用字符串常量"周迅"来初始化
    string girlFriend3("周迅");
    cout << "girlFriend3 = " << girlFriend3 << endl;

    //定义 girlFriend4 的同时,使用字符串变量来初始化
    string girlFriend4(girlFriend3);
    cout << "girlFriend4 = " << girlFriend4 << endl;

    string girlFriend5(10, 'A');
    cout << "girlFriend5 = " << girlFriend5 << endl;
4.2 string 变量的输入、输出

使用 std::cin >> 输入
从第一个非空白字开始,直到遇到空白字符时停止输入
空白字符是指:空格,制表符,回车符
使用 std::cout << 输出
demo1-基本的输入输出
    string job;
    cout << "你是做什么工作的?" << endl;
    cin >> job;
    cout << "做" << job << ",收入一定不错吧?" << endl;
demo2-自动跳过空白字符
    string university; //大学
    string profession; //专业

    cout << "你是哪个学习毕业的?学什么专业? ";
    // 输入:清华 考古 hello
    // 自动跳过空白字符
    cin >> university >> profession;

    cout << university << "的" << profession << "专业不错哦!" << endl;
demo3 -连续输入多个字符串,个数不确定
#include <iostream>
#include <Windows.h>
#include <string>

using namespace std;

int main(void) {
     string food; //专业
     int i = 0;

     cout << "你喜欢什么美食? ";
     while (cin >> food) { //当用户输入 Ctrl + z 并回车 cin >> food 返回 0, 0 就是假
         i = i + 1;
         cout << "你喜欢的第" << i << "美食是:" << food << endl ;
         cout << "你还喜欢吃什么美食? ";
     }

    cout << "你最喜欢的美食有" << i << "种" << endl;

    system("pause");
    return 0;
}
demo4 - 读取一行 getline
#include <iostream>
#include <Windows.h>
#include <string>

using namespace std;

int main(void) {
     string addr; //专业

     cout << "你想到哪里去旅行:";
     //从标准输入设备读取一行,但是不包括最后输入的回车符
     getline(cin, addr);

     //empty 方法
     if (addr.empty() == true) {
          cout << "您输入了一个空行" << endl;
          return 1;
     }

     //size()和 length()完全等效
     //长度是指字符串占用的字节数,如果含有汉字,那么总的字节数和汉字个数不同
     cout << "地址的长度是:" << addr.size() << endl;
     cout << "地址的长度是:" << addr.length() << endl;

     system("pause");
     return 0;
}
4.3 string 字符串的比较

比较规则:和 C 语言相同。
从字符串的第一个字符开始,对应字符逐个比较,直到遇到不相等的字符为止。
比较运算符有:>、>=、<、<=、==
比较运算的结果:逻辑真, 逻辑假
"123" < "1230"          真
"19 "> "123456789"  真
"2" > "1999"              真
"123" == "123"         真
"123" == "1230"       假
#include <iostream>
#include <Windows.h>
#include <string>

using namespace std;

int main(void) {
     string myGirl = "小芳";
     string yourGirl;

     cout << "我喜欢的女孩子是" << myGirl << endl;
     cout << "你喜欢的女孩是:";
     cin >> yourGirl;

     if (myGirl == yourGirl) {
          cout << "我们喜欢同一人,过来决斗吧" << endl;
     } else {
          cout << "祝你幸福";
     }

     system("pause");
     return 0;
}
注意:c 语言的字符串,不能使用这个方式来进行字符串比较。
4.4 string 字符串的加法

把+左侧的字符串,和+右侧的字符串,直接拼接成一个新的字符串
注意顺序。(C 语言的字符串不支持该方式)
注意与数学中的“加法”不同:
数学中:"100" + "200" 等于 "300"
系统中:"100" + "200" 等于 "100200"
demo
#include <iostream>
#include <Windows.h>
#include <string>

using namespace std;

int main(void) {
     string s1 = "武当派";
     string s2 = "张三丰";
     string s3 = "太极拳";
     string s4;

     s4 = s1 + s2; //武当派张三丰
     cout << "s4=" << s4 << endl;

     s4 = s4 + s3; //武当派张三丰太极拳
     //相当于 s4 += s3;
     cout << "s4=" << s4 << endl;

     s4 += "第一式";
     //等效于:s4 = s4 + "第一式";
     cout << "s4=" << s4 << endl;

     system("pause");
     return 0;
}
第 5 节 项目精讲-C 语言风格的字符串 char 数组

在 c 语言中,字符串是以“字符数组”存储的。
#include <iostream>
#include <Windows.h>
#include <stdio.h>

using namespace std;

int main(void) {
     //C 语言风格的字符串
     char name[32];
     
     /*
     使用 C 语言的函数,来处理 C 语言字符串
     printf("请输入您的名字:");
     scanf("%s", name);
     printf("%s, 你好!\n", name);
     */

     // 使用 C++的方式,来处理 C 语言字符串
     cout << "请输入您的名字:";
     cin >> name;
     cout << name << ",你好!" << endl;

     system("pause");
     return 0;
}
第 6 节 项目精讲-数组的概念和定义

什么是数组
数组,就是多个元素的有序“组合”。
生活中的“数组”:


1)由多个大小相同的小柜子组成
2)这些小柜子,有自己对应的编号。
3)而且这些编号是递增顺序。
C 和 C++语言中的数组:
1)由多个大小相同的小柜子组成 => 相同大小的内存块组成,即相同类型的数据
2)这些小柜子,有自己对应的编号 => 编号从 0 开始递增
3)而且这些编号是递增顺序。
数组的“容量”是不能改变的。
数组的定义
数组和其他变量一样,需要先定义,再使用。
实例:
int a[8];
//定义了一个数组,
//数组名是“a”,
//包含 8 个元素,
//每个元素是 int 类型的变量

a[0] = 20;
a[1] = 5;


说明:
定义了如下数组:
int a[8];
就相当于定义了 8 个 int 类型的变量
而且这 8 个变量是连续存储在内存中的。(8 个依次相连的邻居)

实例:
某渣男,想要记录他 10 个女友的身高,可以定义如下:
float girlFirends[8];
girlFirends[5] = 1.78;

int ages[50];
ages[0] = 18;
ages[49] = 19;
第 7 节 项目精讲-数组的初始化

数组的初始化
在定义数组的同时,设置数组内的元素值。
int a[8] = {20, 5, 30, 13, 18};
printf("%d,%d,%d,%d,%d\n", a[0],a[1],a[2],a[3],a[4]);
或者
cout << a[0] << "," << a[1] << "," << a[2] << "," << a[3] << "," << a[4];

int a[8] = {0}; //把数组的所有元素都初始化为 0
printf("%d,%d,%d,%d,%d\n", a[0],a[1],a[2],a[3],a[4]);

int a[8] = {1}; //把 a[0]初始化为 1,其它值都初始化为 0
int b[8] = {1, 5}; //把 a[0]初始化为 1,a[1]初始化为 5,其它值都初始化为 0

int a[] = {1,2,5}; //定义数组 a, 这个数组包含 3 个元素!
                         // 根据“初始化列表”,自动计算数组的容量

高逼格用法(在某些特殊场合使用)
优点:但数组的成员较多时,该方式可读性高
缺点:仅仅 C 编译器支持,C++编译器中不支持,即 C++程序中不能使用。


常见错误
int a[2] = {1,2,5}; //错误!初始值太多,大于数组的容量
int a[3];
a = {1, 2, 3}; //不能对数组名直接赋值!
int a[3];
a[3] = 10; //下标越界!下标的取值范围是 0, 1, 2
第 8 节 项目精讲-数组元素的访问

数组的内元素的访问
通过下标访问对应的元素。
特别注意, 数组的第一个元素的下标是 0, 而不是 1
int girlSize[10];
a[5] = 38;
printf("%d\n", a[5]);
cout << a[5];
另类用法:
使用下标的方式访问 string 字符串
    string name = "Rock";

    //name是 string 字符串中的第 i 个字符(char 类型)
    for (int i=0; i< name.length(); i++) {
          cout << name;
    }

    name[0] = 'L'; //name 变成:Lock
    cout << endl << name;
数组的越界
数组的越界, 是指下标超出正常的范围!
例如:int a[10]; //a[-1] 和 a[10]都是越界!
越界的后果
越界非常危险,可能导致数据破坏,或其他不可预期的后果!
越界的控制
需要程序员自己手动控制,编译器不做任何检查!因为,C/C++语言完全信任程序员!
第 9 节 项目精讲-C 风格的字符串详解

9.1C 语言字符串的存储、初始化

字符串,是通过“字符数组”(元素类型为 char 的数组)来存储的!
demo1
   char name[10];
   name[0] = 'R';
   name[1] = 'o';
   name[2] = 'c';
   name[3] = 'k';
   name[4] = 0; //字符串结束符 0,就是 '\0'

   printf("姓名:%s", name); //姓名:Rock

   name[2] = 0;
   printf("姓名:%s", name); //姓名:Ro
demo2
    char name[10] = "Rock"; //相当于 char name[10] = {'R', 'o', 'c', 'k', '\0'};
    printf("姓名:%s", name);
demo3
    char name[] = "Rock"; //相当于:name[5] = "Rock"
    printf("%d", sizeof(name)); //5
9.2C 语言字符串的输入输出

#include <stdio.h>
#include <Windows.h>

int main(void) {
     char name[16];
     char addr[64];

     printf("姑娘芳名?\n");
     scanf("%s", name);

     //此时输入缓冲区中还有一个回车符
     //清空输入缓冲区
     fflush(stdin);

     printf("姑娘家住何地?\n");
     gets(addr); //读一行,包括一行中的空格

     printf("家住%s 的%s, 我中意你!\n", addr, name);

     system("pause");
     return 0;
}
第 10 节 英语不是障碍:计算机英语加油站

string字符串
length长度
scanfC 语言的标准输入函数
parameter参数
return value返回值
str on success,NULL on failure如果成功,就是 str
如果失败,就是 NULL

主动学习英文文档
结合有道翻译
中文文档
第 11 节 编程思维修炼


  • 代码对战
    <略>
    300 多关,等你来征服...
  • 积木编程
效果
步骤:
1)创建背景
添加背景:
贪食蛇-背景.jpg(480x360)[4:3 比例]
2)画蛇头


再缩小:




注意,蛇头需要向右,因为角色的初始角度就是 90 度(向右)
注意:设置蛇头的中心位置!
并把角色名称设置为“蛇头”


3)添加分值变量 score


4)蛇头初始化代码


5)添加苹果角色
添加苹果角色(选择即可,也可自己绘制)
调整苹果角色的大小比例为 40%

6)添加苹果的脚本
初始化脚本,以及判断是否碰到蛇头。


7)创建蛇身
正方形,两个造型


大小设置为 8%
并命名为“蛇身”
初始化代码:


8)让蛇身跟随蛇头


分析:
只要控制克隆体的生存时间(等待时间),就可以控制蛇身的长度
注意:
切换到造型 2 之前,要等待一点时间,使得蛇头和蛇身之间有,用造型连接。
9)让蛇身跟随蛇头(改进)


10)碰撞检测


11)优化
游戏结束时更换背景
(1)绘制 GameOver 背景
(2)更换背景
(3)吃苹果声音
        上传 eat.mp3
(4)苹果延时后再出现


第 12 节 项目精讲-常见错误总结

错误 1
cin.sync()在 VS 中失效!
C++的标准中, cin.sync()是清空缓冲区,但是实际的实现取决于编译器.
如果使用 vc++或者 g++编译器,是可以的, 但是使用 vs 中的编译器,就不可以.
使用自定义的 clearBuff();
#include <iostream>
#include <Windows.h>
#include <stdio.h>

using namespace std;

void clearBuff() {
      char tmp;
      while ((tmp = getchar()) != '\n');
}

int main(void) {
     int age = 0;
     int height = 0;//身高, 单位:cm

     cout << "请输入年龄: " << endl;
     cin >> age;

     if (cin.fail()) {
          cout << "输入失败,应该输入一个整数" << endl;
          cin.clear();

          //cin.sync();
          clearBuff();
     }

    cout << "请输入身高: " << endl;
    cin >> height;

    cout << "年龄: " << age << endl;
    cout << "身高:" << height << endl;

    system("pause");
    return 0;
}
错误 2
int a[3];
a = {1, 2, 3}; //错误
a[3] = 100;
错误 3
string s;
s = 3.14 * 100 * 100;
int name[32];
scanf("%s", name);
第 13 节 职场修炼:技术和领导关系哪个更重要


  • 在 IT 研发职场中,不要过分依赖领导关系。
  • 要与领导保持积极主动的沟通关系,闷头苦干会丢失很多机会。
  • 技术上,要尽快掌握公司的核心开发业务。
补充:一切关系,都是以个人的价值为基础的。
第 14 节 逼格提升:解决 Bug 的第 1 手段-断点调试

问题代码:
#include <iostream>
#include <Windows.h>
#include <string.h>

using namespace std;

int main(void)
{
     float r;
     float s;

     cout << "请输入圆的半径:";
     scanf("%f", r);

     s = 3.14 * r * r;
     cout << "面积是:" << s << endl;

     system("pause");
     return 0;
}
第 15 节 项目练习

15.1练习 1

连续读入多个单词,然后统计这些单词的总的长度、以及单词个数。
直到输入结束:
(按下 Ctrl +z, 就会输入一个特殊的字符:文件结束符 EOF)
分别使用 C 和 C++实现。
C++ 版本
#include <iostream>
#include <string>
#include <Windows.h>

using namespace std;

int main(void) {
     string word;
     int count = 0;
     int length = 0;

     cout << "请输入任意多个单词:";
     while (1) {
           // 输入成功时,返回 cin 对象本身
           // 遇到文件结束符(ctrl+z),而导致输入失败是,返回 0
           if ((cin >> word) == 0) {
                  break;
           }
           count++;
           length += word.length();
     }

     cout << "一共有" << count << "单词" << endl;
     cout << "总长度:" << length << endl;

     system("pause");
     return 0;
}
C 语言版本
#include <stdio.h>
#include <string.h>
#include <Windows.h>

int main(void) {
     char word[64];
     int count = 0;
     int length = 0;

     printf("请输入任意多个单词:");
     while (1) {
           // 输入失败 返回 0
           // 遇到文件结束符 (ctrl+z),返回-1(EOF)
           if (scanf("%s", word) == -1) {
                 break;
           }
           count++;
           length += strlen(word);
    }

    printf("一共有%d 个单词\n", count);
    printf("总长度:%d\n", length);

    system("pause");
    return 0;
}
15.2练习 2

连续输入多行字符串(文本),统计中的行数,以及字符个数。
分别使用 C 和 C++实现。
C 语言版本
#include <stdio.h>
#include <string.h>
#include <Windows.h>

int main(void) {
     char line[2048];
     int lineCount = 0;
     int length = 0;

     printf("请输入任意多行:");
     while (1) {
        if ( gets(line) == 0) {
        break;
        }
        lineCount++;
        length += strlen(line);
     }

     printf("一共有%d 行\n", lineCount);
     printf("总长度:%d\n", length);

     system("pause");
     return 0;
}
C++版本
#include <iostream>
#include <string>
#include <Windows.h>

using namespace std;

int main(void) {
     string line;
     int lineCount = 0;
     int length = 0;

     cout << "请输入任意多行:";
     while (1) {
        // 遇到文件结束符时, 返回 NULL(0)
        if (getline(cin, line) == 0) {
             break;
        }
        lineCount++;
        length += line.length();
    }

    cout << "一共有" << lineCount << "行" << endl;
    cout << "总长度: " << length << endl;

    system("pause");
    return 0;
}
为看书困难的小伙伴推荐视频教程:百度网盘 提取码:r59a
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表