C++ 基础

c/c++

浏览数:163

2019-9-13

AD:资源代下载服务

前言

这是为了一个好朋友写的,大家也可以看看,欢迎批评指出。

学习内容我简单描述,然后本文主要讲述课后练习以及重点,因为不会很早写完,一直会更新,所以。。。慢慢看吧。

若要观看详细的请访问渣爷的博客:C++基础

然后我们从for循环开始。

正文

for循环

格式

for(循环变量 = 初始值; 循环条件; 循环变量变化)
{
    代码1
    代码2
    ...
    代码n
}

举例说明

这个不用太在意,举个例子,若题目要你求100个数的和,那么怎么搞呢,如果像以前

cin>>a
sum += a;
cin>>a;
sum += a;
......
cout<<a;

显然你是不能这么写的

然而用for语句以后

for(int i = 1/*定义循环变量、初始化(我个人认为在循环里面定义更合适)*/; i <= n/*条件(当i小于等于n)*/; i++/*i = i + 1*/)
{
    cin>>a;
    sum += a;
}
cout<<sum;

循环的意义就是可以重复做同一个操作,Do you know?

先看几遍,看到会为止

然后应该有人会问 i 有啥用,这里面完全没有用到 i 啊?

有时候没用,但大部分会有用的,比如,让你求1到100的和(用for语句)

显然你可以这么写

for(int i = 1; i <= 100; i++)
    sum += i;
//由于只有一条语句可以不用花括号(“{}”)
cout<<sum;

然后就没有什么知识点了吧?进入下一个环节->

练习题库

1、洛谷P1035

2、洛谷P1423

3、洛谷P1424

4、洛谷P1980

注意!请独立思考

while与do while循环

格式

while
while(条件语句为真)
{
    代码1
    代码2
    ...
    代码n
}
do while
do
{
    代码1
    代码2
    ...
    代码n
}while(条件语句为真);
 

举例说明

其实我个人认为while也没什么用,主要是有些时候比for简洁,举个例子,若你要输入很多组数据,那么while语句就可以写成

while(cin>>a)
{
    ...
}
或者
while(scanf("%d", &a) != EOF)
{
    ...
}
补充

意思是当“文件没有读入结束时”

如果我们还在读入,”cin>>a“返回的值是1(true)

读入结束,已经读不到东西的时候,它会返回0(false)

在c++里面,1和0可以看为真或假,判断语句也可以这么写

if(b)//当b为真
    ...
if(!b)//当b为假
    ...

暂时我还不知道for怎么写

还不理解的话,可以暂时认为for是用来做一定次数内的操作,而while可以用来做暂时不知道次数(或知道条件)的操作

虽然for语句也可以写成

for(;scanf("%d", &a) != EOF;)
{
    ...
}

但看起来while更好用一点,自己看得懂就好。。。但如果别人也看得懂就更好了

练习题库

暂无

循环测试

洛谷P1611

数组

格式

//定义
int a[N];
//其中“int”是数组类型,a是数组名,N常量,代表了数组的大小(有多少个变量)
//注意:c++数组是从0开始的一般我们不用下标为0的空间,那么定义int a[2]只有a[0]和a[1]两个元素
/*赋值和其他变量一样,写作*/
a[i] = r
/*r,任意值*/
/*i,下标,代表了是数组中的哪一个元素*/

举例说明

如果,让你读入n个数,n<=1000000,然后要求倒序输出,显然,我们必须把它给我们的每一个数字存起来,如果你不嫌麻烦,你可以

int a1,a2,a3,a4,a5,a6,...,a1000000;

但这样恐怕不行,这时候就可以用数组了,为此,我贴上上面题目的代码

#include <iostream>
using namespace std;
int a[1000000 + 10];
int main(int argc, char const *argv[])
{
    int n;
    cin>>n;
    for(int i = 1; i <= n; i++)
        cin>>a[i];//输入a数组的第i个元素(一般情况下不算a[0])
        /*之前提到过i有什么用,现在就有用啦*/
    for(int i = n; i >= 1; i--)
        cout<<a[i];//显而易见,倒着来输出
    return 0;
}

练习题库

洛谷P1046

洛谷P1047

洛谷P1028

二维数组

与一维数组一样,如果说一维是一条线,二维就是一个平面,但是真正用起来可要抽象得多,本文在此不再赘述。

格式

//定义二维
int a[N][N];
//其中“int”是数组类型,a是数组名,N常量,代表了数组的大小(有多少个变量),二维是N*N的矩阵
/*赋值和其他变量一样,写作*/
a[i][j] = r
/*r,任意值*/
/*i,下标1,j,下标2.代表了是数组中的哪一个元素*/

举例说明

若题目要求你输入一个大小为N*M的矩阵,然后打印矩阵,则代码如下

#include<iostream>
using namespace std;
int main()
{
    int a[100][100];
    int n,m;
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin>>a[i][j];
            
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
            cout<<a[i][j];
        cout<<endl;
    }   
}

练习题库

洛谷P1055

函数

函数是C++语法的最后一个章节,也是最难的一个章节,请认真阅读。

