C++语言基础(゚Д゚

本文介绍了C++的基础知识,包括函数的使用(如标准函数、无返回值函数、无参数函数、传值参数函数、引用参数函数、数组参数函数、字符串参数函数、函数嵌套、函数重载和函数模板),递归的概念和应用,以及数组(静态和动态)和字符串的操作。通过实例展示了如何进行这些操作,并提供了代码示例。
部署运行你感兴趣的模型镜像

👂 无论你多怪异我还是会喜欢你(《刺客伍六七》动画推广版片尾曲) - 周子琰 - 单曲 - 网易云音乐

一起补基础!                                       φ(゜▽゜*)♪         

👂 My Nam's Suzie - Susie/Farfashah - 单曲 - 网易云音乐

算法训练营的东西,会放到《算法训练营》专栏里

花了我68块买的书,第一章耗时5小时,12032字

全书都会写成博客,结合书里的题单和洛谷官方题单,大量刷题

需要的小伙伴可以跟着练,就是周期有点长,预计持续到大一下暑假结束

目录

🌳基础语法

🌼cout与指针

🌼(浮点)精度,域宽,填充

🌼输出格式

🌳轻松写函数

🌼1,标准函数

🌼2,无返回值函数

🌼3,无参数函数

🌼4,传值参数函数

🌼5,引用参数函数

🌼6,数组参数函数

🌼7,字符串参数函数

🌼8,函数嵌套

🌼9,函数重载

🌼10,函数模板

🌳递归

🌳结构体 -- 信息携带者

🌳数组

🌼先说静态数组

🌼再说动态数组

🌼2,二维数组

🌳字符串

🌼1,C-风格字符串

🌼2,C++ string类字符串


🌳基础语法

🌼cout与指针

利用cout对象输出指针,引用类型的数据。当输出数据为指针或引用类型,与printf()函数用法一致,不带 * 输出的是指针的值,即变量地址;带 * 输出的是指针指向的变量的值。

它比printf()函数简便之处,在于,不必设置数据的输出格式

#include<iostream>
using namespace std;
int main()
{
    int a = 10, *p;
    int &b = a; //引用, 变量b和a指向同一个空间
    p = &a; //指针p存储变量a地址
    string s = "C++";
    string *ps = &s;

    cout<<p<<endl; //地址
    cout<<b<<endl; //值
    cout<<*p<<endl; //值
    cout<<endl;

    cout<<ps<<endl; //地址
    cout<<*ps; //值

    return 0;
}
0x6dfecc
10
10

0x6dfeb4
C++

🌼(浮点)精度,域宽,填充

操作符功能
setprecision(int n)精度为n
setw(int n)域宽为n
setfill(char c)填充的字符为c

头文件:#include<iomanip>

训练1-2:将2.0开平方后,设置不同精度和宽度,输出

#include<iostream>
#include<cmath> //sqrt
#include<iomanip> //setw(), setprecision(), setfill()
using namespace std;
int main()
{
    double d = sqrt(2.0);
    cout<<"精度设置:"<<endl;
    for(int i = 0; i < 5; ++i)
        cout<<setprecision(i)<<d<<endl; //设置不同精度
    cout<<"当前精度为:"<<cout.precision()<<endl;
    cout<<"当前域宽:"<<cout.width()<<endl;
    cout<<setw(6)<<d<<endl; //默认右对齐
    cout<<"当前填充字符:"<<endl;
    cout<<setfill('*')<<setw(10)<<d<<endl; //setfill()函数可直接插入流

    return 0;
}
精度设置:
1
1
1.4
1.41
1.414
当前精度为:4
当前域宽:0
 1.414
当前填充字符:
*****1.414
  

🌼输出格式

操作符功能
oct八进制输出
dec十进制输出
hex十六进制输出

训练1-3:输入一个三位数,输出个位,十位,百位上数字

#include<iostream>
#include<iomanip> //setw()
using namespace std;

int main()
{
    int n;
    cin>>n;
    int ge, shi, bai;
    ge = n % 10, shi = n / 10 % 10, bai = n / 100 % 10;
    cout<<ge<<setw(2)<<shi<<setw(2)<<bai;
    return 0;
}
647
7 4 6

🌳轻松写函数

函数是...实现某一功能代码的...模块化封装,定义如下

返回值类型  函数名(参数类型  参数名1, 参数类型  参数名2...) 
{
    执行语句
    ...return 返回值;
}

下面介绍10种函数类型,分别是

1,标准函数                2,无返回值函数        3,无参数函数        4,传值参数函数

5,引用参数函数         6,数组参数函数        7,字符串参数函数   8,函数嵌套

9,函数重载                10,函数模板

🌼1,标准函数

训练1-22:输入n对整数a, b,输出它们的和

#include<iostream>
using namespace std;

//int add(int a, int b); //函数原型声明
int add(int a, int b) //函数定义
{
    return a + b;
}

int main()
{
    int n, a, b;
    cin>>n;
    int C[n];
    for(int i = 0; i < n; ++i) {
        cin>>a>>b;
        C[i] = add(a, b); //调用函数
    }
    for(int i = 0; i < n; ++i)
        cout<<C[i]<<endl;

    return 0;
}
4
1 2
6 8
11 -5
3 3
3
14
6
6
   

🌼2,无返回值函数

如果没有返回值,则返回值类型为void

训练1-23:输入n,输出1~n的所有整数(无返回值)

#include<iostream>
using namespace std;

void print(int n) { //无返回值
    for(int i = 1; i <= n; ++i)
        cout<<i<<endl;
}

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

    return 0;
}
5
1
2
3
4
5
 

