# C++ 基础篇

# 变量

变量是程序中用于存储数据的地方。变量的类型决定了变量可以存储的数据类型,以及变量的操作可以进行的操作。

c++变量声明
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10;
    // using namespace std, we can access cout and endl directly
    // 打印变量 a 的值
    cout << "A = " << a << endl;
}

# 常量

常量是固定值,不能被修改的变量,常量通常用大写字母表示。

  • 常量声明有两种方式:
      1. 宏常量 :使用 #define 关键字定义,通常定义在文件头部。
      1. 常量声明 :使用 const 关键字定义。
c++常量声明一
#include <iostream>
// declaring namespace std
using namespace std;
//defining macro day, 定义宏常量使用 #define 关键字,通常定义在文件头部
#define Day 1
int main() {
    // using namespace std, we can access cout and endl directly
    // 打印 Day 宏常量的值
    cout << "Day = " << Day << endl;
}
c++常量声明二
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    //const 修饰的变量
    const int month = 12;
    //a = 20; // 编译错误,常量不能被修改
    cout << "一年有多少个月份 "<< month << endl; // 输出 10
}

pVA50uq.jpg

# 关键字

  • 关键字: C++ 语言中具有特殊含义的单词,不能用作 变量名常量名函数名 等。
  • 关键字列表:
    • auto :声明变量类型,只能用于局部变量。
    • break :跳出循环。
    • case :选择语句中的一个分支。
    • char :字符类型。
    • const :常量。
    • continue :继续下一轮循环。
    • default :选择语句中的默认分支。
    • do-while :循环语句。
    • double :双精度浮点数类型。
    • else :条件语句中的否定分支。
    • enum :枚举类型。
    • extern :声明变量在其他文件中。
    • float :单精度浮点数类型。
    • for :循环语句。
    • goto :无条件跳转语句。
    • if-else :条件语句。
    • int :整数类型。
    • long :长整数类型。
    • register :声明变量在寄存器中。
    • return :函数返回语句。
    • short :短整数类型。
    • signed :有符号整数类型。
    • sizeof :获取变量或类型大小。
    • static :声明静态变量。
    • struct :结构类型。
    • switch :选择语句。
    • typedef :给类型定义一个新的名称。
    • union :联合类型。
    • unsigned :无符号整数类型。
    • void :空类型。
    • volatile :声明变量易变。
    • while :循环语句。
asmdoifreturntypedef
autodoubleinlineshorttypeid
booldynamic_castintsignedtypename
breakelselongsizeofunion
caseenummutablestaticunsigned
catchexplicitnamespacestatic_castusing
charexportnewstructvirtual
classexternoperatorswitchvoid
constfalseprivatetemplatevolatile
const_castfloatprotectedthiswchar_t
continueforpublicthrowwhile
defaultfriendregistertrue
deletegotoreinterprettry

# 标识符命名规则

  • 标识符:程序中用于表示 变量常量函数命名空间 等名称的符号。
  • 命名规则:
    1. 标识符只能由字母、数字和下划线组成,且不能以数字开头。
    2. 标识符不能是 C++ 关键字。
    3. 标识符的长度不超过 31 个字符。
    4. 标识符的命名应易于理解,不要使用拼音、缩写、数字代替英文单词。

# 数据类型

数据类型是程序中用于存储数据的形式,决定了变量可以存储的数据类型,以及变量的操作可以进行的操作。

  • 数据类型分类:
    1. 整型:整数类型,包括 charshortintlonglong long
    2. 浮点型:小数类型,包括 floatdouble
    3. 字符型: char 类型,包括 charwchar_t
    4. 布尔型: bool 类型。
    5. 指针型:指针类型。
    6. 数组型:数组类型。
    7. 枚举型:枚举类型。
    8. 结构型:结构类型。
    9. 共用体型:共用体类型。
    10. 联合型:联合类型。
    11. 虚基类型:虚基类类型。
    12. 其他类型: void 类型。

# 声明

  • 声明:在程序中声明变量或函数,说明变量或函数的类型、名称、作用域、属性等。
  • 语法: 类型 变量名 = 值;
    • 注意:声明时,类型必须与变量实际存储的数据类型一致。
  • 作用域:声明的变量或函数的作用域决定了变量或函数的可见性和生命周期。
  • 属性:
    1. 全局变量 :全局变量在整个程序中都可以访问,生命周期从程序开始到程序结束。
    2. 局部变量 :局部变量在函数或块作用域中可以访问,生命周期从声明到函数或块结束。
    3. 静态变量 :静态变量在整个程序中只初始化一次,生命周期从程序开始到程序结束。
    4. 常量 :常量的值不能被修改。
c++数据类型声明
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 全局变量
    int a = 10;
    // 局部变量
    int b;
    b = 20;
    // 静态变量
    static int c = 30;
    // 常量
    const int d = 40;
    // 打印变量的值
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;
    cout << "d = " << d << endl;
    return 0;
}

# 整型

  • 整型 :整数类型,包括 charshortintlonglong long
  • 整型范围:
    • char-128~127
    • short-32768~32767
    • int-2147483648~2147483647
    • long-9223372036854775808~9223372036854775807
    • long long-18446744073709551616~18446744073709551615
  • 整型默认值:
    • char0
    • short0
    • int0
    • long0
    • long long0
  • 整型大小:
    • char1字节
    • short2字节
    • int4字节
    • long4字节
    • long long8字节
  • 整型声明:
      1. 声明变量: 类型 变量名 = 值;
      1. 声明多个变量: 类型 变量名1 = 值1, 变量名2 = 值2;
      1. 声明指针变量: 类型 *变量名 = &变量名;
      1. 声明常量: const 类型 变量名 = 值;
c++整型声明
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 声明变量
    int a = 10;
    // 声明多个变量
    int b = 20, c = 30;
    // 声明指针变量
    int *d = &a;
    // 声明常量
    const int e = 40;
    // 打印变量的值
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;
    cout << "d = " << *d << endl;
    cout << "e = " << e << endl;
    return 0;
}

# sizeof 关键字

  • sizeof 关键字:获取变量或类型大小。
  • 语法: sizeof(类型或变量名)
  • 注意: sizeof 关键字返回的是字节数,而不是单位。
c++_sizeof关键字
#include <iostream>
// declaring namespace std  
using namespace std;  
int main() {  
    int a = 10;  
    double b = 20.5;  
    // 打印变量 a 的大小  
    cout << "a的大小为:" << sizeof(a) << "字节" << endl;  
    // 打印变量 b 的大小  
    cout << "b的大小为:" << sizeof(b) << "字节" << endl;  
    return 0;  
}

# 浮点型

  • 浮点型 :小数类型,包括 floatdouble
  • 浮点型范围:
  • float-3.40282347e+38~3.40282347e+38
  • double-1.7976931348623157e+308~1.7976931348623157e+308
  • 浮点型默认值:
    • float0.0
    • double0.0
  • 浮点型大小:
    • float4字节
    • double8字节
  • 浮点型声明:
    1. 声明变量类型 变量名 = 值;
    2. 声明多个变量类型 变量名1 = 值1, 变量名2 = 值2;
    3. 声明指针变量类型 *变量名 = &变量名;
    4. 声明常量const 类型 变量名 = 值;
