笨蛋学C++【C++基础第二弹】

C++基础第二弹

    • 2.C++运算
      • 2.1运算符
        • 2.1.1算术运算符
        • 2.1.2关系运算符
        • 2.1.3逻辑运算符
        • 2.1.4位运算符
        • 2.1.5赋值运算符
        • 2.1.6杂项运算符
        • 2.1.7运算符优先级
        • 2.1.8注意
    • 3.C++循环
      • 3.1C++while循环
        • 3.1.1语法
      • 3.2C++for循环
        • 3.2.1基于范围的for循环方式1
        • 3.2.2基于范围的for循环方式2
        • 3.2.3基于范围的for循环方式3
        • 3.2.4基于范围的for循环方式4
      • 3.3C++do...while循环
      • 3.4C++嵌套循环
        • 3.4.1C++嵌套for循环
        • 3.4.2C++嵌套while循环
        • 3.4.3C++嵌套do...while循环
      • 3.5循环控制语句
        • 3.5.1break语句
        • 3.5.2continue语句
        • 3.5.3goto语句
      • 3.6无限循环
    • 4.C++判断
      • 4.1C++if语句
      • 4.2C++if...else语句
      • 4.3C++if...else if...else语句
      • 4.4C++嵌套if语句
      • 4.5C++switch语句
      • 4.6C++嵌套switch语句
      • 4.7C++?:运算符
    • 5.C++函数
      • 5.1定义函数
      • 5.2函数声明
      • 5.3调用函数
      • 5.4函数参数
        • 传值调用`(x,y)`
        • 指针调用`(*x,*y)`
        • 引用调用`(&x,&y)`
      • 5.5参数的默认值
      • 5.6Lambda函数与表达式
    • 6.C++数字
      • 6.1C++定义数字
      • 6.2C++内置数学函数
      • 6.3C++随机数
        • rand()%(m-1+n)%m

2.C++运算

2.1运算符

  • 运算符是一种告诉编译器执行特定的数学或逻辑操作的符号
    • 算术运算符
    • 关系运算符
    • 逻辑运算符
    • 位运算符
    • 赋值运算符
    • 杂项运算符