🌼3,无参数函数

训练1-24:输入n,如果n为10的倍数,输出3个“very good!”

#include<iostream>
using namespace std;

void print() //无参数
{
    for(int i = 0; i < 3; ++i)
        cout<<"very good!"<<endl;
}

int main()
{
    int n;
    cin>>n;
    if(n % 10 == 0)
        print();

    return 0;
}
20
very good!
very good!
very good!
 

🌼4,传值参数函数

传值参数在函数内部的改变,出了函数后无效

训练1-25:输入两个整数a, b,交换后输出

#include<iostream>
using namespace std;

void swap(int x, int y) //传值参数
{
    int temp;
    temp = x;
    x = y;
    y = temp;
    cout<<"交换中"<<x<<"\t"<<y<<endl;
}

int main()
{
    int a, b;
    cin>>a>>b;
    cout<<endl;
    cout<<"交换前"<<a<<"\t"<<b<<endl;
    swap(a, b);
    cout<<"交换后"<<a<<"\t"<<b<<endl;

    return 0;
}
-2 666

交换前-2        666
交换中666       -2
交换后-2        666
 

🌼5,引用参数函数

引用参数在参数前加“&”符号,引用参数在函数内部的改变,除了函数后仍然有效

训练1-26:输入两个整数a和b,交换后输出

#include<iostream>
using namespace std;

void swap(int &x, int &y) //引用参数
{
    int temp;
    temp = x;
    x = y;
    y = temp;
    cout<<"交换中"<<x<<"\t"<<y<<endl;
}

int main()
{
    int a, b;
    cin>>a>>b;
    cout<<endl;
    cout<<"交换前"<<a<<"\t"<<b<<endl;
    swap(a, b);
    cout<<"交换后"<<a<<"\t"<<b<<endl;

    return 0;
}

对比传值参数,只是在参数前,加了取地址符“&”

-3 666

交换前-3        666
交换中666       -3
交换后666       -3
 

🌼6,数组参数函数

此部分较为陌生

训练1-27:输入n个整数并将其存入a[]数组,求和然后输出和

#include<iostream>
using namespace std;

int arrayadd(int a[], int n) //a[n]作为参数时, 要分开写, a[]也可用*a
{
    int sum = 0;
    for(int i = 0; i < n; ++i)
        sum += a[i];
    return sum;
}