c++浮点型声明
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 声明变量
    float a = 3.14f;
    // 声明多个变量
    double b = 20.5, c = 30.5;
    // 声明指针变量
    double *d = &a;
    // 声明常量
    const double e = 40.5;
    // 打印变量的值
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;
    cout << "d = " << *d << endl;
    cout << "e = " << e << endl;
    
     // 科学计数法输出
    float f2 = 3e2; // 3 * 10^2
    cout << "f2 = " << f2 << endl;
    double d2 = 3e-2; // 3 * 10^-2
    cout << "d2 = " << d2 << endl;
    
    return 0;
}

# 字符型

  • 字符型char 类型,包括 charwchar_t
  • 字符型范围:
    • char-128~127
    • wchar_t-32768~32767
  • 字符型默认值:
    • char'\0'
    • wchar_t'\0'
  • 字符型大小:
    • char1字节
    • wchar_t2字节
  • 字符型声明:
    1. 声明变量类型 变量名 = 值;
    2. 声明多个变量类型 变量名1 = 值1, 变量名2 = 值2;
    3. 声明指针变量类型 *变量名 = &变量名;
    4. 声明常量const 类型 变量名 = 值;
c++字符型声明
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 声明变量
    char a = 'a';
    // 声明多个变量
    char b = 'b', c = 'c';
    // 声明指针变量
    char *d = &a;
    // 声明常量
    const char e = 'e';
    // 打印变量的值
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;
    cout << "d = " << *d << endl;
    cout << "e = " << e << endl;
    return 0;
}

# 转义字符

  • 转义字符:在 C++ 中,有一些字符需要用反斜杠进行转义,以表示其特殊含义。
  • 转义字符列表:
    • \n换行符
    • \t制表符
    • \\反斜杠
    • \'单引号
    • \"双引号
    • \?问号
    • \a响铃
    • \b退格
    • \f换页
    • \r回车
    • \v垂直制表符
c++转义字符
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 输出换行符
    cout << "Hello\nWorld" << endl;
    // 输出制表符
    cout << "Hello\tWorld" << endl;
    // 输出反斜杠
    cout << "Hello\\World" << endl;
    // 输出单引号
    cout << "Hello'World" << endl;
    // 输出双引号
    cout << "Hello\"World" << endl;
    // 输出问号
    cout << "Hello?World" << endl;
    // 输出响铃
    cout << "Hello\aWorld" << endl;
    // 输出退格
    cout << "Hello\bWorld" << endl;
    // 输出换页
    cout << "Hello\fWorld" << endl;
    // 输出回车
    cout << "Hello\rWorld" << endl;
    // 输出垂直制表符
    cout << "Hello\vWorld" << endl;
    return 0;
}

# 字符串类型

  • 字符串类型char 类型数组,以 '\0' 结尾。
  • 字符串类型声明:
      1. 声明变量char 变量名[] = "值";
      1. 声明指针变量char *变量名 = "值";
      1. 声明常量const char 变量名[] = "值";
  • C++11 新增了一种字符串类型: std::string ,可以自动管理内存,使用方便。
  • C 风格字符串: char str[] = "Hello World";
  • C++ 风格字符串: std::string str = "Hello World";
  • 注意:
    • C++ 风格字符串可以自动管理内存,不需要手动释放内存。
    • C++ 风格字符串可以直接输出,不需要使用 cout << str << endl;
c++字符串类型
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 声明变量
    char str1[] = "Hello World";
    // 声明指针变量
    char *str2 = "Hello World";
    // 声明常量
    const char str3[] = "Hello World";
    // 打印变量的值
    cout << "str1 = " << str1 << endl;
    cout << "str2 = " << str2 << endl;
    cout << "str3 = " << str3 << endl;
    // C++11 新增的字符串类型
    string str4 = "Hello World";
    // 打印变量的值
    cout << "str4 = " << str4 << endl;
    return 0;
}

# 布尔类型

  • 布尔类型bool 类型,只有 truefalse 两个值。
  • 布尔类型声明:
      1. 声明变量: bool 变量名 = 值;
      1. 声明指针变量: bool *变量名 = &变量名;
      1. 声明常量: const bool 变量名 = 值;
c++布尔类型
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 声明变量
    bool a = true;
    // 声明指针变量
    bool *b = &a;
    // 声明常量
    const bool c = false;
    // 打印变量的值
    cout << "a = " << a << endl;
    cout << "b = " << *b << endl;
    cout << "c = " << c << endl;
    return 0;
}

# 数据的输入

  • 输入数据:
    - cin :从标准输入设备(键盘)读取数据。
    • getline :从标准输入设备(键盘)读取一行数据。
    • get :从标准输入设备(键盘)读取一个字符。
  • 输出数据:
    • cout :输出到标准输出设备(屏幕)。
    • put :输出到标准输出设备(屏幕)。
    • putchar :输出到标准输出设备(屏幕)。
c++数据的输入输出
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 输入数据
    int a;
    double b;
    char c;
    string d;
    // 输出数据
    cout << "请输入整数a:" << endl;
    // 读取输入数据
    cin >> a;
    cout << "请输入小数b:" << endl;
    cin >> b;
    cout << "请输入字符c:" << endl;
    cin >> c;
    cout << "请输入字符串d:" << endl;
    cin >> d;
    // 输出数据
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;
    cout << "d = " << d << endl;
    return 0;
}

# 运算符

# 加减乘除

  • 加法运算符: +
  • 减法运算符: -
  • 乘法运算符: *
  • 除法运算符: /
  • 取余运算符: %
c++算术运算符
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 5;
    // 加法运算
    int c = a + b;
    cout << "a + b = " << c << endl;
    // 减法运算
    int d = a - b;
    cout << "a - b = " << d << endl;
    // 乘法运算
    int e = a * b;
    cout << "a * b = " << e << endl;
    // 除法运算
    int f = a / b;
    cout << "a / b = " << f << endl;
    // 取余运算
    int g = a % b;
    cout << "a % b = " << g << endl;
    return 0;
}

# 取余运算符

  • 取余运算符: %
  • 语法: a % b
  • 功能:求 a 除以 b 的余数,即 a - b * (a / b)
  • 特别注意:
    • 取余运算符的结果是整数,向零取整。
    • 取余运算符的结果是负数,表示 b 大于 a
c++取余运算符
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 5;
    // 取余运算
    int c = a % b;
    cout << "a % b = " << c << endl;
    return 0;
}

# 自增自减运算符

  • 自增运算符: ++
  • 自减运算符: --
  • 语法: 变量名++变量名--
  • 功能:
    • 自增运算符先将变量的值加1,然后再返回变量的值
    • 自减运算符先将变量的值减1,然后再返回变量的值
c++自增自减运算符
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 5;
    // 自增运算
    a++;
    cout << "a = " << a << endl;
    b--;
    cout << "b = " << b << endl;
    return 0;
}
  • 注意:
    • 自增自减运算符只能作用于变量,不能作用于常量。
    • 自增自减运算符只能作用于整型变量。
    • 自增自减运算符只能作用于变量,不能作用于表达式。