格式

函数类型 函数名(参数类型 参数 1;参数类型 参数 2)
{
    代码
}

举例说明

1、输入a,b;求a,b的最大值

//之前的写法
cin>>a>>b;
if(a > b)
    cout<<a
else
    cout<<b;

现在我们可以写一个专门的函数来实现这个功能

#include<iostream>
using namespace std;
int MAXN(int x,int y)//这里的x,y = 主函数的a,b
{
    if(x > y)
        return x;//返回x,而不是输出,让主函数的c = x
    else
        return y;//返回y
    /*这里返回的值必须是int类型的数,返回到的地方就是调用它的地方*/
}
int main()
{
    //这是主函数的内容
    cin>>a>>b;
    int c = MAXN(a,b);//调用函数MAXN(最大值函数),传参数a,b。c = 这个函数的返回值
    //c++标准库函数和自己写的函数和数学里的函数(三角函数)一样,会有返回值或没有返回值
    cout<<c;
}

其实这里的代码相当于上面的代码,只是形式不同

那这样还比上面要多几行呢,这个东西有啥用?

其实当我们多次要使用到一段代码的时候,就可以使用函数

有几个知识点:

1、子函数(除了main函数之外的函数)必须写在主函数上,或者提前定义(推荐第一种)

2、函数可以不传参

3、void类型的函数指的是空函数,意思为没有返回值

有时候我们还可以用函数做复杂的调用,比如自己调用自己,叫做递归

递归

斐波那契数列(为了简便,我们后面管他叫“肥婆数列”),大家肯定不陌生吧,让你求肥婆数列的第N项,要求使用递归算法,怎么做?

#include<iostream>
using namespace std;
int f(int t)//代表肥婆数列的第t项
{
    //我们知道,第t项 = 第t-1项 + 第t-2项
    //那么可以这么写:
    if(t == 1 || t == 2)
        return 1;//如果是第1和第2项返回1(他们的答案为1)
    return f(t - 1) + f(t - 2);
    //返回值为这一项的答案,然后t-1项又会调用t-2项和t-3项……
}
int main()
{
    cin>>n;
    cout<<f(n);//输出结果
}

 

递归的调用如图所示。但是作为一种优秀算法的同时,他的时间复杂度也很高,因为顾名思义,递归就是递过再回来时间复杂度大概为(因为我没学过,所以不清楚)O(n^2)。

所以有了递推

不过他没什么用,我现在都已经忘了它是干嘛的了,所以本文不再赘述,若要了解请翻书。

搜索与回溯

搜索与回溯算法其实就是在递归上加了东西,搜索分为深度优先搜索宽度优先搜索(或广度优先搜索),简称深搜和宽搜,英文简称为DFS(深搜)和BFS(宽搜)

我记得,搜索可以解决一部分的问题,最典型的是迷宫问题,其他的东西我忘得差不多了,但是迷宫问题却还记得

基本是这样的:给你一个N * M的地图,和其中的障碍物的位置,要求从x0,y0到x1,y1的最短距离

深搜,回溯的做法就是枚举每一条路径,然后求出最短距离,但他是有规律的找

/*我们设置地图中0可以走,1不能走*/
#include<cstdio>
#include<algorithm>
using namespace std;
const int dx[4] = {1, -1, 0, 0}//两个数组枚举位置变化的可能性,枚举x轴
const int dy[4] = {0, 0, 1, -1}//枚举y轴
int mp[100][100];
int vis[100][100];
int k = 0x3f3f3f3f;//因为要最小值,所以初始值要赋最大值
void s(int x,int y)
{
    if(x == x1 && y == y1)//如果已到达
    {
        k = min(k,ans);//c++标准库函数,求最小值
        return;//若想结束,那么可以直接返回,但仅限于void没有返回值
    }
    for(int i = 0; i < 4; i++)
    {
        int nx = x + dx[i];
        int ny = y + dx[i];
        //这里两个变量指的是下一个遍历到的地方
        if(nx > n || ny > m || nx < 1 || ny < 1 /*判断是否越界*/|| vis[nx][ny] == 1 || mp[nx][ny] == 1)
            /*vis数组判断是否走过*//*判断是否有障碍*/
            continue;//非法访问,跳过
        vis[nx][ny] = 1;//记录已访问
        ans ++;//答案加一
        s(nx,ny);//递归下一层
        ans --;//回溯
        vis[nx][ny] = 0;//设置未访问,这样才能保证从其他地方还可以访问这一点
    }
}
int main()
{
    int x0,y0,x1,y1;
    cin>>n>>m>>x0>>y0>>x1>>y1;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin>>mp[i][j];
    s(x0,y0);//从当前点出发
    cout<<k;//输出答案
}

这一部分代码可以慢慢阅读,或找几本书再来理解,因为时间原因,所以只能靠读者自己理解了

任务为AK洛谷新手村!

后记

不知不觉更新就完毕了,突然发现作为一个新手来看还是很难看懂的,也不如XC的课件那么详细,但同时我也自己复习了一遍所学的知识,我会继续努力的!

作者:#BIG_K