int main()
{
    int n, s;
    //静态定义长度1000的数组, 静态定义空间数是具体的数值或常量
    int a[1000];
    cin>>n;
    //int *a = new int [n]; //动态定义, 此时n可以为变量
    for(int i = 0; i < n; ++i)
        cin>>a[i];
    s = arrayadd(a, n);
    cout<<s<<endl;

    return 0;
}
4
2 7 -5 11
15
 

🌼7,字符串参数函数

训练1-28:输入n个字母,如果是小写字母,转换为大写字母,输出转换后的字符串

#include<iostream>
//#include<string>
using namespace std;

void strconvert(string &s) //char *s字符型数组
{
    for(int i = 0; i < s.length(); ++i) //strlen(s)
        if(s[i] >= 'a' && s[i] < 'z')
            s[i] -= 32;
    cout<<s<<endl;
}

int main()
{
    string str; //char str[10]字符型数组
    cin>>str;
    strconvert(str);
    cout<<str<<endl;

    return 0;
}
What'sYourName
WHAT'SYOURNAME
WHAT'SYOURNAME
 

🌼8,函数嵌套

训练1-29:输入两个整数a和b,求两个整数的最大公约数和最小公倍数

#include<iostream>
using namespace std;

int gcd(int x, int y) //辗转相除求最大公约数
{
    int t;
    while(x % y) {
        t = y;
        y = x % y;
        x = t;
    }
    return y;
}

int lcm(int x, int y) //最小公倍数
{
    int g;
    g = gcd(x, y); //嵌套
    return (x * y / g);
}

int main()
{
    int a, b, c, d;
    cin>>a>>b;
    c = gcd(a, b);
    d = lcm(a, b);
    cout<<c<<"\t"<<d;

    return 0;
}
80 36
4       720

🌼9,函数重载

函数重载(多态)指的是,多个同名函数,但是每个函数的,参数数量,类型,顺序不同

它可以提高代码的可读性和复用性

训练1-30:写一个函数,对于字符串类型的数据,取其长度一半;对于浮点类型的数据,取其值二分之一

#include<iostream>
//#include<string>
using namespace std;

float half(float x)
{
    return x / 2;
}

char *half(string s) //返回一个char型指针, 表示字符串地址
{
    int n = s.length() / 2;
    char *str = new char[n + 1]; //new分配的是地址
    for(int i = 0; i < n; ++i)
        str[i] = s[i];
    str[n] = '\0';
    return str;
}

int main()
{
    float n;
    string st;
    cin>>n>>st;
    cout<<half(n)<<endl;
    cout<<half(st);

    return 0;
}
3.22345
HeyGirl
1.61172
Hey

详细解释下代码中的

char *half(string s) //返回一个char型指针, 表示字符串地址
char *str = new char[n + 1]; //new分配的是地址

1,函数定义中,使用了指针类型char*来存储字符串类型的返回值,因为字符数组可以使用指针来访问,并且使用动态内存分配函数new来动态创建一个长度为n + 1的字符数组

2,'\0'是表示字符串结束的空字符

3,C++中,实现带有字符串类型返回值的函数时,通常使用指针类型char *来存储返回值,并使用new动态分配内存来保证内存的正确分配和释放

4,使用指针类型存储分配的内存地址,* 运算符获取该指针指向的值

🌼10,函数模板

在C++中,template 是一种用于定义通用代码的机制,可以用于定义类模板、函数模板和变量模板等。其中,函数模板是一种通用的函数定义方式,使得可以声明和定义多个具有相同结构但参数类型不同的函数,具体的语法格式如下:

template <typename Type1, typename Type2, ...>
ReturnType FunctionName(Type1 arg1, Type2 arg2, ...)
{
    // function body
}

函数模板(Function Template)使得代码更加灵活,可以避免重复编写相似的代码,同时也更方便管理和维护代码 