c++自增自减运算符注意事项
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    const int a = 10;
    // 自增运算
    a++; // 错误,不能作用于常量
    cout << "a = " << a << endl;
    return 0;
}
  • 自增自减运算符的前后顺序:
    • 前置++变量名--变量名
    • 后置变量名++变量名--
c++自增自减运算符的前后顺序
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 5;
    // 前置自增运算
    ++a;
    cout << "a = " << a << endl;
    // 后置自增运算
    b = b++;
    cout << "b = " << b << endl;
    // 前置自减运算
    --a;
    cout << "a = " << a << endl;
    // 后置自减运算
    b = b--;
    cout << "b = " << b << endl;
    return 0;
}

# 赋值运算符

  • 赋值运算符: =
  • 语法: 变量名 = 值
  • 功能:将右侧的值赋给左侧的变量。
c++赋值运算符
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 5;
    // 赋值运算
    a = b;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    return 0;
}

# 关系运算符

  • 关系运算符:
    • ==等于
    • !=不等于
    • >大于
    • <小于
    • >=大于等于
    • <=小于等于
c++关系运算符
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 5;
    // 关系运算
    bool c = (a == b);
    cout << "a == b = " << c << endl;
    c = (a != b);
    cout << "a != b = " << c << endl;
    c = (a  > b);
    cout << "a  > b = " << c << endl;
    c = (a  < b);
    cout << "a  < b = " << c << endl;
    c = (a >= b);
    cout << "a >= b = " << c << endl;
    c = (a <= b);
    cout << "a <= b = " << c << endl;
    return 0;
}

# 逻辑运算符

  • 逻辑运算符:
    • &&逻辑与
    • ||逻辑或
    • !逻辑非
  • 语法:
    • 逻辑与表达式1 && 表达式2
    • 逻辑或表达式1 || 表达式2
    • 逻辑非!表达式
  • 功能:
    • 逻辑与只有两个表达式都为真,结果才为真
    • 逻辑或只要两个表达式有一个为真,结果就为真
    • 逻辑非取反,如果表达式为真,结果为假;如果表达式为假,结果为真
c++逻辑运算符
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 5;
    // 逻辑运算
    bool c = (a == b) && (a > b);
    cout << "a == b && a > b = " << c << endl;
    c = (a != b) || (a < b);
    cout << "a != b || a < b = " << c << endl;
    c =!(a == b);
    cout << "!a == b = " << c << endl;
    const int d = 10;
    cout << !!d << endl; // 可以使用逻辑运算符!!对常量进行取反操作
    return 0;
}
c++逻辑运算符短路特性
#include <iostream>
// declaring namespace std
using namespace std;
int main() {    
    int a = 10, b = 5;
    // 逻辑与短路特性
    bool c = (a == b) && (a > b);
    cout << "a == b && a > b = " << c << endl;
    c = (a != b) || (a < b);
    cout << "a != b || a < b = " << c << endl;
    c =!(a == b);
    cout << "!a == b = " << c << endl;
    const int d = 10;
    cout << !!d << endl; // 可以使用逻辑运算符!!对常量进行取反操作
    return 0;
}

# 位运算符

  • 位运算符:
    • & :按位与。
    • | :按位或。
    • ^ :按位异或。
    • ~ :按位取反。
    • << :左移。
    • >> :右移。
  • 语法:
    • &变量1 & 变量2
    • |变量1 | 变量2
    • ^变量1 ^ 变量2
    • ~~变量
    • <<变量 << 位数
    • >>变量 >> 位数
  • 功能:
    • & :两个二进制位都为 1 时,结果才为 1。
    • | :两个二进制位中只要有一个为 1,结果就为 1。
    • ^ :两个二进制位不同时为 1,结果才为 1。
    • ~ :对二进制位取反,即 0 变 1,1 变 0。
    • << :将二进制位向左移动指定的位数。
    • >> :将二进制位向右移动指定的位数。
c++位运算符
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 5;
    // 位运算
    int c = a & b;
    cout << "a & b = " << c << endl;
    c = a | b;
    cout << "a | b = " << c << endl;
    c = a ^ b;
    cout << "a ^ b = " << c << endl;
    c = ~a;
    cout << "~a = " << c << endl;
    c = a << 2;
    cout << "a << 2 = " << c << endl;
    c = a >> 2;
    cout << "a >> 2 = " << c << endl;
    return 0;
}

# 程序流程结构

  • C/C++ 支持最基本的三种程序流程结构:顺序结构、分支结构、循环结构。
    • 顺序结构:从上到下依次执行语句。
    • 分支结构:选择执行。
    • 循环结构:重复执行。
  • 顺序结构:
    • 语法: {语句1; 语句2; ...; 语句n;}
    • 功能:从上到下依次执行语句。
c++顺序结构示例
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 5;
    // 顺序结构
    {
        int c = a + b;
        cout << "a + b = " << c << endl;
    }
    cout << "b = " << b << endl;
    return 0;
}

# 单行 if 语句

  • 语法: if(条件表达式){语句}
  • 功能:如果条件表达式为真,则执行语句。
c++单行if语句
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int Language, Mathematics;
    cout << "请输入语文成绩:"<< endl;
    // 获取输入
    cin >> Language;
    cout << "请输入数学成绩:"<< endl;
    cin >> Mathematics;
    if (Language >= 60 && Mathematics >= 60) {
        cout << "你通过了本次考试!" << endl;
    } else {
        cout << "你未通过本次考试!" << endl;
    }
    return 0;
}

# 多行 if 语句

  • 语法: if(条件表达式){语句1}else{语句2}
  • 功能:如果条件表达式为真,则执行语句 1;否则执行语句 2。
c++多行if语句
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 总分
    int score = 0;
    cout << "请输入一个考试分数:" << endl;
    // 获取输入的分数
    cin >> score;
    // 判断分数是否合法
    if (score >= 600) {
        cout << "恭喜你通过了考试!" << endl;
    }else {
        cout << "很遗憾,你未能通过考试!" << endl;
    }
    return 0;
}

# 多条件 if 语句

  • 语法: if(条件表达式1){语句1}else if(条件表达式2){语句2}...else{语句n}
  • 功能:从上到下依次判断条件表达式,如果第一个表达式为真,则执行第一个语句;如果第一个表达式为假,则判断第二个表达式,如果第二个表达式为真,则执行第二个语句;以此类推,直到找到真值表达式,执行对应的语句。
c++多条件if语句
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 总分
    int score = 0;
    cout << "请输入一个考试分数:" << endl;
    // 获取输入的分数
    cin >> score;
    // 判断分数是否合法
    if (score >= 90) {
        cout << "恭喜你通过了考试!" << endl;
    } else if (score >= 80) {
        cout << "你通过了本次考试!" << endl;
    } else if (score >= 60) {
        cout << "你及格了!" << endl;
    } else {
        cout << "很遗憾,你未能通过考试!" << endl;
    }
    return 0;
 
    // 输出结果:
    // 请输入一个考试分数:
    // 85
    // 你通过了本次考试!
}