2.1.1算术运算符
运算符描述实例
+把两个操作数相加A + B 将得到 30
-从第一个操作数中减去第二个操作数A - B 将得到 -10
*把两个操作数相乘A * B 将得到 200
/分子除以分母B / A 将得到 2
%取模运算符,整除后的余数B % A 将得到 0
++自增运算符,整数值增加 1A++ 将得到 11
自减运算符,整数值减少 1A-- 将得到 9
2.1.2关系运算符
运算符描述实例
==检查两个操作数的值是否相等,如果相等则条件为真。(A == B) 不为真。
!=检查两个操作数的值是否相等,如果不相等则条件为真。(A != B) 为真。
>检查左操作数的值是否大于右操作数的值,如果是则条件为真。(A > B) 不为真。
<检查左操作数的值是否小于右操作数的值,如果是则条件为真。(A < B) 为真。
>=检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。(A >= B) 不为真。
<=检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。(A <= B) 为真。
2.1.3逻辑运算符
运算符描述实例
&&称为逻辑与运算符。如果两个操作数都 true,则条件为 true。(A && B) 为 false。
||称为逻辑或运算符。如果两个操作数中有任意一个 true,则条件为 true。(A || B) 为 true。
!称为逻辑非运算符。用来逆转操作数的逻辑状态,如果条件为 true 则逻辑非运算符将使其为 false。!(A && B) 为 true。
2.1.4位运算符
pqp & qp | qp ^ q
00000
01011
11110
10011
运算符描述实例
(A为60(0011 1100),
B为13(0000 1101))
&按位与操作,按二进制位进行"与"运算。
运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;
(A & B) 将得到 12,即为 0000 1100
|按位或运算符,按二进制位进行"或"运算。
运算规则:`0
0=0; 0
^异或运算符,按二进制位进行"异或"运算。
运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0;
(A ^ B) 将得到 49,即为 0011 0001
~取反运算符,按二进制位进行"取反"运算。
运算规则:~1=-2; ~0=-1;
(~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。
<<二进制左移运算符。将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。A << 2 将得到 240,即为 1111 0000
>>二进制右移运算符。将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。A >> 2 将得到 15,即为 0000 1111
2.1.5赋值运算符
运算符描述实例
=简单的赋值运算符,把右边操作数的值赋给左边操作数C = A + B 将把 A + B 的值赋给 C
+=加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数C += A 相当于 C = C + A
-=减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数C -= A 相当于 C = C - A
*=乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数C *= A 相当于 C = C * A
/=除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数C /= A 相当于 C = C / A
%=求模且赋值运算符,求两个操作数的模赋值给左边操作数C %= A 相当于 C = C % A
<<=左移且赋值运算符C <<= 2 等同于 C = C << 2
>>=右移且赋值运算符C >>= 2 等同于 C = C >> 2
&=按位与且赋值运算符C &= 2 等同于 C = C & 2
^=按位异或且赋值运算符C ^= 2 等同于 C = C ^ 2
|=按位或且赋值运算符C |= 2 等同于 C = C | 2
2.1.6杂项运算符
运算符描述
sizeofsizeof 运算符返回变量的大小。例如,sizeof(a) 将返回 4,其中 a 是整数。
Condition ? X : Y条件运算符。如果 Condition 为真 ? 则值为 X : 否则值为 Y。(三目运算符
,逗号运算符会顺序执行一系列运算。整个逗号表达式的值是以逗号分隔的列表中的最后一个表达式的值。
.(点)和 ->(箭头)成员运算符用于引用类、结构和共用体的成员。
Cast强制转换运算符把一种数据类型转换为另一种数据类型。例如,int(2.2000) 将返回 2。
&指针运算符 & 返回变量的地址。例如 &a; 将给出变量的实际地址。
*指针运算符 * 指向一个变量。例如,*var; 将指向变量 var。
2.1.7运算符优先级
类别运算符结合性
后缀() [] -> . ++ - -从左到右
一元+ - ! ~ ++ - - (type)* & sizeof从右到左
乘除* / %从左到右
加减+ -从左到右
移位<< >>从左到右
关系< <= > >=从左到右
相等== !=从左到右
位与 AND&从左到右
位异或 XOR^从左到右
位或 OR|从左到右
逻辑与 AND&&从左到右
逻辑或 OR||从左到右
条件?:从右到左
赋值= += -= *= /= %=>>= <<= &= ^= |=从右到左
逗号,从左到右
2.1.8注意
  • 任何数异或^0得到的值不变(a ^0 = a)

  • 任何书异或同一个数两次得到的值不变(a ^b ^b = a)

  • 对取模运算符 % 的优化(比如%8 == &7,%9 == &8,%22 == &21)

    int a,b,c;
    a=53;
    b=a%8;                //给a取模8
    c=a&7;                //让a和7进行位运算"与"
    std::cout<<"b="<<b<<std::endl;  //b=5
    std::cout<<"c="<<c<<std::endl;   //c=5
    
  • 先算右一后左一,①

    乘除加减移位比。②

    与异或或位逻辑,③

    三目赋值逗号稀。④

    ①先算右面的一元运算符,后算左面的。

    ②乘除代表*/%,加减就是+和-,移位就是<<和>>,比就是比较运算符,注意比较运算符先算<、>、<=和>=这4个含不等号的,后算==和!=这两个。

    ③先算按位逻辑运算符,再算普通的逻辑运算符;按位逻辑运算符的顺序是&^|,逻辑运算符先算&&再算||,只是少了逻辑异或。

    ④先算三目运算符,再算赋值运算符,逗号运算符的优先级最低,所以说它“稀”。

3.C++循环

  • 允许多次执行一个语句或语句组

    循环类型描述
    while 循环当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。
    for 循环多次执行一个语句序列,简化管理循环变量的代码。
    do…while 循环除了它是在循环主体结尾测试条件外,其他与 while 语句类似。
    嵌套循环可以在 while、for 或 do…while 循环内使用一个或多个循环。

3.1C++while循环

3.1.1语法
while(条件表达式){循环体代码块;
}
如果条件为true
如果条件为false
开始
条件表达式判断
循环内的代码块
结束
  • while循环的关键点是循环可能一次都不会执行
  • 当条件被测试且结果为假时,会跳过循环主体,直接执行while循环后的下一条语句
//
// Created by 16690 on 2024/4/18.
//
#include <iostream>
using namespace std;int main(void){//局部变量声明int a = 10;//while循环执行while(a < 20){cout << "a的值为: " << a << endl;a++;}cout << "循环结束,a的值为:" << a << endl;return 0;
}

3.2C++for循环

for(初始化语句; 条件语句; 自增或自减语句){循环体代码块;
}
  • 初始化语句 会首先被执行,且只会执行一次。可以声明并初始化任何循环控制变量,也可以不在这里写任何语句,只要有一个分号出现即可。
  • 接下来,会判断 条件语句。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
  • 在执行完 for 循环主体后,控制流会跳回上面的 自增或自减 语句。该语句允许更新循环控制变量,该语句可以留空,只要在条件后有一个分号出现即可。
  • 条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后自增或自减,再然后重新判断条件)。在条件变为假时,for 循环终止。
如果条件为true
如果条件为false
开始
初始化语句
条件表达式判断
循环内的代码块
自增或自减语句
结束
//局部变量声明int a = 10;//while循环执行while(a < 20){cout << "a的值为: " << a << endl;a++;}cout << "循环结束,a的值为:" << a << endl;
3.2.1基于范围的for循环方式1
//
// Created by 16690 on 2024/4/18.
//
#include <iostream>
using namespace std;int main(void){int my_array[5] = {1,2,3,4,5};//每个数组元素乘以2for(int &x : my_array){x *= 2;cout << x << endl;}cout << "--------------------------" << endl;//auto自动获取变量的类型for(auto &x : my_array){cout << x << endl;x *= 2;}return 0;
}
3.2.2基于范围的for循环方式2
//
// Created by 16690 on 2024/4/18.
//
#include <iostream>
#include <array>
using namespace std;int main(void){int my_array[5] = {1,2,3,4,5};cout << "--------------------------" << endl;for(int x: my_array){x *= 2;cout << x << endl;}return 0;
}
3.2.3基于范围的for循环方式3
//
// Created by 16690 on 2024/4/18.
//
#include <iostream>
using namespace std;int main(void){cout << "--------------------------" << endl;string str("some string");//range for语句for(auto &c : str){cout << c << endl;c = toupper(c);}cout << str << endl;return 0;
}
3.2.4基于范围的for循环方式4
//
// Created by 16690 on 2024/4/18.
//
#include <iostream>
using namespace std;int main(void){cout << "--------------------------" << endl;for(int x: {1,2,3,4,5}){x *= 2;cout << x << endl;}return 0;
}

3.3C++do…while循环

do{循环体代码块;
}while(条件语句);
  • 条件表达式出现在循环的尾部,所以循环体中代码块会在条件语句判断前至少执行一次
  • 若条件为真,会跳转回上面的do,然后重新执行循环中的循环体代码块,过程会不断重复,直到给定条件变假为止
如果条件为true
如果条件为false
开始
循环内的代码块
条件表达式判断
结束
//
// Created by 16690 on 2024/4/18.
//
#include <iostream>
#include <array>
using namespace std;int main(void){//局部变量声明int a = 10;//do循环执行do{cout << "a的值为: " << a << endl;a=a+1;}while(a < 20);return 0;
}

3.4C++嵌套循环

3.4.1C++嵌套for循环
for ( 初始化语句; 条件语句表达式; 自增或自减语句 )
{for ( 初始化语句; 条件语句表达式; 自增或自减语句 ){循环体代码块;}循环体代码块; // 可以放置更多的语句
}
3.4.2C++嵌套while循环
while(条件语句表达式)
{while(条件语句表达式){循环体代码块;}循环体代码块; // 可以放置更多的语句
}
3.4.3C++嵌套do…while循环
do
{循环体代码块; // 可以放置更多的语句do{循环体代码块;}while( 条件语句表达式 );}while( 条件语句表达式 );

3.5循环控制语句

3.5.1break语句
  • 当break语句出现在一个循环内时,循环会立即终止,且程序将继续执行循环后的下一条语句
  • 可用于终止switch语句中的case
  • 若是嵌套循环,则break会停止执行最内层的循环,然后开始执行该块之后的下一行代码
如果条件为true
如果条件为false
开始
条件语句
循环内代码块
结束
break
3.5.2continue语句
  • 是跳过当前循环中的代码,强迫开始下一次循环
如果条件为true
如果条件为false
开始
条件语句
循环内代码块
结束
continue
3.5.3goto语句
  • goto语句允许把控制无条件转移到同一函数内的被标记的语句

    goto label;
    ......
    ...
    label: 代码块;
    
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    #include <array>using namespace std;int main(void) {//局部变量声明int a = 10;//do循环执行LOOP:do {if (a == 15) {//跳过迭代a = a + 1;goto LOOP;}cout << "a = " << a << endl;a = a + 1;} while (a < 20);return 0;
    }
    //打印11-14,16-20
    

3.6无限循环

  • 若条件永远不为假,则循环将变成无限循环
  • for( ; ; ){}表示一个无限循环

4.C++判断

  • 指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)

4.1C++if语句

if(布尔表达式语句){//若布尔表达式为真就执行的语句
}
  • 如果布尔表达式为 true,则 if 语句内的代码块将被执行。如果布尔表达式为 false,则 if 语句结束后的第一组代码(闭括号后)将被执行。
  • 任何非零非空的值假定为 true,把null 假定为 false
若布尔表达式为true
若布尔表达式为false
开始
布尔表达式语句
需要执行的代码
结束
#include <iostream>
using namespace std;int main ()
{// 局部变量声明int a = 10;// 使用 if 语句检查布尔条件if( a < 20 ){// 如果条件为真,则输出下面的语句cout << "a 小于 20" << endl;}cout << "a 的值是 " << a << endl;return 0;
}

4.2C++if…else语句

if(布尔表达式语句){//若布尔表达式为真就执行的语句
}
else{//若布尔表达式为真就执行的语句
}
若布尔表达式为true
若布尔表达式为false
开始
布尔表达式语句
if内的代码块
结束
else内的代码块
#include <iostream>
using namespace std;int main ()
{// 局部变量声明int a = 100;// 检查布尔条件if( a < 20 ){// 如果条件为真,则输出下面的语句cout << "a 小于 20" << endl;}else{// 如果条件为假,则输出下面的语句cout << "a 大于 20" << endl;}cout << "a 的值是 " << a << endl;return 0;
}

4.3C++if…else if…else语句

if(布尔表达式语句1)
{// 当布尔表达式 1 为真时执行
}
else if( 布尔表达式语句2)
{// 当布尔表达式 2 为真时执行
}
else if( 布尔表达式语句3)
{// 当布尔表达式 3 为真时执行
}
else 
{// 当上面条件都不为真时执行
}
  • 一个if后可以跟0个或1个else,else必须在所有else if之后
  • 一个if后可以跟0个或多个else if,else if必须在else之前
  • 一旦某个else if匹配成功,其它的else if 或else 就不会被测试
#include <iostream>
using namespace std;int main ()
{// 局部变量声明int a = 100;// 检查布尔条件if( a == 10 ){// 如果 if 条件为真,则输出下面的语句cout << "a 的值是 10" << endl;}else if( a == 20 ){// 如果 else if 条件为真,则输出下面的语句cout << "a 的值是 20" << endl;}else if( a == 30 ){// 如果 else if 条件为真,则输出下面的语句cout << "a 的值是 30" << endl;}else{// 如果上面条件都不为真,则输出下面的语句cout << "没有匹配的值" << endl;}cout << "a 的准确值是 " << a << endl;return 0;
}

4.4C++嵌套if语句

if( 布尔表达式语句1)
{// 当布尔表达式 1 为 true 时执行if(布尔表达式语句2){// 当布尔表达式 2 为 ture 时执行}
}
  • 可以在一个if 或else if语句内使用另一个if 或else if语句
if (布尔表达式语句1) {// 如果 布尔表达式语句1 为 true,则执行此处的代码块if (布尔表达式语句2) {// 如果 布尔表达式语句2 也为 true,则执行此处的代码块}else {// 如果 布尔表达式语句2 为 false,则执行此处的代码块}
}
else {// 如果 布尔表达式语句1 为 false,则执行此处的代码块
}

4.5C++switch语句

switch(表达式){case 比较的值1 :代码块1;break; // 可选的case 比较的值2  :代码块2;break; // 可选的// 可以有任意数量的 case 语句default : // 可选的其它代码块;
}
  • 允许测试一个变量等于多个值时的情况,每个值称为一个case,且被测试的变量会对每个switch case进行检查

  • switch语句中的表达式必须是一个整型或枚举类型,或是一个class类型,class有一个单一的转换函数将其转换为整型或枚举类型
  • 在 switch 中可以有任意数量的 case 语句。每个 case 后跟一个要比较的值和一个冒号。
  • case 的 比较的值 必须与 switch 中的变量具有相同的数据类型,且必须是一个常量或字面量。
  • 当被测试的变量等于 case 中的常量时,case 后跟的语句将被执行,直到遇到 break 语句为止。
  • 当遇到 break 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。
  • 不是每一个 case 都需要包含 break。如果 case 语句不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止。
  • 一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
case1
case2
case3
default
开始
表达式
代码块1-break
代码块2-break
代码块3-break
其它代码块-break
结束
#include <iostream>
using namespace std;int main ()
{// 局部变量声明char grade = 'D';switch(grade){case 'A' :cout << "很棒!" << endl; break;case 'B' :case 'C' :cout << "做得好" << endl;break;case 'D' :cout << "您通过了" << endl;break;case 'F' :cout << "最好再试一下" << endl;break;default :cout << "无效的成绩" << endl;}cout << "您的成绩是 " << grade << endl;return 0;
}

4.6C++嵌套switch语句

  • 可以在一个switch语句内使用另一个switch语句
switch(ch1) {case 'A': cout << "这个 A 是外部 switch 的一部分";switch(ch2) {case 'A':cout << "这个 A 是内部 switch 的一部分";break;case 'B': // 内部 B case 代码}break;case 'B': // 外部 B case 代码
}
#include <iostream>
using namespace std;int main ()
{// 局部变量声明int a = 100;int b = 200;switch(a) {case 100: cout << "这是外部 switch 的一部分" << endl;switch(b) {case 200:cout << "这是内部 switch 的一部分" << endl;}}cout << "a 的准确值是 " << a << endl;cout << "b 的准确值是 " << b << endl;return 0;
}

4.7C++?:运算符

  • Exp1 ?Exp2 :Exp3;,?表达式的值由Exp1决定,若Exp1为真,则计算Exp2的值,否则就计算Exp3的值

5.C++函数

  • 函数是一组一起执行一个任务的语句,每个C++程序都至少有一个函数,即主函数
  • 可以将代码划分到不同的函数中
  • 函数声明告诉编译器函数的名称、返回类型、参数
  • 函数定义提供了函数的实际主体

5.1定义函数

返回类型 函数名(参数列表){函数体代码块;
}
  • 返回类型,一个函数可以返回一个值,若不需要返回,则返回类型设为void
  • 函数名,函数的实际名称,与参数列表构成了函数签名
  • 参数,参数是可选的,当函数被调用时,就向参数传递一个值,这个值被称为实际参数,参数列表包含函数参数的类型、顺序、个数
  • 函数体代码块,包含一组该函数需要执行的代码块

5.2函数声明

  • 函数声明包括 返回类型 函数名(参数列表)
  • 返回类型 函数名(参数类型 参数1,参数类型 参数2)
  • 返回类型 函数名(参数类型,参数类型),参数名不是必须的,参数类型是必须的

5.3调用函数

  • 通过定义函数做什么,然后通过调用函数来完成已定义的任务
  • 调用函数时,传递所需参数,若函数返回一个值,则可以存储返回值
//
// Created by 16690 on 2024/4/18.
//
#include <iostream>using namespace std;//函数声明
int max(int num1,int num2);
//int max(int,int);
int main(void){//局部变量声明int a = 100;int b = 200;int ret;//调用函数来获取最大值ret = max(a,b);cout << "最大值 : " << ret << endl;return 0;
}
int max(int num1,int num2){int result;if(num1>num2){result = num1;}else{result = num2;}return result;
}

5.4函数参数

  • 函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数
  • 形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁
调用类型描述
传值调用该方法把参数的实际值赋值给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。
指针调用该方法把参数的地址赋值给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
引用调用该方法把参数的引用赋值给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
  • 传值调用(x,y)
    • 将参数的实际值复制给函数的形式参数
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>using namespace std;void swap1(int, int);void swap2(int, int);void swap3(int, int);int main(void) {int num1, num2;num1 = 10;num2 = 20;cout << "交换前的值" << endl;cout << "num1 = " << num1 << endl;cout << "num2 = " << num2 << endl;swap1(num1, num2);swap2(num1, num2);swap3(num1, num2);cout << "交换后的值" << endl;cout << "num1 = " << num1 << endl;cout << "num2 = " << num2 << endl;return 0;
    }
    //中间变量处理
    void swap1(int num1, int num2) {int temp;temp = num1;num1 = num2;num2 = temp;return;
    }
    //算术处理
    void swap2(int num1, int num2) {num1 = num1 + num2;num2 = num1 - num2;num1 = num1 - num2;
    }
    //异或处理
    void swap3(int num1, int num2) {num1 = num1 ^ num2;num2 = num1 ^ num2;num1 = num1 ^ num2;
    }
    
  • 指针调用(*x,*y)
    • 将参数的地址复制给形式参数,在函数内,地址用于访问调用中要用到的实际参数
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>using namespace std;void swap(int *a, int *b);int main(void) {int a = 10;int b = 20;cout << "交换前的值" << endl;cout << "a = " << a << endl;cout << "b = " << b << endl;swap(a, b);cout << "交换后的值" << endl;cout << "a = " << a << endl;cout << "b = " << b << endl;return 0;
    }void swap(int *a, int *b) {int temp;temp = *a;*a = *b;*b = temp;
    }
    
  • 引用调用(&x,&y)
    • 将引用的地址复制给形式参数,在函数内,引用用于访问调用中要用到的实际参数
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>using namespace std;void swap1(int &x, int &y);void swap2(int &x, int &y);
    void swap3(int &x, int &y);int main(void) {int x = 10;int y = 20;cout << "swap1交换前的值" << endl;cout << "x = " << x << endl;cout << "y = " << y << endl;swap1(x, y);cout << "swap1交换后的值" << endl;cout << "x = " << x << endl;cout << "y = " << y << endl;cout << "swap2交换前的值" << endl;cout << "x = " << x << endl;cout << "y = " << y << endl;swap2(x, y);cout << "swap2交换后的值" << endl;cout << "x = " << x << endl;cout << "y = " << y << endl;cout << "swap3交换前的值" << endl;cout << "x = " << x << endl;cout << "y = " << y << endl;swap3(x, y);cout << "swap3交换后的值" << endl;cout << "x = " << x << endl;cout << "y = " << y << endl;return 0;
    }void swap1(int &x, int &y) {int temp;temp = x;x = y;y = temp;
    }void swap2(int &x, int &y) {int temp;temp = x ^ y;x = temp ^ x;y = temp ^ y;
    }
    void swap3(int &x, int &y) {x^=y^=x^=y;
    }

5.5参数的默认值

  • 当定义函数时,可以为参数列表中的每一个参数都指定默认值,当调用函数时,若实际的参数值为空,则使用这个默认值

  • 调用函数时,若未传递参数的值,则会使用默认值,若指定了值,则会忽略默认值,使用传递的值

    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>using namespace std;int sum(int x, int y = 20) {int result;result = x + y;return (result);
    }int main(void) {int a =100;int b =200;int result;//不能声明函数,需要将函数放在main函数前result = sum(a,b);cout << "result = " << result << endl;result = sum(a);cout << "result = " << result << endl;return 0;
    }

5.6Lambda函数与表达式

  • Lambda 表达式把函数看作对象,Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值
  • 语法:
    • 有返回值:[capture](parameters)->return-type{...}
    • 无返回值:[capture](parameters){...}
  • [capture]:捕获子句,用于指定如何在lambda内部访问外部变量。可以是值捕获、引用捕获或默认捕获([]&=)。
  • (parameters):参数列表,可以是空的,如果lambda不需要参数。
  • -> return-type:返回类型。如果所有返回语句都返回相同的类型,或者没有返回语句,可以指定返回类型。在C++14及以后的版本中,可以省略返回类型,让编译器自动推断。
  • {...}:函数体,包含lambda表达式的代码。

  • []:默认不捕获任何变量
  • [=]:默认以值捕获所有变量
  • [&]:默认以引用捕获所有变量
  • [x]:仅以值捕获x,其它变量不捕获;
  • [&x]:仅以引用捕获x,其它变量不捕获;
  • [=, &x]:默认以值捕获所有变量,但是x是例外,通过引用捕获;
  • [&, x]:默认以引用捕获所有变量,但是x是例外,通过值捕获;
  • [this]:通过引用捕获当前对象(其实是复制指针);
  • [*this]:通过传值方式捕获当前对象;

  • 有/无参数、有/无捕获、值捕获、引用捕获、默认捕获、有/无返回值
//
// Created by 16690 on 2024/4/18.
//
#include <iostream>using namespace std;int main(void) {//无参数,无捕获auto lambda1 = []() {cout << "无参数,无捕获" << endl;};//有参数,无捕获auto lambda2 = [](int x, int y) {cout << "x+y=" << x + y << endl;cout << "有参数,无捕获" << endl;};//有参数,无捕获auto lambda3 = [](int x, int y = 20) {cout << "x+y=" << x + y << endl;cout << "有参数,无捕获" << endl;};//值捕获int result1 = 10;auto lambda4 = [result1](int x) {cout << "值捕获" << endl;return result1 * x;};//值捕获int result2;auto lambda5 = [result2 = 20](int x) {cout << "值捕获" << endl;return result2 * x;};//引用捕获,有返回值int result3 = 10;auto lambda6 = [&]() {result3 = 99;};//默认捕获class MyClass {public:int value;MyClass(int val) : value(val) {}void getLambda() {auto lambda = [this]() {this->value *= 2;};//调用lambda表达式lambda();}};//泛型lambda (c++14引入)// auto lambda = [](auto x, auto y) {//     return x + y;// };lambda1(); lambda2(1, 2);lambda3(1);cout << lambda4(2) << endl;cout << lambda5(2) << endl;cout << result3 << endl;lambda6();cout << result3 << endl;MyClass myClass(10);myClass.getLambda();cout << myClass.value << endl;return 0;
}
  1. 无参数,无捕获

    auto noParamNoCapture = []() {return 42;
    };
    
  2. 有参数,无捕获

    auto withParamsNoCapture = [](int x, int y) {return x + y;
    };
    
  3. 无参数,值捕获

    int a = 10;
    auto noParamValueCapture = [a]() {return a * 2;
    };
    
  4. 无参数,引用捕获

    int b = 20;
    auto noParamRefCapture = [&b]() {b *= 2;return b;
    };
    
  5. 默认捕获(所有外部变量以值捕获)

    int c = 30;
    auto defaultCaptureByValue = [=]() {int localC = c; // 值捕获变量creturn localC;
    };
    
  6. 默认捕获(所有外部变量以引用捕获)

    auto defaultCaptureByRef = [&]() {int localC = c; // 引用捕获变量cc = 50; // 修改外部变量creturn localC;
    };
    
  7. 有参数,值捕获

    int x = 5;
    auto withParamsValueCapture = [x](int y) {return x + y;
    };
    
  8. 有参数,引用捕获

    int y = 3;
    auto withParamsRefCapture = [&](int z) {y += z;return y;
    };
    
  9. 捕获列表中有显式值捕获和引用捕获

    int a = 1, b = 2;
    auto mixedCapture = [a, &b]() {return a + b;
    };
    
  10. 有返回值的lambda

    auto lambdaWithReturn = [](int x) -> int {return x * x;
    };
    
  11. 无返回值的lambda(在C++14及以后,可以省略返回类型):

    auto lambdaWithoutReturn = [](int x) {// 执行操作,但不返回任何值
    };
    
  12. 泛型lambda(C++14引入)

    auto genericLambda = [](auto x, auto y) {return x + y;
    };
    
  13. 使用this指针的lambda(在类的成员函数中):

    class MyClass {
    public:void someMethod() {auto lambda = [this]() {this->someOtherMethod();};}void someOtherMethod() {}
    };
    
  14. lambda作为函数参数

    void doSomething(auto lambda) {lambda();
    }
    
  15. lambda作为函数返回值

    auto makeLambda() -> auto {return [](int x) { return x * 2; };
    }
    
  16. 带有异常处理的lambda

    auto lambdaWithException = [](int x) -> int {if (x < 0) throw std::runtime_error("Negative value");return x * x;
    };
    

6.C++数字

6.1C++定义数字

//
// Created by 16690 on 2024/4/19.
//
#include <iostream>using namespace std;int main(void) {// 数字定义short s;int i;long l;float f;double d;// 数字赋值s = 10;i = 1000;l = 1000000;f = 230.47;d = 30949.374;// 数字输出cout << "short  s :" << s << endl;cout << "int    i :" << i << endl;cout << "long   l :" << l << endl;cout << "float  f :" << f << endl;cout << "double d :" << d << endl;return 0;
}

6.2C++内置数学函数

序号函数 & 描述
1double cos(double); 该函数返回弧度角(double 型)的余弦。
2double sin(double); 该函数返回弧度角(double 型)的正弦。
3double tan(double); 该函数返回弧度角(double 型)的正切。
4double log(double); 该函数返回参数的自然对数。
5double pow(double, double); 假设第一个参数为 x,第二个参数为 y,则该函数返回 x 的 y 次方。
6double hypot(double, double); 该函数返回两个参数的平方总和的平方根,也就是说,参数为一个直角三角形的两个直角边,函数会返回斜边的长度。
7double sqrt(double); 该函数返回参数的平方根。
8int abs(int); 该函数返回整数的绝对值。
9double fabs(double); 该函数返回任意一个浮点数的绝对值。
10double floor(double); 该函数返回一个小于或等于传入参数的最大整数。

6.3C++随机数

  • 先调用srand()函数设置随机种子,然后调用rand()函数返回一个伪随机数

  • 生成指定区间内的随机数

    rand()%(m-1+n)%m
//
// Created by 16690 on 2024/4/19.
//
#include <iostream>
#include <ctime>
#include <cstdlib>using namespace std;int main(void) {int x;//设置种子//通过系统时间作为随机种子,防止随机生成的数字相同srand((unsigned)time (NULL));//生成10个随机数for(int i=0;i<10;i++){//生成实际的随机数x=rand();cout << "随机数=" << x << endl;//输出1-100的随机数:rand()%(m-1+n)+m;int num = rand()%(1-1+100)+1;cout << "模除+加法的随机数=" << num << endl;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux驱动开发笔记(零)驱动基础知识及准备

文章目录 前言一、Liunx、MCU和FPGA编程的区别二、Linux内核模块1. 什么是内核模块2. 内核模块的代码架构3. 头文件4. 模块参数5. makefile说明 三、 驱动程序设计思路1. 基本步骤2. 设备号3. 数据结构3.1 file_operations3.2 file3.3 inode3.4 哈希表3.5 cdev结构体3.6 kobj_m…

[Linux][进程信号][一][信号基础][如何产生信号]详细解读

目录 0.前言预备1.系统定义的信号列表2.核心转储 -- Core Dump 1.信号基础1.信号概念2.信号处理方式概览3.理解信号如何被保存4.信号发送的本质 2.如何产生信号&#xff1f;1.终端按键产生信号2.系统调用接口1.kill()2.raise()3.abort()4.如何理解&#xff1f; 3.由软件条件产生…

将闲置的windows硬盘通过smb共享的方式提供给mac作为时间机器备份

1.windows端&#xff0c;开启smb共享 自行解决 2.mac端 磁盘工具-文件-新建映像-空白映像 假设你的名字为&#xff1a;backup 大小&#xff1a;350GB&#xff08;自己修改&#xff09; 格式&#xff1a;MacOS扩展&#xff08;日志式&#xff09; 分区&#xff1a;单个分区-A…

C# 图像旋转一定角度后,对应坐标怎么计算?

原理分析 要计算图像内坐标在旋转一定角度后的新坐标&#xff0c;可以使用二维空间中的点旋转公式。假设图像的中心点&#xff08;即旋转中心&#xff09;为 (Cx, Cy)&#xff0c;通常对于正方形图像而言&#xff0c;中心点坐标为 (Width / 2, Height / 2)。给定原坐标点 (X, …

开发与产品的战争之自动播放视频

开发与产品的战争之自动播放视频 起因 产品提了个需求&#xff0c;对于网站上的宣传视频&#xff0c;进入页面就自动播放。但是基于我对chromium内核的一些浅薄了解&#xff0c;我当时就给拒绝了: “浏览器不允许”。&#xff08;后续我们浏览器默认都是chromium内核的&#…

【深度学习】Vision Transformer

一、Vision Transformer Vision Transformer (ViT)将Transformer应用在了CV领域。在学习它之前&#xff0c;需要了解ResNet、LayerNorm、Multi-Head Self-Attention。 ViT的结构图如下&#xff1a; 如图所示&#xff0c;ViT主要包括Embedding、Encoder、Head三大部分。Class …

K8s: 运行Pod时的root用户和非root用户的安全相关配置

关于 root 用户 1 &#xff09;概述 docker 容器运行起来&#xff0c;默认是 root 用户这样运行起来后&#xff0c;基本不会遇到权限相关问题带来的问题是: 权限过大&#xff0c;被攻击后会遇到严峻挑战基于这个问题&#xff0c;K8s提出了特权用户的概念在容器启动时&#xff…

Javascript 中 package.json 和 package-lock.json 有什么区别呢

package.json 和 package-lock.json 文件都是 Node.js 项目中的重要组成部分&#xff0c;但它们的作用不同。以下是它们之间的主要区别&#xff1a; 作用: package.json: 这个文件主要用于管理和记录关于项目的元数据&#xff0c;包括项目的名称、版本、作者、依赖项、脚本和…

OpenHarmony鸿蒙南向开发案例:【智能燃气检测设备】

样例简介 本文档介绍了安全厨房案例中的相关智能燃气检测设备&#xff0c;本安全厨房案例利用轻量级软总线能力&#xff0c;将两块欧智通V200Z-R/BES2600开发板模拟的智能燃气检测设备和燃气告警设备组合成。当燃气数值告警时&#xff0c;无需其它操作&#xff0c;直接通知软总…

VOS3000加装登陆服务器安全防护系统有用吗

VOS3000是一款专业的软交换系统&#xff0c;它主要用于中小规模的VoIP运营业务&#xff0c;包括运营费率设定、套餐管理&#xff0c;账户管理、业终端管理、网关管理、数据查询、卡类管理、号码管理、系统管理等功能1。而关于加装登陆服务器安全防护系统是否有用&#xff0c;这…

Multi-granularity Correspondence Learning from Long-term Noisy Videos--论文笔记

解决在视频语言学习中&#xff0c;如何有效地从长期&#xff08;long-term&#xff09;且带有噪声的视频数据中学习时间上的对应关系&#xff08;temporal correspondence&#xff09;。 噪声对应学习&#xff08;Noisy Correspondence Learning&#xff09;是指在处理视频和文…

2.4 Web容器配置:Tomcat

2.4 Web容器配置 2.4.1Tomcat配置1.常规配置2. HTTPS配置 *********** 2.4.1Tomcat配置 1.常规配置 在SpringBoot项目中&#xff0c;可以内置Tomcat、Jetly、Undertow、Netty等容器。 当开发者添加了spring-boot-starter-web依赖之后&#xff0c;默认会使用Tomcat作为Web容器…

基于Springboot+Vue的Java项目-网上点餐系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

【EdgeBox-8120AI-TX2】Ubuntu18.04 + ROS_ Melodic + 星秒PAVO2单线激光 雷达评测

大家好&#xff0c;我是虎哥&#xff0c;好久不见&#xff0c;最近这断时间出现了一点变故&#xff0c;开始自己创业&#xff0c;很多事需要忙&#xff0c;所以停更了大约大半年&#xff0c;最近一切已经理顺&#xff0c;所以我还是抽空继续我之前的FLAG&#xff0c;CSDN突破十…

牛客NC314 体育课测验(一)【中等 图,BFS,拓扑排序 Java,Go、PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/1a16c1b2d2674e1fb62ce8439e867f33 核心 图&#xff0c;BFS,拓扑排序&#xff0c;队列参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修…

数据库——实验9 存储过程的使用

1. 存储过程的定义 存储过程是一系列预先编辑好的、能实现特定数据操作功能的SQL 代码集&#xff0c;它与特定的数据库相关联&#xff0c;存储在SQL Server服务器上。用户可以像使用自定义的函数一样重复调用这些存储过程&#xff0c;实现它所定义的操作。 2. 存储过程的类型…

A26 STM32_HAL库函数 之 IRDA通用驱动 -- A -- 所有函数的介绍及使用

A26 STM32_HAL库函数 之 IRDA通用驱动 -- A -- 所有函数的介绍及使用 1 该驱动函数预览1.1 HAL_IRDA_Init1.2 HAL_IRDA_DeInit1.3 HAL_IRDA_MspInit1.4 HAL_IRDA_MspDeInit1.5 HAL_IRDA_Transmit1.6 HAL_IRDA_Receive1.7 HAL_IRDA_Transmit_IT1.8 HAL_IRDA_Receive_IT1.9 HAL_I…

后台管理系统加水印(react)

效果 代码图片 代码 window.waterMark function (config) {var defaultConfig {content: 我是水印,fontSize: 16px,opacity: 0.3,rotate: -15,color: #ADADAD,modalId: J_waterMarkModalByXHMAndDHL,};config Object.assign({}, defaultConfig, config);var existMarkModal…

镜舟科技荣获金科创新社 2024 年度金融数据智能解决方案奖

近日&#xff0c; 镜舟科技凭借领先的金融实时数仓构建智能经营解决方案&#xff0c;在“金科创新社第六届金融数据智能优秀解决方案评选”活动中&#xff0c;成功入选“数据治理与数据平台创新优秀解决方案”榜单。 金科创新社主办的“鑫智奖”评选活动&#xff0c;旨在展示…

【解决】Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed

问题原因&#xff1a; 在Java8及高版本以上的版本在源应用程序不信任目标应用程序的证书&#xff0c;因为在源应用程序的JVM信任库中找不到该证书或证书链。也就是目标站点启用了HTTPS 而缺少安全证书时出现的异常 解决方案&#xff1a; 我使用的是忽略证书验证 public clas…