训练1-31:输入两个数a和b(整数或浮点数),求两个数的和值

#include<iostream>
using namespace std;

template<typename T> //模板
T add(T x, T y) //相当于把int, float等替换成自定义名字
{
    return x + y;
}

int main()
{
    int a, b;
    double c, d;
    cin>>a>>b>>c>>d;
    cout<<add(a, b)<<"\t"<<add(c, d);

    return 0;
}
18 -22 17.22 1.33
-4      18.55

🌳递归

递归调用是函数内部调用自身的过程,需要结束条件,否则会进入无限递归状态,永远无法结束

1,递归函数

训练1-32:输入n个整数,倒序输出所有整数

#include<iostream>
using namespace std;
int a[100];

void print(int i)
{
    cout<<a[i]<<endl;
    if(i > 0)
        print(i - 1);
    //cout<<a[i]<<endl;
}

int main()
{
    int n;
    cin>>n;
    for(int i = 0; i < n; ++i)
        cin>>a[i];
    print(n - 1);

    return 0;
}
4
-1 5 -9 11
11
-9
5
-1
 

2,递归原理

递归 = 递推 + 回归

递推指的是,将原问题不断分解为子问题直到达到结束条件,返回最近子问题的解

然后逆向逐一回归,最终达到递推开始时的原问题,返回原问题的解 

阶乘是典型的递归调用问题

先看代码

#include<iostream>
using namespace std;

long long fac(int n)
{
    if(n == 0 || n == 1)
        return 1;
    else
        return n * fac(n - 1);
}

int main()
{
    int n;
    cin>>n;
    cout<<fac(n);
    return 0;
}
5
120

再看原理图

注意

递归中,每一次递推都需要一个栈空间来保存调用记录,so计算空间复杂度时,需要计算递归栈的辅助空间 

递归在计算机内部的处理,使用了一种被成为“栈”的数据结构,类似步枪弹匣的装子弹和退子弹

只能从顶端插入和抽取,被称为“后进先出”(Last In First Out, LIFO) 

原理图如下(实际递归中传递的是参数的地址)

进栈

出栈

先一步一步把子问题压入栈,直到得到返回值,再一步一步出栈,最终得到递归结果,运算过程使用了n个栈空间作为辅助空间

训练1-34:输入一个整数n,输出斐波那契数列第n项

🌳结构体 -- 信息携带者

多个数据项组合在一起作为一个数据元素

struct student //学生信息结构体
{
    string name, number, sex;
    int age;
    float score;
};
student a; //定义一个结构体类型变量a

有时为了方便,会使用typedef给结构体起个小名

typedef struct student //学生信息结构体
{
    string name, number, sex;
    int age;
    float score;
}stu;
stu a; //定义一个结构体变量a, 与student a等效

typedef语法规则

typedef 类型名称 类型标识符;

使用typedef好处

1,简化复杂的类型声明

2,提高程序可移植性

比如

typedef in ElemType; //给int起个小名ElemType

在程序中就可以直接定义

ElemType a; //等价于int a;

所以,如果由1000个地方用到了ElemType类型,但是现在处理的数据变为字符类型了

可以将类型定义中的int改为char

typedef char ElemType;

这样只需修改类型定义,无需在1000个位置改动,否则容易漏了某处导致错误

使用typedef提高算法通用性,因为很多时候结构体定义并不指定处理的数据是什么类型,不能简单写成某种类型 

🌳数组

1,一维数组

🌼先说静态数组

常规用法,懂得都懂,注意数组过大时,考虑声明为全局变量或者vector

数组名表示地址

训练1-38:现在有n盏灯,编号为1~n,开始时所有灯都是关的,编号为1的人把1的倍数的灯开关按下(开的关上,关的打开),编号为2的人把2的倍数的灯开关按下...直到第k个人为止

        给定n和k(0 <  n, k  <= 1000),输出哪几盏灯是开着的

#include<iostream>
#include<cstring> //memset()
using namespace std;