# 嵌套 if 语句

  • 语法: if(条件表达式1){语句1}else if(条件表达式2){语句2}...else{语句n}
  • 功能:从上到下依次判断条件表达式,如果第一个表达式为真,则执行第一个语句;如果第一个表达式为假,则判断第二个表达式,如果第二个表达式为真,则执行第二个语句;以此类推,直到找到真值表达式,执行对应的语句。
c++嵌套if语句
// 嵌套 if 语句
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 总分
    int score = 0;
    cout << "请输入一个考试分数:" << endl;
    // 获取输入的分数
    cin >> score;
    // 判断分数是否合法
    if (score >= 90) {
        cout << "恭喜你通过了考试!" << endl;
    } else if (score >= 80) {
        cout << "你通过了本次考试!" << endl;
        if (score >= 85) {
            cout << "你优秀!" << endl;
        } else {
            cout << "你及格了!" << endl;
        }
    } else if (score >= 60) {
        cout << "你及格了!" << endl;
    } else {
        cout << "很遗憾,你未能通过考试!" << endl;
    }
    return 0;
 
    // 输出结果:
    // 请输入一个考试分数:
    // 85
    // 你通过了本次考试!
    // 你优秀!
}

# 三只小猪称重程序

  • 功能:输入三只小猪的体重,判断谁那只小猪最重。
c++三只小猪称重程序
// 三只小猪称重程序,使用多重 if 语句和嵌套 if 语句判断谁那只小猪谁最重
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 三只小猪的体重
    int weight1, weight2, weight3;
    cout << "请输入第一只小猪的体重:" << endl;
    cin >> weight1;
    cout << "请输入第二只小猪的体重:" << endl;
    cin >> weight2;
    cout << "请输入第三只小猪的体重:" << endl;
    cin >> weight3;
    // 三只小猪的重量
    int totalWeight = weight1 + weight2 + weight3;
    // 三只小猪的体重
    cout << "第一只小猪的体重:" << weight1 << endl;
    cout << "第二只小猪的体重:" << weight2 << endl;
    cout << "第三只小猪的体重:" << weight3 << endl;
    // 三只小猪的重量
    cout << "三只小猪的总体重:" << totalWeight << endl;
    // 三只小猪的重量
    if (weight1 > weight2) {// 第一只小猪最重
        if (weight1 > weight3) {// 第一只小猪最重
            cout << "第一只小猪最重!" << endl;
        } else {// 第三只小猪最重
            cout << "第三只小猪最重!" << endl;
        }
    } else {// 第二只小猪最重
        if (weight2 > weight3) {// 第二只小猪最重
            cout << "第二只小猪最重!" << endl;
        } else {// 第三只小猪最重
            cout << "第三只小猪最重!" << endl;
        }
    }
    return 0;
}

# 三目运算符

  • 语法: 表达式1?表达式2:表达式3
  • 功能:如果表达式 1 为真,则返回表达式 2 的值;否则返回表达式 3 的值。
  • 注意:在 C++ 中三目运算符返回的是变量,可以继续赋值
c++三目运算符
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 10, b = 20, c = 0;
    // 三目运算符
    c = (a > b ? a : b);
    cout << "c = " << c << endl;
    // 在 C++ 中三目运算符返回的是变量,可以继续赋值
    (a > b ? a : b) = 100;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    return 0;
}

# switch 语句

  • 语法: switch(表达式){case 常量1:语句1;break;case 常量2:语句2;break;...default:语句n;break;}
  • 功能:根据表达式的值,选择执行对应的语句。
  • 注意:
    • case 后面的常量可以是表达式,也可以是常量。
    • break 语句用于结束当前 case 语句,并开始执行下一个 case 语句。
    • default 语句是可选的,如果没有匹配到任何 case 语句,则执行 default 语句。
c++switch语句
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int grade = 0;
    cout << "请输入您的成绩:" << endl;
    // 获取输入的成绩
    cin >> grade;
    //switch 语句
    switch (grade) {
        case 10:
            cout << "超棒" << endl;
            break;
        case 9:
            cout << "优秀" << endl;
            break;
        case 8:
            cout << "良好" << endl;
            break;
        case 7:
            cout << "及格" << endl;
            break;
        case 6:
            cout << "不及格" << endl;
            break;
        default:
            cout << "输入错误" << endl;
            break;
    }
    return 0;
}

# 循环结构

  • 循环结构:
    • while 循环: while(条件表达式){语句}
    • do-while 循环: do{语句}while(条件表达式)
    • for 循环: for(初始化表达式;条件表达式;循环表达式){语句}
  • 功能:
    • while 循环:当条件表达式为真时,执行语句。
    • do-while 循环:先执行语句,然后判断条件表达式。
    • for 循环:初始化表达式,判断条件表达式,执行语句,循环表达式,直到条件表达式为假。
c++循环结构
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int i = 0;
    //while 循环
    while (i < 5) {
        cout << "i = " << i << endl;
        i++;
    }
    //do-while 循环
    i = 0;
    do {
        cout << "i = " << i << endl;
        i++;
    } while (i < 5);
    //for 循环
    for (int j = 0; j < 5; j++) {
        cout << "j = " << j << endl;
    }
    return 0;
}

# 猜数字游戏

  • 功能:用户输入一个数字,计算机根据提示猜测数字。
c++猜数字游戏
#include <iostream>
// declaring namespace std
using namespace std;
//time 系统时间头文件包含
#include <ctime>
int main() {
    // 添加随机数种子,保证每次运行程序生成的随机数相同
    srand((unsigned int)time(nullptr));
    // 生成随机数
    int random_number = rand() % 100 + 1;
    int user_input;
    while (true){
        cout << "请猜一个数字: ";
        // 获取用户输入
        cin >> user_input;
        // 判断用户输入是否正确
        if (user_input == random_number) {
            cout << "恭喜你,猜对了!" << endl;
        } else if (user_input < random_number) {
            cout << "你猜的数字小了,再接再厉!" << endl;
        } else if (user_input > random_number){
            cout << "你猜的数字大了,再接再厉!" << endl;
        }else {
            cout << "很遗憾,猜错了!正确答案是" << random_number << endl;
            return 0;
        }
    }
}

# do-while 循环

  • 语法: do{语句}while(条件表达式)
  • 功能:先执行语句,然后判断条件表达式。
  • 注意: do-while 循环至少执行一次语句。
c++do-while循环
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int i = 0;
    //do-while 循环
    do {
        cout << "i = " << i << endl;
        i++;
    } while (i < 5);
    //do...while 与 while 的区别在于,do...while 循环至少执行一次语句。
    return 0;
}

# 水仙花数

  • 功能:输入一个 3 位数,判断是否为水仙花数。
  • 水仙花数:一个 n 位数,它的每个位上的数字的 n 次幂之和等于这个数本身。
  • 例如: 153 是一个 3 位数,它的每个位上的数字的 3 次幂之和等于这个数本身,即 1^3 + 5^3 + 3^3 = 153
c++水仙花数
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int num;
    cout << "请输入一个3位数:" << endl;
    cin >> num;
    int gewei = num / 100;
    int shiwei = (num % 100) / 10;
    int baiwei = num % 10;
    int sum = gewei * gewei * gewei + shiwei * shiwei * shiwei + baiwei * baiwei * baiwei;
    if (sum == num) {
        cout << num << "是水仙花数!" << endl;
    } else {
        cout << num << "不是水仙花数!" << endl;
    }
    return 0;
}
  • 使用 do-while 实现水仙花数游戏
c++do-while实现水仙花数游戏
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int num = 100;
    do {
        int gewei = 0;// 个位数
        int shiwei = 0;// 十位数
        int baiwei = 0;// 百位数
        gewei = num % 10;// 取个位数
        shiwei = num / 10 % 10;// 取十位数
        baiwei = num / 100;// 取百位数
        if (gewei * gewei * gewei + shiwei * shiwei * shiwei + baiwei * baiwei * baiwei == num) {
            cout << num << endl;
        }
        num++;
    } while (num < 1000);
    return 0;
}

# for 循环

  • 语法: for(初始化表达式;条件表达式;循环表达式){语句}
  • 功能:初始化表达式,判断条件表达式,执行语句,循环表达式,直到条件表达式为假。
  • 注意:
    • 初始化表达式:在循环开始之前执行一次。
    • 循环表达式:在每次循环结束后执行一次。
    • 条件表达式:循环条件,当其为真时,循环继续,当其为假时,循环结束。
c++for循环
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    for (int i = 0; i < 5; i++) {
        cout << "i = " << i << endl;
    }
    return 0;
}

# 敲桌子游戏

  • 功能:从这 100 个数字中找到特殊数字,改为 “敲桌子:”
  • 特殊数字:
    • 能被 7 整除的数字
    • 能被 10 整除的数字
    • 能被 70 整除的数字
c++敲桌子游戏
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    for (int i = 1; i <= 100; i++) {
        cout << ((i % 10 == 7 || i / 10 == 7 || i % 7 == 0) ? "敲桌子" : to_string(i)) << endl;
    }
    return 0;
}

# 九九乘法表

  • 功能:打印九九乘法表。
c++九九乘法表
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= i; j++) {
            cout << i << "x" << j << "=" << i * j << "\t";
        }
        cout << endl;
    }
    return 0;
}

# 打印矩形

c++打印矩形
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    for (int i = 1; i <= 10; i++) {
        for (int j = 1; j <= 10; j++) {
            cout << "*"<< " ";
        }
        cout << endl;
    }
    return 0;
}

# 斐波那契数列

  • 功能:打印斐波那契数列。
c++斐波那契数列
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int a = 0, b = 1, c;
    cout << a << " " << b << " ";
    for (int i = 2; i < 10; i++) {
        c = a + b;
        cout << c << " ";
        a = b;
        b = c;
    }
    return 0;
}

# break 跳出循环

  • 语法: break;
  • 功能:跳出当前循环。
c++break跳出循环
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    int i = 0;
    while (true) {
        cout << "i = " << i << endl;
        i++;
        if (i == 5) {
            break;
        }
    }
    return 0;
}

# continue 跳过本次循环

  • 语法: continue;
  • 功能:跳过本次循环,继续执行下一次循环。
c++continue跳过本次循环
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    for (int i = 0; i < 5; i++) {
        if (i == 2) {
            continue;
        }
        cout << "i = " << i << endl;
    }
    return 0;
}
// 输出结果:
// i = 0
// i = 1
// i = 3
// i = 4

# goto 跳转语句

  • 语法: goto 标签;
  • 功能:跳转到指定标签处执行。
  • 注意: goto 语句只能用于无限循环中,且不能跳出 switch 语句,不推荐使用。
c++goto语句
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    cout << "1.xxx" << endl;
    // using goto statement to jump to the label "flag"
    goto flag;
    cout << "2.xxx" << endl;
    cout << "3.xxx" << endl;
    // using label "flag" to mark the end of the program
    flag:
    cout << "4.xxx" << endl;
    return 0;
}
// 输出结果:
// 1.xxx
// 4.xxx

# 数组

  • 语法: 类型 数组名[数组大小];
  • 功能:声明一个数组,数组名为数组的名字,数组大小为数组的元素个数。
  • 注意:数组的下标从 0 开始,数组的元素可以是不同的数据类型。
c++数组
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 方法一
    int arr[5];
    // 数组元素赋值
    arr[0] = 10;
    arr[1] = 20;
    arr[2] = 30;
    arr[3] = 40;
    arr[4] = 50;
    // 输出数组元素
    for (int i = 0; i < 5; i++) {
        cout << "arr[" << i << "] = " << arr[i] << endl;
    }
    cout << endl;
    // 方法二,如果在初始化数据时候,没有全部填写完,会用 0 来填补剩余数据
    int arr2[] = {10, 20, 30};
    // 输出数组元素
    for (int i = 0; i < 5; i++) {
        cout << "arr2[" << i << "] = " << arr2[i] << endl;
    }
    cout << endl;
    // 方法三,定义数组的时候必须有初始长度
    int arr3[] = {10, 20, 30, 40, 50};
    for (int i = 0; i < 5; i++) {
        cout << "arr3[" << i << "] = " << arr3[i] << endl;
    }
    return 0;
}

# 数组名用途

  • 数组名可以作为指针使用,指向数组的第一个元素。
  • 数组名可以作为函数参数,传递数组的首地址。
  • 数组名可以作为结构体成员,访问结构体中的数组元素。
c++数组名用途
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 数组名用途
    // 1. 可以通过数组名统计整个数组占用内存大小
    int arr[5] = {10, 20, 30, 40, 50};
    cout << "arr数组占用内存大小为: " << sizeof(arr) << endl;
    cout << "每个元素占用内存空间为: " << sizeof(arr[0]) << endl;
    cout << "数组中元素个数为: " << sizeof(arr)/sizeof(arr[0]) << endl;
    // 2. 可以通过数组名查看数组首地址
    // 强转成 int 报错的话是因为精度丢失,可以用 long long
    // 使用 long long 可以避免精度丢失,使用强转主要是可以查看十进制的地址
    cout << "数组首地址为:" << (long long)arr << endl;
    cout << "数组中第一个元素地址为:" << (long long)&arr[0] << endl;
    cout << "数组中第二个元素地址为:" << (long long)&arr[1] << endl;
    //arr = 100; // 数组名是常量,不可以进行赋值操作
    return 0;
}

# 数组案例 1

c++数组案例1
#include <iostream>
// declaring namespace std
using namespace std;
/**
 * 案例描述 1:
 * 在一个数组中记录了五只小猪的体重,如:int arr [5] = {300,350,200,400,250};
 * 找出并打印最重的小猪体重
 * @return
 */
int main() {
    int arr[5] = {300, 350, 200, 400, 250};
    int max = arr[0]; // 假设第一个小猪最重
    for (int i = 1; i < sizeof(arr) / sizeof(arr[0]); i++) {
        if (arr[i] > max) {
            max = arr[i]; // 更新最重的小猪体重
        }
    }
    cout << "The heaviest pig is " << max << "kg." << endl;
    //arr = 100; // 数组名是常量,不可以进行赋值操作
    return 0;
}