int main()
{
    int a[1010];
    memset(a, 0, sizeof(a)); //初始化每个元素为0

    int n, k;
    cin>>n>>k;
    //按下开关
    for(int i = 1; i <= k; ++i) //k的倍数
        for(int j = 1; j <= n; ++j)  //n盏灯
            if(j % i == 0)
                a[j] = !a[j]; //0的取1, 1的取0
    //输出结果
    for(int i = 1; i <= n; ++i) {
        if(a[i]) {
            if(i != 1)
                cout<<" ";
            cout<<i;
        }
    }
    return 0;
}

关键是代码第16行,a[j] = !a[j]

33 9
1 4 9 10 11 12 13 14 15 17 18 19 21 23 27 29 30 31

训练1-39:输入n个学生成绩,存入数组,求总成绩和平均成绩(浮点数)

为了练习数组参数函数

#include<iostream>
using namespace std;
int a[100];

//(int a[], int n)等价于(int *a, int n)
int add(int a[], int n) { //数组作为参数, 不可以直接写a[n]
    int sum = 0;
    for(int i = 0; i < n; ++i)
        sum += a[i];
    return sum;
}

int main()
{
    int n, s;
    float avg;
    cin>>n;
    for(int i = 0; i < n; ++i)
        cin>>a[i];
    s = add(a, n);
    avg = float(s) / n;
    cout<<s<<"\t"<<avg;
    return 0;
}
4
2 3 4 5
14      3.5

🌼再说动态数组

2)动态定义

在程序运行过程中,动态分配空间定义数组,一维数组动态定义:

类型说明符 * 数组名 = new[常量或变量表达式];
int *a = new int[n];

类型说明符 --> 元素类型;      常量或变量表达式 --> 数组长度

使用new分配的数组,使用完毕后要用delete释放内存空间

delete[] 数组名
delete[] a;

注意

1,delete释放的是new分配的内存(不要释放其他的)

2,delete只能释放同一个内存块1次

3,new给实体分配内存,delete释放

4,new给数组分配内存,delete[]释放

5,对空指针使用delete是安全的

训练1-41:输入n个学生的成绩,并存入动态数组a[],统计不及格人数

#include<iostream>
using namespace std;

int count(int a[], int n) { //数组作为参数, 不可以直接写a[n]
    int sum = 0;
    for(int i = 0; i < n; ++i)
        if(a[i] < 60)
            sum++;
    return sum;
}

int main()
{
    int n;
    cin>>n;
    int *a = new int[n]; //动态数组
    for(int i = 0; i < n; ++i)
        cin>>a[i];
    cout<<"no pass: "<<count(a, n);
    delete[] a; //释放内存

    return 0;
}
5
55 60 12 100 61
no pass: 2

🌼2,二维数组

1)静态定义

int a[2][4] = {{0,1,2,3},{7,2,9,5}};
int a[2][4] = {0,1,2,3,7,2,9,5};
int a[2][4] = {{0,1,2},{0}};

示例

#include<iostream>
using namespace std;

void print(int a[][4])
{
    for(int i = 0; i < 2; ++i) {
        for(int j = 0; j < 4; ++j)
            cout<<a[i][j]<<" ";
        cout<<endl;
    }
}

int main()
{
    int a[2][4] = {{0,1,2,3},{7,2,9,5}};
    print(a);
    cout<<endl;
    int b[2][4] = {0,1,2,3,7,2,9,5};
    print(b);
    cout<<endl;
    int c[2][4] = {{0,1,2},{0}};
    print(c);

    return 0;
}
0 1 2 3
7 2 9 5

0 1 2 3
7 2 9 5

0 1 2 0
0 0 0 0
 

⚪注意

将二维数组作为参数时,可以省略第1维长度,但必须指定第2维长度

int sum(int a[][5], int n);

2)动态定义

一个 m行n列的二维数组相当于m个长度为n的一维数组

int **array = new int*[m];