# 数组案例 2

c++数组案例2
#include <iostream>
// declaring namespace std
using namespace std;
/**
 * 练习案例 2: 数组元素逆置
 * 案例描述:请声明一个 5 个元素的数组,并且将元素逆置
 * 如原数组元素为:1,3,2,5,4; 逆置后输出结果为:4,5,2,3,1
 * @return
 */
int main() {
    // 起始下标
    int start = 0;
    // 数组
    int arr[5] = {1, 3, 2, 5, 4};
    // 结束下标
    int end = sizeof(arr) / sizeof(arr[0])-1;
    // 输出原数组
    cout << "Original Array: " << arr[0] << " " << arr[1] << " " << arr[2] << " " << arr[3] << " " << arr[4] << endl;
    // 逆置数组
    while (start < end) {
        // 交换元素
        int temp = arr[start];
        arr[start] = arr[end];
        arr[end] = temp;
        // 更新下标
        start++;
        end--;
    }
    // 输出逆置后的数组
    cout << endl << "Reversed Array: " << arr[0] << " " << arr[1] << " " << arr[2] << " " << arr[3] << " " << arr[4] << endl;
    return 0;
}

# 冒泡排序

  • 功能:对数组进行升序排序。
  • 步骤:
    1. 外层循环控制遍历数组的次数,从 0 到 n-1。
    2. 内层循环控制比较的次数,从 0 到 n-i-1。
    3. 内层循环从 0 到 n-i-1,比较 arr [j] 和 arr [j+1],如果 arr [j] 大于 arr [j+1],则交换 arr [j] 和 arr [j+1]。
c++冒泡排序
#include <iostream>
// declaring namespace std
using namespace std;
void bubbleSort(int arr[], int n) {
    bool swapped;  // 引入一个标志变量
    for (int i = 0; i < n-1; i++) {
        swapped = false;  // 每次外循环开始时重置
        for (int j = 0; j < n-i-1; j++) {
            if (arr[j] > arr[j+1]) {
                // 交换相邻的元素
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                swapped = true;  // 标志变量设为 true,表示发生了交换
            }
        }
        // 如果在某一轮没有发生交换,说明数组已经有序
        if (!swapped) {
            break;
        }
    }
}
int main() {
    int arr[] = {5, 2, 8, 3, 9, 1, 7, 6, 4};
    int n = sizeof(arr) / sizeof(arr[0]);
    bubbleSort(arr, n);
    cout << "Sorted array: ";
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    return 0;
}
/**
在最好的情况下(即数组已经是有序的),优化后的算法只需要一轮就可以判断出数组有序,从而将时间复杂度从 O (n^2) 优化到 O (n)。
在最坏的情况下,时间复杂度仍然是 O (n^2),因为冒泡排序的核心机制决定了它的最坏表现。
*/

# 二维数组

  • 语法: 类型 数组名[行数][列数];
  • 功能:声明一个二维数组,数组名为二维数组的名字,行数为二维数组的行数,列数为二维数组的列数。
  • 注意:二维数组的下标从 0 开始,数组的元素可以是不同的数据类型。
c++二维数组
#include <iostream>
// declaring namespace std
using namespace std;
int main() {
    // 方法一
    int arr[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    // 输出二维数组
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << "arr[" << i << "][" << j << "] = " << arr[i][j] << endl;
        }
    }
    cout << endl;
    // 方法二,如果在初始化数据时候,没有全部填写完,会用 0 来填补剩余数据
    int arr2[3][3] = {
        {1, 2},
        {3, 4},
        {5, 6}
    };    
    // 输出二维数组
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << "arr2[" << i << "][" << j << "] = " << arr2[i][j] << endl;
        }
    }
    cout << endl;
    // 方法三,定义二维数组的时候必须有初始行数和列数
    int arr3[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    // 输出二维数组
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << "arr3[" << i << "][" << j << "] = " << arr3[i][j] << endl;
        }
    }
    return 0;
}

# 函数

# 函数的调用

  • 功能:使用定义好的函数
  • 语法: 函数名 (参数)
函数的调用
#include <iostream>
using namespace std;
int add(int num1, int num2) {
    int sum = num1 + num2;
    return sum;
}
int main() {
    int a = 10;
    int b = 20;
    int sum = add(a, b);
    cout << "Sum = " << sum << endl;
    // 执行结果 Sum = 30
}

# 函数的声明

  • 作用是告诉编译器函数名称及如何调用函数,函数的实际主体可以单独定义
  • 函数的声明可以多次,但函数的定义只能有一次
函数的声明
#include <iostream>
using namespace std;
// 函数的声明
int max(int a, int b);
int max(int a, int b);
// 函数的声明可以多次,但定义只能有一次
int max(int a, int b) {
    return a > b ? a : b;
}
int main() {
}

# 拆分函数编写 (函数的分文件编写)

  • 作用让代码结构更清晰,函数分文件编写一般有四个步骤
  • 1. 创建后缀名为 .h 的头文件
  • 2. 创建后缀名为 .cpp 的源文件
  • 3. 在头文件中写函数的声明
  • 4. 在源文件中写函数的定义
swap.h
#include <iostream>
using namespace std;
#ifndef DEMO_SWAP_H
#define DEMO_SWAP_H
#endif //DEMO_SWAP_H
int swap(int a,int b);
调用头文件示例
#include <iostream>
#include "swap.h"
using namespace std;
int main() {
    int sum = swap(3,2);
    cout << "sum" << sum << endl;
    return 0;
}

# 指针

指针的作用:可以土狗指针间接访问内存

  • 内存编号是从 0 开始记录的,一般用十六进制数字进行表示
  • 可以利用指针变量保存地址

# 指针的使用

  • 指针变量定义语法: 数据类型 * 变量名
指针的使用
#include <iostream>
using namespace std;
int main() {
    // 定义变量
    int a = 10;
    // 定义指针
    int * p;
    // 让指针记录变量 a 的地址
    p = &a;
    cout << "a的地址:" << &a << endl;
    cout << "p的地址:" << p << endl;
    // 使用指针
    // * 代表解引用,找到指针指向的内存中的数据。这样就可以修改 a 变量的值
    *p = 1000;
    cout << "a:" << a << endl;
    cout << "p:" << *p << endl;
    return 0;
}

# 指针的占用空间

指针也是种数据类型,那么遮罩数据类型占用多少内存空间呢?

指针的占用空间
#include <iostream>
using namespace std;
int main() {
    // 指针占用内存空间
    int a = 10;
    int *p = &a;
    // 在 32 位操作系统下,指针是占 4 个字节空间大小,不管是什么数据类型
    // 在 64 位操作系统下,指针是占 8 个字节空间大小,不管是什么数据类型
    cout << "sizeof(int *)" << sizeof(int *) << endl;
    cout << "sizeof(float *)" << sizeof(float *) << endl;
    cout << "sizeof(double *)" << sizeof(double *) << endl;
    cout << "sizeof(char *)" << sizeof(char *) << endl;
    
    /**
     * 执行结果
     * sizeof (int *) 8
     * sizeof (float *) 8
     * sizeof (double *) 8
     * sizeof (char *) 8
     */
    
}

# 空指针 and 野指针

  • 空指针:指针变量指向内存中编号为 0 的空间
  • 野指针:指针变量指向非法的内存空间

# 空指针

  • 空指针:指针变量指向内存中编号为 0 的空间
  • 用途:初始化指针变量
  • 注意:空指针指向的内存是不可以访问的
空指针和野指针
/**
* 空指针和野指针
空指针:指针变量指向内存中编号为 0 的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的
*/
#include <iostream>
using namespace std;
int main() {
    // 空指针
    int *p = NULL ;
    cout << "*p" << *p << endl;
    return 0;
}

# 野指针

  • 野指针:指针变量指向非法的内存空间
野指针
/**
* 野指针
 * 指针变量指向非法的内存空间
*/
#include <iostream>
using namespace std;
int main() {
    // 指针变量 p 指向内存地址编号为 θx1100 的空间
    int * p = (int *)0x1100 ;
    cout << "*p" << *p << endl;
    return 0;
}

# const 修饰指针

  • const 修饰指针有三种情况:
    1. const 修饰指针 - 常量指针
    2. const 修饰常量 - 指针常量
    3. const 即修饰指针,又修饰常量
const修饰指针
/**
* const 修饰指针
 * const 修饰指针有三种情况:
 * 1.const 修饰指针 --- 常量指针
 * 2. const 修饰常量 - 指针常量
 * 3. const 即修饰指针,又修饰常量
*/
#include <iostream>
using namespace std;
int main() {
    int a = 20;
    int b = 10;
    /**
    常量指针
    特点:指针的指向可以修改,但是指针指向的值不可以改
     */
    const int * p = &a;
//     *p = 20; // 错误,指针指向的值不可以改
//     *p = &b; // 正确,指针指向可以改
    // 指针常量
    int * const p2 = &a;
    // 特点:指针的指向不可以改,指针指向的值可以改
    //     *p = 20; // 正确,指针指向的值可以改
    //     *p = &b; // 错误,指针指向不可以改
    //const 即修饰指针,又修饰常里,特点:指针的指向和指针指向的值都不可以改
    const int * const p3 = &a;
    //     *p = 20; // 错误,指针指向的值不可以改
    //     *p = &b; // 错误,指针指向不可以改
    return 0;
}

# 指针和数组

利用指针访问数组中的元素

利用指针访问数组中元素
/**
* 利用指针访问数组中元素
*/
#include <iostream>
using namespace std;
int main() {
    // 指针和数组
    // 利用指针访问数组中的元素
    int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,};
    cout << "第一个元素为:" << arr[0] << endl;
    //arr 就是数组首地址
    int *p = arr;
    cout << "利用指针访问第一个元素:" << *p << endl;
    p++;// 让指针向后位移四个四节
    cout << "利用指针访问第二个元素:" << *p << endl;
    cout << "利用指针遍历数组" << endl;
    // 定义新指针
    int *p2 = arr;
    for (int i = 0; i<10;i++) {
//        cout << arr[i] << endl;
        cout << *p2  << endl;
        p2++;
    }
}

# 指针和函数

利用指针作为函数参数,可以修改实参的值

指针和函数
/**
 * 指针和函数
 * 总结:如果不想修改实参,就用值传递,如果想修改实参,就用地址传递
*/
#include <iostream>
using namespace std;
void swap01(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
    cout << "swap01 a = " << a << endl;
    cout << "swap01 b = " << b << endl;
}
void swap02(int *p1, int *p2) {
    int temp = *p1;
    *p1 = *p2;
    *p2 = temp;
    cout << "swap02 *p1 = " << *p1 << endl;
    cout << "swap02 *p2 = " << *p2 << endl;
}
// 实现两个数字交换
int main() {
    // 指针和函数
    int a = 10;
    int b = 20;
    // 1. 值传递
    swap01(a, b);// 值传递不会改变实参
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << endl;
    // 2. 地址传递
    // 如果是地址传递,可以修饰实参
    swap02(&a, &b);
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
}

# 指针、数组、函数案例

案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序

冒泡排序
#include <iostream>
using namespace std;
void bubbleSort(int *arr, int n) {
    // 外层循环控制遍历次数
    for (int i = 0; i < n - 1; i++) {
        // 内层循环进行相邻元素的比较和交换
        for (int j = 0; j < n - 1 - i; j++) {
            if (*(arr + j) > *(arr + j + 1)) {
                // 交换元素
                int temp = *(arr + j);
                *(arr + j) = *(arr + j + 1);
                *(arr + j + 1) = temp;
            }
        }
    }
}
void printArray(int *arr, int n) {
    for (int i = 0; i < n; i++) {
        cout << *(arr + i) << " ";
    }
    cout << endl;
}
int main() {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "原始数组: ";
    printArray(arr, n);
    bubbleSort(arr, n);
    cout << "排序后的数组: ";
    printArray(arr, n);
    // 原始数组: 64 34 25 12 22 11 90
    // 排序后的数组: 11 12 22 25 34 64 90
    return 0;
}

# 结构体

结构体属于用户自定义的数据类型,允许用户存储不同的数据类型,结构体语法: struct 结构体名 { 结构体成员列表 };

  • 通过结构体创建变量的方式有三种:
    1. struct 结构体名 变量名
    2. struct 结构体名 变量名 = { 成员值1,成员值2 }
    3. 定义结构体时顺便创建变量

# 结构体的使用

结构体的使用
/**
 * 结构体的定义与使用
 * 总结 1:定义结构体时的关键字是 struct,不可省略
 * 总结 2:创建结构体变垂时,关键字 struct 可以省略
 * 总结 3:结构体变量利用操作符 “.“访问成员
 */
#include <iostream>
#include <string>
using namespace std;
//1. 创建学生结构体数据类型
// 自定义数据类型,一些类型集合组成的应该类型
// 语法 struct 类型名称 {成员列表}
struct Student {
    // 成员列表
    string name;// 昵称
    int age{};// 年龄
    int score{};// 分数
} s3;// 这里的 s3 就是顺便创建的结构体变量
//2. 通过学生类型创建具体学生
int main() {
    // 2.1 struct Student s1;
    //struct 关键字可以省略
//     Student s1;
    struct Student s1;
    // 给 s1 属性进行赋值,通过访问结构体变量中的属性
    s1.name = "张三";
    s1.age = 18;
    s1.score = 100;
    cout << "name:" << s1.name << " age:" << s1.age << " score:" << s1.score << endl;
    //2.2 struct Student s2={...};
    struct Student s2 = {"张三", 20, 200};
    cout << "name:" << s2.name << " age:" << s2.age << " score:" << s2.score << endl;
    //2.3 在定义结构体时顺便创建结构体变量
    s3 = {"李四", 20, 200};
    cout << "name:" << s3.name << " age:" << s3.age << " score:" << s3.score << endl;
}

# 结构体数组

将自定义的结构体放入到数组中方便进行维护

语法: struct 结构体名 数组名[元素个数] = { {},{},{},...,{} }

结构体数组
/**
 * 结构体数组
 */