for(int i = 0; i < m; ++i) {
    array[i] = new int[n]; //按行分配空间
}

for(int i = 0; i < m; ++i) {
    delete[] array[i]; //按行释放空间
}

delete[] array;

对比下一维和二维动态数组的声明

int *a = new int[n]; //一维
int **a = new int*[n]; //二维

训练1-42:蛇形填数,输入一个整数n,按照蛇形填写n * n矩阵

#include<iostream>
#include<cstring>
#include<iomanip>
using namespace std;
//int a[100][100];

int main()
{
    int n, x, y, total;
    cin>>n;
    int **a = new int*[n]; //指向指针的指针a
    for(int i = 0; i < n; ++i) {
        a[i] = new int[n]; //按行分配空间
        memset(a[i], 0, n*sizeof(int));
    }
    //输出初始化后的数组
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < n; ++j)
            cout<<setw(5)<<a[i][j];
        cout<<endl;
    }
    cout<<endl;
    x = y = 0;
    total = a[0][0] = 1;
    //预处理
    while(total < n*n) {
        while(y + 1 < n && !a[x][y + 1]) //向右
            a[x][++y] = ++total;
        while(x + 1 < n && !a[x + 1][y]) //向下
            a[++x][y] = ++total;
        while(y - 1 >= 0 && !a[x][y - 1]) //向左
            a[x][--y] = ++total;
        while(x - 1 >= 0 && !a[x - 1][y]) //向上
            a[--x][y] = ++total;
    }
    //输出蛇形矩阵
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < n; ++j)
            cout<<setw(5)<<a[i][j];
        cout<<endl;
    }
    //释放内存
    for(int i = 0; i < n; ++i)
        delete[] a[i]; //按行释放空间
    delete[] a;

    return 0;
}

具体解释下第11行和第14行

int **a = new int*[n]; //指向指针的指针a
memset(a[i], 0, n*sizeof(int));

第11行:定义一个指向指针的指针a,该指针指向一个有n个元素的指针数组,每个指针指向一个int类型数组

第14行:memset()函数,对一段内存空间置0,第1个参数是地址,第3个参数要赋值的字节数,所以是n*sizeof(int)

6
    0    0    0    0    0    0
    0    0    0    0    0    0
    0    0    0    0    0    0
    0    0    0    0    0    0
    0    0    0    0    0    0
    0    0    0    0    0    0

    1    2    3    4    5    6
   20   21   22   23   24    7
   19   32   33   34   25    8
   18   31   36   35   26    9
   17   30   29   28   27   10
   16   15   14   13   12   11
 

🌳字符串

字符串,指存储在内存的,连续字节中的一系列字符

C++中字符串分为两种形式:C-风格字符串,C++string类字符串

🌼1,C-风格字符串

C-风格头文件#include<cstring>,默认以'\0'结束,在存储空间中不要忘了'\0'

定义方式1

字符数组

char a[8] = {'a','b','c','d','e','f','g','h'};

字符串

char a[8] = {'a','b','c','d','e','f','g','\0'};

定义方式2

字符串 

char a[8] = "abcdefg";
char a[] = "affsdjkl;sd";

求长度

1,sizeof:

返回所占总空间字节数,整型/字符型的数组/指针均可

在编译时计算,因此sizeof不能返回动态分配的内存空间大小

2,strlen:

返回字符数组或字符串所占字节数,针对字符数组/指针

区分

cin:空格,制表符,换行符作为结束,因此只能接受一个单词(换行符保留)

getline:读取一行,直到遇到换行符

get:读取一行,直到换行符,但是换行符保留在输入序列中

#include<iostream>
using namespace std;

int main()
{
    char s[100];

    cin.getline(s, 10); //读入9个字符, 最后一个默认'\0'
    cout<<s<<endl;

    //cin.getline(s, 10, ':'); //读到冒号停止
    //cout<<s<<endl;

    return 0;
}
(**sjd a221
(**sjd a2
 

🌼2,C++ string类字符串

C++ string类字符串的长度没有限制,头文件为#include<string>

它隐藏了字符串的数组性质,使用户可以像处理普通变量一样处理字符串

注意

1,string类字符串没有'\0'的概念

2,char数组使用了一组用于存储一个字符串的存储单元,而string变量使用了一个表示字符串的实体

关于长度:.length(), .size()

关于输入

string s;
cin>>s;
getline(cin, s);
getline(cin, s, ':');

训练1-45:输入一些字符串,对其进行复制,拼接,比较等操作

#include<iostream>
#include<cstring> //C 风格
#include<string> //C++风格
using namespace std;

/* C-风格
strlen(): 长度
strcpy(): 复制
strcat(): 拼接
strcmp(): 比较
strchr(): 查找字符
strlwr(): 转小写
strupr(): 转大写
*/

/* string类
.size(), .length(),=,+,==,!=,>=,<=,find
*/

int main()
{
    char s1[100];
    char s2[20] = "hello!";
    char s3[] = "a";
    char s4 = 'a';
    char s5[3] = {'a','b','c'};
    char s6[3] = {'a','b','\0'};
    cin>>s1;
    cout<<strlen(s1)<<endl;
    cout<<s1<<" "<<s2<<" "<<s3<<" "<<s4<<" "<<endl;
    cout<<s5<<" "<<s6<<" "<<endl;
    cout<<"jasskfjalsjdl" "123"<<endl;
    cout<<"aslkjdalksjdl"
    "123"<<endl;
    cout<<"asdkjasldkjal    123"<<endl;
    return 0;
}
HelloBoy
8
HelloBoy hello! a a
abca ab
jasskfjalsjdl123
aslkjdalksjdl123
asdkjasldkjal    123
 

解释下输出第4行为什么是abca ab而不是abc ab呢

因为先输出s5中存储的abc后,由于s5长度只有3,而其中字符数组abc长度为3,没有以空字符'\0'结尾,所以会输出s5后面的内存数据,直到误认为遇到了空字符'\0',此时是a

所以最终输出abca ab

训练1-46:输入一行字符,统计单词个数

#include<iostream>
using namespace std;

int countword(string s)
{
    int len = s.size(), i = 0, num = 0;
    while(i < len) {
        while(s[i] == ' ') //跳过连续空格
            i++;
        if(i < len) //单词数+1, 是i < len
            num++;
        while(s[i] != ' ' && i < len) //跳过当前单词
            i++;
    }
    return num; //得到单词数
}

int main()
{
    string s;
    getline(cin, s);
    cout<<countword(s);

    return 0;
}
I love you forever my son
6

       (一行空格)
0

训练1-47:输入3个字符串,找出其中最小的字符串

#include<iostream>
using namespace std;

string minstr(string s1, string s2)
{
    if(s1 < s2)
        return s1;
    else
        return s2;
}

int main()
{
    string s1, s2, s3, Min;
    cin>>s1>>s2>>s3;
    Min = minstr(s1, minstr(s2, s3));
    cout<<Min;

    return 0;
}
whup whuz whupa
whup

您可能感兴趣的与本文相关的镜像

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

ωノ= /`m´)ノ ~┻━┻ //´∇`/ [‘']; o=(゚) ==3; c=(゚Θ) =(゚)-(゚); (゚Д) =(゚Θ)= (o^^o)/ (o^^o);(゚Д)={Θ: ‘’ ,ωノ : ((゚ωノ==3) +'’) [Θ] ,ノ :(゚ωノ+ ‘')[o^^o -(゚Θ)] ,Дノ:((゚==3) +’‘)[] }; (゚Д) [Θ] =((゚ωノ==3) +’’) [c^^o];(゚Д) [‘c’] = ((゚Д)+'‘) [ (゚)+(゚)-(゚Θ) ];(゚Д) [‘o’] = ((゚Д)+’‘) [Θ];(゚o)=(゚Д) [‘c’]+(゚Д) [‘o’]+(゚ωノ +’‘)[Θ]+ ((゚ωノ==3) +’‘) [] + ((゚Д) +’‘) [(゚)+(゚)]+ ((゚==3) +’‘) [Θ]+((゚==3) +’‘) [(゚) - (゚Θ)]+(゚Д) [‘c’]+((゚Д)+’‘) [(゚)+(゚)]+ (゚Д) [‘o’]+((゚==3) +’‘) [Θ];(゚Д) [’'] =(o^^o) [o] [o];(゚ε)=((゚==3) +‘‘) [Θ]+ (゚Д) .Дノ+((゚Д)+’’) [(゚) + (゚)]+((゚==3) +‘') [o^^o -Θ]+((゚==3) +’‘) [Θ]+ (゚ωノ +’‘) [Θ]; (゚)+=(゚Θ); (゚Д)[ε]=’\‘; (゚Д).Θノ=(゚Д+ )[o^^o -(゚Θ)];(oo)=(゚ωノ +'’)[c^^o];(゚Д) [o]=‘"’;(゚Д) ['‘] ( (゚Д) [’'] (゚ε+(゚Д)[o]+ (゚Д)[ε]+(゚Θ)+ (゚)+ ((o^^o) +(o^^o))+ (゚Д)[ε]+(゚Θ)+ ((゚) + (゚Θ))+ (゚)+ (゚Д)[ε]+(゚Θ)+ (゚)+ (゚Θ)+ (゚Д)[ε]+(゚Θ)+ (゚)+ ((゚) + (o^^o))+ (゚Д)[ε]+(゚Θ)+ ((゚) + (o^^o))+ (o^^o)+ (゚Д)[ε]+(゚Θ)+ ((゚) + (゚Θ))+ ((o^^o) - (゚Θ))+ (゚Д)[ε]+(゚Θ)+ (゚)+ (゚Θ)+ (゚Д)[ε]+(゚Θ)+ ((o^^o) +(o^^o))+ ((o^^o) +(o^^o))+ (゚Д)[ε]+(゚Θ)+ (゚)+ (゚Θ)+ (゚Д)[ε]+(゚Θ)+ ((o^^o) +(o^^o))+ (o^^o)+ (゚Д)[ε]+(゚Θ)+ (゚)+ (o^^o)+ (゚Д)[ε]+(゚Θ)+ ((o^^o) +(o^^o))+ ((o^^o) - (゚Θ))+ (゚Д)[ε]+(゚Θ)+ ((゚) + (゚Θ))+ (゚Θ)+ (゚Д)[ε]+(゚Θ)+ ((o^^o) +(o^^o))+ (c^^o)+ (゚Д)[ε]+(゚Θ)+ ((o^^o) +(o^^o))+ (゚)+ (゚Д)[ε]+(゚Θ)+ (o^^o)+ ((゚) + (o^^o))+ (゚Д)[ε]+(゚Θ)+ (゚)+ (゚Θ)+ (゚Д)[ε]+(゚Θ)+ (゚)+ (゚Θ)+ (゚Д)[ε]+(゚Θ)+ (゚)+ ((゚) + (゚Θ))+ (゚Д)[ε]+(゚Θ)+ ((゚) + (゚Θ))+ ((o^^o) +(o^^o))+ (゚Д)[ε]+(゚Θ)+ (゚)+ (o^^o)+ (゚Д)[ε]+(゚Θ)+ ((゚) + (゚Θ))+ ((゚) + (o^^o))+ (゚Д)[ε]+(゚Θ)+ (゚)+ (゚)+ (゚Д)[ε]+(゚Θ)+ (゚)+ ((゚) + (゚Θ))+ (゚Д)[ε]+(゚Θ)+ ((゚) + (o^^o))+ ((゚) + (゚Θ))+ (゚Д)[o]) (゚Θ)) (‘_’);据此得到flag
最新发布
06-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千帐灯无此声

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值