#include <iostream>
#include <string>
using namespace std;
// 1. 结构体定义
struct Student{
    string name;
    int age;
    int score;
};
int main(){
    // 2. 定义结构体数组
    Student arr[3] = {
            {"张三",10,100},
            {"李四",12,80},
            {"王五",14,75},
    };
    // 3. 给结构体数组中的元素赋值
    arr[2].name = "老六";
    arr[2].age = 21;
    // 4.1 遍历数组
    for (auto & i : arr) {
        cout << "name:" << i.name << " age:" << i.age << " score:" << i.score << endl;
    }
}

# 结构体指针

通过指针访问结构体中的成员,利用操作符 -> 就可以通过结构体指针访问结构体属性

结构体指针
/**
 * 指针结构体
 * 作用:通过指针访问结构体中的成员
 * 利用操作符 -> 可以通过结构体指针访问结构体属性
 * 总结:结构体指针可以通过 -> 操作符来访问结构体中的成员
 */
#include <iostream>
using namespace std;
// 创建结构体
struct Student{
    string name;
    int age;
    int score;
};
int main(){
    // 创建学生结构体变量
    Student stu = {"张三",18,80};
    // 通过指针指向结构体变量
    // 通过指针访问结构体中的数据
    // 通过结构体指针访问结构体中的属性,需需要利用 ->
    Student * p = &stu;
    p->age = 16;
    cout << "name = " << p->name <<" age = " << p->age << " score = " << p->score << endl;
    //system ("pause"); 请按任意键继续. . .
}

# 结构体嵌套

结构体中的成员可以是另一个结构体,例如:每个老师辅导应该学员,应该老师的结构体中,记录一个学生的结构体

结构体嵌套
/**
 * 结构体嵌套
 * 总结:在结构体中可以定义另一个结构体作为成员,用来解决实际问题
 */
#include <iostream>
using namespace std;
/*
 * 定义学生结构体
 */
struct Stendent{
    string name;// 学生编号
    int age;// 学生年龄
    int score;// 学生分数
};
/*
 * 定义老师结构体
 */
struct Teacher{
    int id;// 老师 ID
    string name;// 老师名称
    int age;// 老师年龄
    struct Stendent stu;// 辅导的学生
};
int main(){
    Teacher t1 = {1,"王老师",20,{"李四",18,20}};
    cout << "Teacher-Name:" << t1.name << " Teacher-Age:" << t1.age << " Stendent-Name:" << t1.stu.name << " Stendent-Age:" << t1.stu.age << " Stendent-Score:" <<t1.stu.score << endl;
    Teacher t2[2] = {
            {1,"赵老师",19,{"张三",19,10}},
            {2,"张老师",16,{"王五",20,60}},
    };
    for (auto & i : t2) {
        cout << "Teacher-Name:" << i.name << " Teacher-Age:" << i.age << " Stendent-Name:" << i.stu.name << " Stendent-Age:" << i.stu.age << " Stendent-Score:" <<i.stu.score << endl;
    }
}

# 结构体做函数参数

将结构体作为参数向函数中传递,传递方式有两种:一 值传递,二 地址传递

结构体做函数参数
/**
 * 结构体做函数参数
 * 总结:如果不想修改主函数中的数据,用值传递,反之用地址传递
 * 值传递是复制,地址传递是共用
 */
#include <iostream>
using namespace std;
/*
 * 定义学生结构体
 */
struct Stendent{
    string name;// 学生编号
    int age;// 学生年龄
    int score;// 学生分数
};
/**
 * 值传递
 * @param stu
 */
void printStudent1(Stendent stu){
    stu.age = 28;// 值传递不会修改实参
    cout << "子函数1 姓名:" << stu.name << " 年龄:" << stu.age << " 分数:" << stu.score << endl;
}
/**
 * 地址传递
 * @param stu
 */
void printStudent2(Stendent *stu){
    stu->age = 50;// 地址传递可以修改实参
    cout << "子函数2 姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;
}
int main(){
    Stendent s1 = {"张三",12,100};
    printStudent1(s1);
    printStudent2(&s1);
    cout << "主函数 姓名:" << s1.name << " 年龄:" << s1.age << " 分数:" << s1.score << endl;
}

# 结构体中 const 使用场景

用 const 来防止误操作

结构体中const使用场景
#include <iostream>
using namespace std;
/*
 * 定义学生结构体
 */
struct Stendent{
    string name;// 学生编号
    int age;// 学生年龄
    int score;// 学生分数
};
/**
 * 值传递
 * @param stu
 */
void printStudent1(Stendent stu){
    stu.age = 28;// 值传递不会修改实参
    cout << "子函数1 姓名:" << stu.name << " 年龄:" << stu.age << " 分数:" << stu.score << endl;
}
/**
 * 地址传递
 * 将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
 * @param stu
 */
void printStudent2(const Stendent *stu){// 加 const 防止函数体中的误操作
    cout << "子函数2 姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;
}
int main(){
    Stendent s1 = {"张三",12,100};
    printStudent1(s1);
    printStudent2(&s1);
    cout << "主函数 姓名:" << s1.name << " 年龄:" << s1.age << " 分数:" << s1.score << endl;
}

# 结构体案例

/**
 * 结构体案例
 */
#include <iostream>
#include <ctime>
using namespace std;
/*
 * 定义学生结构体
 */
struct Stendent {
    string name;// 学生编号
    int score;// 学生分数
};
/*
 * 定义老师结构体
 */
struct Teacher {
    string name;// 老师名称
    struct Stendent stuArray[5];// 辅导的学生
};
/**
 * 给老师和学生赋值的函数
 * @return
 */
void allocateSpace(Teacher tArray[], int len) {
    string nameSeed = "ABCDE";
    // 给老师开始赋值
    for (int i = 0; i < len; i++) {
        tArray[i].name = "Teacher_";
        tArray[i].name += nameSeed[i];
        // 通过循环给每名老师所带的学生赋值
        for (int j=0;j<5;j++) {
            tArray[i].stuArray[j].name = "Student_";
            tArray[i].stuArray[j].name += nameSeed[j];
            // 设置随机数
            int random = rand() % 61+40;//40~100
            tArray[i].stuArray[j].score = random;
        }
    }
}
// 打印所有信息
void printInfo(Teacher pTeacher[3], int len) {
    // 遍历老师
    for (int i = 0; i < len; i++) {
        cout << "老师名称:" << pTeacher[i].name << endl;
        for (int j=0;j<5;j++) {
            cout << "\t学生名称:" << pTeacher[i].stuArray[j].name << " 学生成绩:"
                 << pTeacher[i].stuArray[j].score << endl;
        }
    }
}
int main() {
    // 添加随机数种子
    srand((unsigned  int )time(NULL));
    // 创建 3 名老师的数组
    Teacher tArray[3];
    // 通过函数给 3 名老师的信息赋值,并给老师带的学生信息赋值
    allocateSpace(tArray, size(tArray));
//    cout << size(tArray)<<endl;
    // 打印所有老师及所带的学生
    printInfo(tArray, size(tArray));
}
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Light Rain 微信支付

微信支付