调查研究
Javascript
基础知识
介绍
**javascript是一种运行在客户端(浏览器)的编程语言 ,实现人机交互效果 **
- 作用:网页特效、表单验证、数据交互、服务器编程(node.js)
组成:
- ECMAScripts ---> 规定js的基础语法核心知识
- Web APIs --->
- DOM 操作文档,比如对页面元素进行移动、大小、添加删除操作
- BOM 操作浏览器,比如页面弹窗,检测窗口宽度、存储数据到浏览器
 
- 书写位置
- 
内部js --->写在html里面,用script标签,写在上面 
- 
外部js --->代码写在js文件,引入html页面 
- 
内联js --->代码写在标签内部 js<script> prompt("hello,world") document.write('你好,js') </script>
- 
注释 单行注释 // 快捷键 Ctrl + / 
 块注释 /* */ 快捷键 shift + alt + a
 结束符 --->英文分号代表语句结束 ;
- 输入输出语法
输出语法:向body输出内容 document.write('你好,js')
 页面警示框 alert('你好,js')
 控制台输出语法 console.log('你好,js')
输入语法: 提示输入prompt('请输入hello,world')
- 代码执行顺序
alert()和prompt()会跳过页面渲染先被执行
变量
- 变量的定义
变量是计算机存储数据的容器
- 变量的声明
创建变量:声明关键字、变量名
            
            
              js
              
              
            
          
          let 变量名赋值:对变量进行初始化
            
            
              js
              
              
            
          
          let age = 18
//let不允许多次声明一个变量交换两个变量的值,引入第三个变量temp
- 变量的本质
内存-->计算机存储数据的地方,程序在内存中申请一小块用来存放数据的小空间
- 变量的命名规范
由数字、字母、下划线、$符号组成,不能使用关键字,不能以数字开头;严格区分大小写
- let和var的区别
var可以先使用在声明、声明过的变量可以重复声明;变量提升、全局变量、没有块级作用域
声明变量统一用let
- 常量
概念:是一个不能被修改的值,通常用于表示固定、不变的量,使用const变量
使用:const PI = 3.1415926
常量不允许重新赋值,声明的时候必须复制(初始化)
- 数据类型(弱数据类型语言)
①基本数据类型
number、string、boolean、undefined、null、
②引用数据类型
object、function、array
数字--number
- 
定义: number类型用于表示整数和浮点数,包括正数、负数和零
- 
算术运算符 ( + - * / % >> 取余)  
- 
特别地: NaN是一个特殊的数值状态,它不等于任何值,包括自己,因此NaN != NaN
任何对NaN的操作都是返回NaN
字符串--string
- 用于存储文本数据的变量类型。字符串由字符组成,可以包含字母、数字、标点符号等;单引号、双引号、反引号包裹的数据
- 字符串拼接 '+';
- 模版字符串
语法:``反引号
内容拼接变量时,用${ }包裹变量
${变量名}
其他类型
- 布尔类型---boolean
是一种数据类型,用于表示逻辑值,只有两种可能的值:true 和 false
- 未定义类型---undefined
未定义类型"通常指的是在程序运行时,遇到的与变量类型相关的错误;声明变量未赋值
- 空类型---null
表示一个变量被赋值为 null,将来存放对象
类型转换
typeof或typeof ()--->用于获取变量的类型
            
            
              js
              
              
            
          
          let num = 10
typeof num 隐式转换:+ 两边只要有字符串,默认为字符串计算,其他算术运算符为数字类型
+'123'可转为数字类型
Number( ) 函数可以将字符串转换为数字
parseInt( ) 函数用于将字符串转换为整数
parsefloat( ) 函数将字符串转换为浮点数
运算符
赋值运算符(=、+=)
对变量进行赋值的运算符
            
            
              js
              
              
            
          
          let b = 5;
b += 3; // b现在等于8,等同于b = b + 3一元运算符(+)
只需要一个表达式就可运算,自增++和 自减--
自增运算符
- 前缀形式(++a):先增加值,再使用该值。
- 后缀形式(a++):先使用原值,再增加值。
自减运算符
- 前缀形式(--a):先减少值,再使用该值。
- 后缀形式(a--):先使用原值,再减少值。
比较运算符(> <)
比较运算符有隐式转换
- <=:小于等于
- ==:等于
- !=:不等于
- ===:严格等于
- !==:严格不等于
- 字符串比较
字符串比较转换为对应的ASCII码比较
逻辑运算符&&
逻辑与(全真为真)---&&
逻辑或(一真则真)---||
逻辑非 (非真即假)---!
流程控制语句
- 
顺序结构>>从上到下、依次执行 
- 
分支结构 - if:条件为真就执行
- else:否则执行这里
- switch:匹配哪个 case 就执行哪个
 
- 
循环结构 - for:计数循环,条件成立就继续
- while:先判后做,成立才循环
- do...while:先做后判,至少执行一次
- for:用于遍历数据结构
 - for...of:获取元素值(如数组元素、字符串字符)
- for...in:获取键名(如对象键、数组索引字符串)
 
- 
break和continue 
 break:彻底结束循环,立即跳出。
 continue:跳过当前迭代,继续下一轮循环
数组array
- 定义
 数组是一个有序的存储容器,用于存储多个值。这些值可以是 primitives(如字符串、数字、 boolean、 null、 undefined)或 objects(对象)、 arrays(数组)等复杂的值。
- 声明语法
let 数组名 = [数据]
- 访问
数组名[索引号]
长度-->数组的length获得:数组名.length
- 遍历
i <= array.length-1,确保索引不超过数组的最后一个元素(索引为 length-1)
进阶知识
HTML
基础知识
CSS
基础知识
Linux
基础知识
前景提要
- 计算机的主要组成部分:硬件系统和软件系统
操作系统(Operating System, OS)是计算机系统中负责管理和控制计算机及其资源的核心软件;
移动操作系统
- 安卓(Android)
- iOS
- 鸿蒙(HarmonyOS)
PC操作系统
- Windows
- macOS
- Linux
Linux的主要发行版:Ubuntu/RedHat/Centos
Windows操作系统
WSL(Windows Subsystem for Linux)
- WSL2:基于轻量级虚拟机(Hyper-V),提供完整的Linux内核,文件系统性能大幅提升,推荐使用。
Linux知识
Linux系统的组成:linux系统内核、系统级应用程序
Linux目录结构
- 根目录 (/):
- Linux系统的根目录是所有其他目录的起点,通常包含操作系统和系统配置文件。
 
- 常用目录层次结构:
- /boot:包含操作系统启动所需的文件和分区。
- /home:用户日志、配置文件等。
- /root:根用户的目录,通常是系统管理员的主目录。
- /etc:环境变量、系统配置文件。
- /user:用户目录,存储用户程序和数据。
- /mnt:挂载点,用于连接外置文件系统。
 
- 用户目录 (/user):
- 用户目录下通常包含用户的配置文件、应用程序的安装目录、以及用户生成的文件等。
 
- 本地目录 (/user/local):
- 用于存储用户的本地配置文件,如密码、登录信息等,通常隐藏在用户目录下。
 
- 设备驱动层:
- /dev:包含设备驱动和虚拟设备,如swap分区、设备映射等。
 
Shell编程
C++程序设计语言
基础知识
变量
命名规则:C++标识符由字母、数字和下划线组成,必须以字母或下划线开头,不能是关键字,并且区分大小写
数据的输入与输出
cout是标准输出流对象,通过<<运算符向控制台输出数据(如cout << "Hello" << endl;),endl换行;
cin是标准输入流对象,通过>>从控制台读取输入到变量(如cin >> name;)。
两者需包含头文件<iostream>,属std命名空间。
<<称插入运算符,>>为提取运算符,注意输入类型需匹配变量,字符串输入用getline()更安全。
数据类型
C++数据类型包括基本类型:整型( int、long long int)、浮点型(如 float、double)、布尔型(如 true、false)、字符型(char)和字符串型(string)、复合类型(数组array、结构体、类、联合体)、空类型(void)及引用类型
sizeof 是 C++ 中的一个一元运算符 ,用于计算数据类型或变量在内存中所占的字节数,返回值为 size_t 类型
size_t---无符号整数类型,专门用来表示 "对象大小" 或 "数组索引" 这类 非负整数值。
- sizeof(类型名)(如- sizeof(int))
- sizeof 变量/表达式(如- sizeof(a))
科学计数法:
科学计数法的幂次是 10 的幂,float 精度约 7 位十进制,double 精度约 15 位
未指定后缀的科学计数法默认是 double 类型 。
例如:3e-2 是 double,若赋值给 float 变量,添加后缀 f 或 F:
flaot f3 = 3e-2f =3*10^-2
double f3 = 3e+2  = 3*10^2
运算符
算术运算符
- /:除法(整数除法会截断小数部分)整数相除结果依然是整数
- %:取模(求余数,仅用于整数类型)
- ++:自增
- --:自减
前置运算符 --- 变量先加减,再进行表达式运算;
后置运算符 --- 先执行表达式运算,再进行变量加减
赋值运算符
=用于赋值,复合形式如+=、*=可简化操作
比较运算符
用于判断两值关系,返回布尔值:
==相等、!=不等、>大于、<小于、>=大于等于、<=小于等于
逻辑运算符
&&:全真为真;||:一真即真;!:非真即假
条件运算符
语法格式为:
condition ? expression1 : expression2
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    int score = 85;
    
    // 条件运算符:condition ? expr1 : expr2
    // 如果条件为真,返回expr1;否则返回expr2
    string result = (score >= 60) ? "及格" : "不及格";
    
    cout << "分数 " << score << " 的结果是:" << result << endl;
    // 输出:分数 85 的结果是:及格
    
    return 0;
}三目运算符返回的是变量,可以继续赋值
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    int a = 10;
    int b = 20;
    
    // 三目运算符返回的是变量本身(左值),所以可以继续赋值
    // 因为 a < b,所以 (a > b ? a : b) 返回的是 b 这个变量
    // 相当于执行了 b = 100
    (a > b ? a : b) = 100;
    
    cout << "a = " << a << ", b = " << b << endl; // 输出: a = 10, b = 100
    
    return 0;
}流程结构
顺序结构
依次执行
- 
程序从 main()函数开始
- 
逐行执行每条语句 
- 
每条语句执行完成后自动进入下一条 
- 
直到遇到 return 0;程序结束 
选择结构
if语句
简单if语句:if (条件) 语句;
- 如果条件为真,执行语句;否则跳过
if-else语句:if (条件) 语句1; else 语句2;
- 如果条件为真,执行语句1;否则执行语句2
if-else else-if语句:用于多条件判断
- 依次检查每个条件,执行第一个为真的条件对应的语句
重要规则:
- 条件表达式需要用圆括号 ()括起来
- 如果if或else后面有多条语句,必须用花括号 {}括起来形成代码块
- C++中,非零值被视为真,零值被视为假
Switch语句
重要规则:
- 类型限制:switch的判断表达式只能是整型(int, short, long等)或字符型(char),不能是浮点型、字符串或布尔型
- 值匹配:只能匹配具体的值,不能判断区间(如case 60-70: 是错误的)
- break的重要性:每个case后通常需要break语句,否则会"穿透"执行下一个case的代码
- default可选:可以包含default分支处理未匹配的情况
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    char grade = 'B';
    
    cout << "成绩等级对应评语:" << endl;
    
    switch (grade) {
        case 'A':
            cout << "优秀!继续保持!" << endl;
            break;  // 必须有break,否则会继续执行下一个case
        case 'B':
            cout << "良好!很有潜力!" << endl;
            break;
        case 'C':
            cout << "及格!需要更加努力!" << endl;
            break;
        case 'D':
            cout << "不及格!要加油了!" << endl;
            break;
        case 'F':
            cout << "很差!需要重新学习!" << endl;
            break;
        default:  // 处理未匹配的情况
            cout << "无效的成绩等级!" << endl;
            break;
    }
    
    // 错误示例:尝试使用区间(这是不允许的)
    /*
    int score = 85;
    switch (score) {
        case 90-100:  // 错误!不能使用区间
            cout << "A" << endl;
            break;
        case 80-89:   // 错误!
            cout << "B" << endl;
            break;
    }
    */
    
    // 正确处理数值范围的方式应该用if-else
    int score = 85;
    cout << "\n用if-else处理分数区间:" << endl;
    if (score >= 90) {
        cout << "等级:A" << endl;
    } else if (score >= 80) {
        cout << "等级:B" << endl;
    } else if (score >= 70) {
        cout << "等级:C" << endl;
    } else if (score >= 60) {
        cout << "等级:D" << endl;
    } else {
        cout << "等级:F" << endl;
    }
    
    return 0;
}循环结构
1. while循环
- 
语法: while (条件) { 循环体 }
- 
执行流程: - 判断条件表达式是否为真
- 如果为真,执行循环体,然后回到判断
- 如果为假,跳出循环,执行循环后的代码
 c++#include <iostream> using namespace std; int main() { int i = 1; // 当i <= 5时,重复执行循环体 while (i <= 5) { cout << i << " "; i++; // 更新循环变量 } // 输出:1 2 3 4 5 return 0; } 
2. do while循环
- 语法
            
            
              c++
              
              
            
          
          do {
    // 循环体
} while (条件);- 重要规则:
- 至少执行一次:无论条件是否为真,循环体都会先执行一次
- 后判断:在每次循环体执行完毕后才检查条件
- 分号:while后的条件判断必须以分号结束
 
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    int i = 1;
    
    // 先执行循环体,再判断条件
    do {
        cout << i << " ";
        i++;
    } while (i <= 5);
    // 输出:1 2 3 4 5
    
    return 0;
}3. for循环
- 语法:
            
            
              c++
              
              
            
          
          for (初始化; 条件; 更新) {
    // 循环体
}- 重要规则:
- 三要素集中:初始化、条件判断、更新操作都在括号内清晰定义
- 预测试:先判断条件,为真时才执行循环体
- 适用场景:适合循环次数已知的情况
 
数组是用于存储相同类型多个元素的连续内存空间
利用for循环遍历数组
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    
    // 使用for循环遍历数组
    for (int i = 0; i < 5; i++) {
        cout << "arr[" << i << "] = " << arr[i] << endl;
    }
    
    return 0;
}猜数字案例
            
            
              c++
              
              
            
          
          #include <iostream>      // 输入输出流
#include <ctime>         // time()函数获取时间
using namespace std;
int main()
{
    cout << "猜数字游戏开始!" << endl;
    
    // 1. srand() + time(NULL):设置随机数种子
    // time(NULL)返回当前时间(秒数),确保每次运行程序产生不同的随机序列
    srand(time(NULL));
    
    // 2. rand() % 100 + 1:生成1-100的随机数
    // rand()产生0-RAND_MAX的随机数
    // % 100 得到0-99,+1 变成1-100
    int a = rand() % 100 + 1;
    
    int guess = 0;
    cout << "请输入你猜的数字(1-100):" << endl;
    
    // 3. while(true)无限循环 + break:实现持续猜测直到正确
    while (true) {
        cin >> guess;  // 输入
        
        // 4. if-else if-else:多分支判断
        if (guess > a) {
            cout << "猜大了" << endl;
        }
        else if (guess < a) {
            cout << "猜小了" << endl;
        }
        else {
            cout << "恭喜你猜对了" << endl;
            break;  // 5. break:跳出循环
        }
    }
    cout << "游戏结束" << endl;
    return 0;
}4. 跳转语句
- 
break - 跳出循环**:在 for、while、do-while循环中,立即终止整个循环**
- 跳出switch :在 switch语句中,跳出当前switch结构,防止"穿透"到下一个case
 break只能跳出最内层 的循环或switch语句
- 跳出循环**:在 
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    // break在循环中的使用
    for (int i = 1; i <= 10; i++) {
        if (i == 5) {
            break;  // 当i等于5时,立即跳出循环
        }
        cout << i << " ";  // 输出:1 2 3 4
    }
    
    return 0;
}- 
continue - 跳过当前循环体中剩余的代码
- 直接进入下一次循环的迭代
- 对于 for循环,会先执行更新表达式,再判断条件
 continue只能在循环结构(for、while、do-while)中使用。
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    // continue跳过偶数,只输出奇数
    for (int i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            continue;  // 如果是偶数,跳过本次循环剩余代码
        }
        cout << i << " ";  // 只有奇数能执行到这里
    }
    // 输出:1 3 5 7 9
    
    return 0;
}- **go to **
            
            
              c++
              
              
            
          
          goto 标签名;
...
标签名: // 标签后跟冒号 1. 无条件跳转:立即跳转到标签所在位置
 2. 标签命名:遵循变量命名规则,后跟冒号
 3. 作用范围:只能在同一函数内跳转
 4. 限制:不能跳过变量的初始化(如跳过带初始化的定义)
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    int i = 1;
    
    loop_start:  // 定义标签
    if (i > 5) {
        goto loop_end;  // 条件满足时跳转到loop_end
    }
    cout << i << " ";
    i++;
    goto loop_start;  // 跳转回loop_start
    
    loop_end:  // 标签位置
    cout << "\n循环结束" << endl;
    
    return 0;
}
// 输出:1 2 3 4 5
//       循环结束数组
一维数组
- 声明语法 :类型 数组名[大小];- 类型:数组中所有元素的数据类型(如int、double、char等)
- 大小:数组元素的个数,必须是编译时常量(正整数)
 
- 内存布局 :
- 数组元素在内存中连续存储
- 第一个元素的索引是0,最后一个元素的索引是大小-1
- 可以通过&数组名[索引]获取元素的内存地址
 
- 初始化方式 :
- 完全初始化:int arr[3] = {1, 2, 3};
- 部分初始化:int arr[5] = {1, 2};(剩余元素自动初始化为0)
- 自动大小:int arr[] = {1, 2, 3};(编译器根据初始化值确定大小)
 
- 完全初始化:
- 访问元素 :
- 使用下标运算符 [],如arr[0]
- 不检查边界:访问超出范围的索引会导致未定义行为(如内存越界)
 
- 使用下标运算符 
- 数组名的含义 :
- 数组名代表数组首元素的地址
- sizeof(数组名)返回整个数组的字节数
- 作为函数参数传递时,会退化为指针
 
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    // 1. 声明并初始化一维数组
    int scores[5] = {85, 92, 78, 96, 88};  // 完全初始化
    
    // 2. 访问数组元素(使用for循环)
    cout << "=== 数组元素遍历 ===" << endl;
    for (int i = 0; i < 5; i++) {
        cout << "第" << (i+1) << "个成绩: " << scores[i] << endl;
    }
    
    // 3. 修改数组元素
    scores[2] = 85;  // 将第三个元素修改为85
    cout << "\n修改后第三位成绩: " << scores[2] << endl;
    
    // 4. 数组大小计算
    cout << "数组总大小: " << sizeof(scores) << " 字节" << endl;
    cout << "单个元素大小: " << sizeof(scores[0]) << " 字节" << endl;
    cout << "元素个数: " << sizeof(scores) / sizeof(scores[0]) << endl;
    
    // 5. 内存地址演示
    cout << "\n=== 内存地址 ===" << endl;
    for (int i = 0; i < 5; i++) {
        cout << "scores[" << i << "] 地址: " << &scores[i] << endl;
    }
    cout << "数组名地址: " << scores << endl;  // 数组名即首元素地址
    
    return 0;
}二维数组
- 
声明语法 : 类型 数组名[行数][列数];- 例如:int matrix[3][4];声明一个3行4列的整型数组
 
- 例如:
- 
内存布局: - 元素在内存中连续存储
- 按行优先顺序:第一行所有元素 → 第二行所有元素 → ...
- 总元素个数 = 行数 × 列数
- 总字节数 = 行数 × 列数 × sizeof(元素类型)
 
- 
初始化方式: - 按行初始化:int arr[2][3] = {``{1,2,3}, {4,5,6}};
- 连续初始化:int arr[2][3] = {1,2,3,4,5,6};
- 部分初始化:未指定的元素自动初始化为0
 c++#include <iostream> using namespace std; int main() { // 1. 完整按行初始化(推荐,清晰易读) int arr1[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 2. 连续初始化(按内存顺序) int arr2[2][3] = {1, 2, 3, 4, 5, 6}; // 等价于上面的arr1 // 3. 部分初始化 - 只初始化前几行 int arr3[3][4] = { {1, 2}, // 第0行:1,2,0,0 {3, 4, 5} // 第1行:3,4,5,0 // 第2行全部为0 }; // 4. 部分初始化 - 只初始化前几个元素 int arr4[2][3] = {1, 2, 3, 4}; // 等价于 {{1,2,3},{4,0,0}} // 5. 全部初始化为0 int arr5[2][3] = {0}; // 所有元素都为0 // 6. 省略行数,自动推断(列数必须指定) int arr6[][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; // 编译器自动推断行数为3 // 验证初始化结果 cout << "=== 部分初始化示例(arr3) ===" << endl; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { cout << arr3[i][j] << "\t"; } cout << endl; } // 输出: // 1 2 0 0 // 3 4 5 0 // 0 0 0 0 return 0; } 
- 按行初始化:
- 
访问元素: - 使用双下标:数组名[行索引][列索引]
- 行索引范围:0 到 (行数-1)
- 列索引范围:0 到 (列数-1)
- 不进行边界检查,越界访问会导致未定义行为
 
- 使用双下标:
- 
数组名的含义: - 数组名代表第一行的地址(即&数组名[0])
- sizeof(数组名)返回整个二维数组的总字节数
 
- 数组名代表第一行的地址(即
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    // 1. 声明并初始化二维数组
    int matrix[3][4] = {
        {1, 2, 3, 4},    // 第0行
        {5, 6, 7, 8},    // 第1行  
        {9, 10, 11, 12}  // 第2行
    };
    
    // 2. 遍历并输出二维数组
    cout << "=== 二维数组遍历 ===" << endl;
    for (int i = 0; i < 3; i++) {      // 行循环
        for (int j = 0; j < 4; j++) {  // 列循环
            cout << matrix[i][j] << "\t";
        }
        cout << endl;  // 每行结束后换行
    }
    
    // 3. 访问特定元素
    cout << "\nmatrix[1][2] = " << matrix[1][2] << endl;  // 输出7
    
    // 4. 数组大小信息
    cout << "总大小: " << sizeof(matrix) << " 字节" << endl;
    cout << "每行大小: " << sizeof(matrix[0]) << " 字节" << endl;
    cout << "元素类型大小: " << sizeof(matrix[0][0]) << " 字节" << endl;
    cout << "总元素个数: " << (sizeof(matrix) / sizeof(matrix[0][0])) << endl;
    
    return 0;
}函数
- 函数的定义
            
            
              c++
              
              
            
          
          返回类型 函数名(参数列表) {
    // 函数体(具体实现代码)
    [return 表达式;]  // 如果返回类型不是void,则需要return语句
}- 函数的调用
- 语法:函数名(实际参数列表);
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
// 函数定义
int add(int a, int b) {
    return a + b;
}
void printResult(int result) {
    cout << "计算结果: " << result << endl;
}
int main() {
    int x = 5, y = 3;
    
    // 函数调用示例
    int sum = add(x, y);           // 调用add函数,实参是变量x和y
    printResult(sum);              // 调用printResult函数,实参是变量sum
    
    printResult(add(10, 20));      // 嵌套调用:add的返回值作为printResult的参数
    
    printResult(add(x, 7));        // 实参可以是变量和常量的组合
    
    return 0;
}- 函数的类别
- 无参无返回值 (void function())
- 特点:不接收任何输入,也不返回结果
- 用途:执行固定操作,如显示菜单、打印信息
 
            
            
              c++
              
              
            
          
          void showMenu() {
    cout << "=== 主菜单 ===" << endl;
    cout << "1. 开始游戏" << endl;
    cout << "2. 退出游戏" << endl;
}- 有参无返回值 (void function(parameters))
- 特点:接收输入参数,但不返回结果
- 用途:根据输入执行操作,如打印格式化信息
 
            
            
              c++
              
              
            
          
          void printSum(int a, int b) {
    cout << a << " + " << b << " = " << (a + b) << endl;
}- 无参有返回值 (return_type function())
- 特点:不接收输入,但返回一个计算结果
- 用途:获取系统状态、生成随机数等
 
            
            
              c++
              
              
            
          
          int getRandomNumber() {
    return rand() % 100 + 1;  // 返回1-100的随机数
}- 
有参有返回值 (return_type function(parameters)) 特点:接收输入参数,并返回计算结果 用途:最常用的函数类型,进行数据处理和计算 
            
            
              c++
              
              
            
          
          int add(int a, int b) {
    return a + b;  // 根据输入参数计算并返回结果
}案例
            
            
              c++
              
              
            
          
          #include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// 1. 无参无返回值
void showMenu() {
    cout << "=== 计算器 ===" << endl;
    cout << "1. 加法" << endl;
    cout << "2. 退出" << endl;
}
// 2. 有参无返回值
void printResult(int a, int b, int result) {
    cout << a << " + " << b << " = " << result << endl;
}
// 3. 无参有返回值  
int getRandomNumber() {
    return rand() % 10 + 1;  // 返回1-10的随机数
}
// 4. 有参有返回值
int add(int a, int b) {
    return a + b;
}
int main() {
    srand(time(0));
    
    // 测试四种函数类型
    showMenu();                    // 无参无返
    
    int num1 = getRandomNumber();  // 无参有返
    int num2 = getRandomNumber();
    
    int sum = add(num1, num2);     // 有参有返
    printResult(num1, num2, sum);  // 有参无返
    
    return 0;
}- 函数的分文件编写
创建.h后缀名的头文件,创建.cpp后缀名的源文件,头文件中写函数声明,源文件中写函数定义
头文件(.h 或 .hpp):
1. 包含函数声明(函数原型)
	2. 使用    `#ifndef`/`#define`/`#endif` 防止重复包含(头文件保护)
	3. 通过    `#include` 在其他文件中引用源文件(.cpp):
 1. 包含函数的具体实现(定义)
 2. 实现头文件中声明的函数
主文件(main.cpp):
 1. 包含 main() 函数
 2. 引用头文件来使用其他文件中的函数
指针
- 
指针的作用:指针间接访问内存 **指针是C++中一种特殊的变量,用于存储另一个变量的内存地址**
- 
语法: 数据类型* 指针变量名; 
- 
指针初始化 数据类型* 指针名 = &变量名;-------将变量的地址赋值给指针 
- 
&取地址 取地址运算符(&) &变量名;------获取变量的内存地址 
- 
解引用运算符 (*) *指针名-------访问指针所指向地址中的值 
- 
指针所占内存空间 - 大小固定 :
- 在同一系统上,所有类型指针的大小都相同
- 与指向 int、double、char等无关
 
- 系统依赖 :
- 32位系统 :指针占 4字节(32位 = 4字节)
- 64位系统 :指针占 8字节(64位 = 8字节)
 
- 使用 sizeof :
- sizeof(指针变量)或- sizeof(数据类型*)可获取指针大小
 
 
- 大小固定 :
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    int value = 42;
    
    // 1. 指针声明
    int* ptr;
    
    // 2. 指针初始化(使用取地址符&)
    ptr = &value;
    
    // 3. 解引用(使用*获取指向的值)
    cout << "value的值: " << value << endl;
    cout << "ptr指向的值: " << *ptr << endl;
    cout << "value的地址: " << &value << endl;
    cout << "ptr存储的地址: " << ptr << endl;
    
    // 4. 通过指针修改值
    *ptr = 100;
    cout << "修改后value: " << value << endl;
    
    // 5. 空指针
    ptr = nullptr;  // 安全的空指针
    
    return 0;
}空指针指向的内存,不允许访问,访问空指针所指向的内存是非法的
- 空指针的本质 :
- 值为 nullptr(或NULL、0)
- 不指向任何有效的内存位置
- 是一种安全的"无指向"状态
 
- 值为 
常量指针(Pointer to const)
- 语法 :const 数据类型* 指针名或数据类型 const* 指针名
- 含义 :指针指向的数据不能修改,但指针本身可以指向其他地址
- 记忆法:"指向常量的指针"
            
            
              c++
              
              
            
          
          int a = 10, b = 20;
const int* ptr = &a;  // ptr指向常量整数
// ✅ 允许:改变指针指向
ptr = &b;  // ptr现在指向b
// ❌ 禁止:修改指针指向的数据
// *ptr = 30;  // 错误!不能通过ptr修改数据指针常量(Const pointer)
- 语法 :数据类型* const 指针名
- 含义 :指针本身是常量,指向的地址不能改变,但可以修改指向的数据
- 记忆法:"常量的指针"
            
            
              c++
              
              
            
          
          int a = 10, b = 20;
int* const ptr = &a;  // ptr是一个常量指针,初始化指向a
// ✅ 允许:修改指针指向的数据
*ptr = 15;  // a的值变为15
// ❌ 禁止:改变指针指向
// ptr = &b;  // 错误!ptr是常量,不能重新赋值常量指针常量(完全常量)
- 语法 :const 数据类型* const 指针名
- 含义:既不能改变指向的地址,也不能修改指向的数据
            
            
              c++
              
              
            
          
          int a = 10, b = 20;
const int* const ptr = &a;
// ❌ 都不允许
// *ptr = 20;   // 错误!不能修改数据
// ptr = &b;    // 错误!不能改变指向口诀:
- 
const在*左边:数据常量(指针可变)
- 
const在*右边:指针常量(数据可变)
- 
const在 两边:都是常量
- 
**指针和数组 ** - 数组名的本质 :
- 数组名是一个指向首元素的指针常量
- arr等价于- &arr[0]
- 不能修改数组名的指向(因为是常量)
 
- 指针算术 :
- 指针加减整数会按指向类型的大小移动
- ptr + 1移动- sizeof(类型)个字节
 
 - sizeof(arr)返回整个数组的字节数
- sizeof(ptr)返回指针变量的大小
 
- 数组名的本质 :
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    
    // 1. 数组名作为指针
    cout << "arr = " << arr << endl;           // 数组首地址
    cout << "&arr[0] = " << &arr[0] << endl;   // 首元素地址
    cout << "*arr = " << *arr << endl;         // 10(首元素值)
    
    // 2. 指针指向数组
    int* ptr = arr;  // 等价于 int* ptr = &arr[0];
    
    // 3. 两种访问方式等价性
    cout << "\n=== 访问方式对比 ===" << endl;
    for (int i = 0; i < 5; i++) {
        cout << "arr[" << i << "] = " << arr[i] 
             << ", *(arr+" << i << ") = " << *(arr + i)
             << ", *(ptr+" << i << ") = " << *(ptr + i) << endl;
    }
    
    // 4. 指针遍历
    cout << "\n=== 指针遍历 ===" << endl;
    for (int* p = arr; p < arr + 5; p++) {
        cout << *p << " ";
    }
    cout << endl;
    
    // 5. 重要区别
    int* dynamicArr = new int[3]{1, 2, 3};
    cout << "sizeof(arr) = " << sizeof(arr) << endl;      // 整个数组大小
    cout << "sizeof(ptr) = " << sizeof(ptr) << endl;      // 指针大小
    cout << "sizeof(dynamicArr) = " << sizeof(dynamicArr) << endl; // 指针大小
    
    delete[] dynamicArr;
    return 0;
}- 
指针和函数 - 指针作为函数参数
 - 概念:将指针作为参数传递给函数
- 优点 :
- 
避免大数据的复制开销 
- 
实现函数间的双向通信(修改原数据) 
- 
处理动态分配的内存  
 
- 
 
结构体
- 结构体的定义
            
            
              c++
              
              
            
          
          struct 结构体名 {
    数据类型 成员1;
    数据类型 成员2;
    // ...
};- 
结构体数组 
- 
结构体指针 
- 
结构体嵌套结构体 
- 
结构体做函数参数 
- 
const使用场景 
- 
结构体案例 
通讯管理系统案例
内存四区
内存分区模型:代码区、全局区、栈区、堆区
代码区;只读、共享
全局区:全局变量和静态变量(static)/常量(字符串常量,const修饰的全局变量)
栈区的注意事项:不要返回局部变量的地址、栈区的数据在函数执行完成后自动释放
堆区:
new 数据类型 new返回的是该数据类型的指针;
释放数据delete 释放数组 delete [ ]
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
int main() {
    // --- 栈区示例 ---
    int stackVar = 50;  // 栈区,函数结束自动释放
    
    // --- 堆区示例 ---
    int* heapPtr = new int(100);      // 堆区分配
    int* heapArray = new int[5]{1,2,3,4,5};  // 堆区分配数组
    
    cout << "*heapPtr = " << *heapPtr << endl;
    
    // 使用完必须释放
    delete heapPtr;        // 释放单个int
    delete[] heapArray;    // 释放数组
    
    // 避免悬空指针
    heapPtr = nullptr;
    heapArray = nullptr;
    
    return 0;
}引用
- 
引用的作用 替代指针实现引用传递 语法: 数据类型 &别名 = 原名;
- 
引用的注意事项 必须初始化:引用在声明时就必须绑定到一个对象 绑定后不可更改:引用一旦初始化,就不能再指向其他对象 绑定对象必须存在:不能引用不存在的变量(如已销毁的局部变量) 
- 
引用做函数参数 c++返回类型 函数名(类型& 参数名) { // 函数体 }
- 
引用做函数返回值(函数调用做左值) 
- 
引用的本质是指针常量 
- 
常量引用主要用来修饰形参 
进阶知识
函数高级
函数的默认参数(函数声明有默认参数,函数实现就不能有默认参数)
 从右向左原则:默认参数必须从右向左依次定义
 只能在声明中指定:通常在头文件中声明时设置默认值
 不能重复指定:定义时不能再写默认值
函数重载(函数的返回值不可以作为函数重载的条件)
 允许在同一作用域内定义多个同名函数,只要它们的参数列表不同
满足:同一个作用域、函数名称相同、函数参数类型不同或顺序不同或个数不同
重载的条件
函数重载必须满足以下至少一个条件:
| 条件 | 示例 | 
|---|---|
| 参数个数不同 | func()vsfunc(int a) | 
| 参数类型不同 | func(int a)vsfunc(double a) | 
| 参数顺序不同 | func(int, double)vsfunc(double, int) | 
类和对象
C++面向对象的三大特性:封装、继承、多态
封装
- 什么是封装:
- 将相关的数据(属性)和函数(方法)组织在一个类中
- 隐藏对象的内部实现细节
- 通过公共接口与外界交互
- 封装的好处:
- 安全性:防止外部直接修改内部数据
- 易维护性:内部实现可以改变而不影响外部代码
- 复用性:封装好的类可以被多次使用
- 简化使用:用户只需了解公共接口
类(class)
            
            
              c++
              
              
            
          
          class 类名 {
private:    // 私有成员(默认)
    // 数据成员(属性)
    // 成员函数
protected:  // 保护成员
    // ...
public:     // 公有成员
    // 成员函数(接口)
};- 访问控制 :
- private:只能在类内部访问(默认)
- public:可以在任何地方访问
- protected:在类内部和派生类中访问
 
- 成员组成 :
- 数据成员:描述对象的属性
- 成员函数:描述对象的行为
 
- 对象创建 :
- 类名 对象名;
- 对象通过.操作符访问公有成员
 
实例化
类中的属性和行为统一称为成员
struct和class的区别
默认的访问权限不同struct(public)/class(prviate)
| 特性 | struct | class | 
|---|---|---|
| 默认访问权限 | public | private | 
| 默认继承方式 | public | private | 
| 使用习惯 | 侧重数据组织 | 侧重面向对象设计 | 
成员属性设置私有
对象的初始化和清理
1.构造函数和析构函数
 构造函数语法:类名(){ }
 关键特征:
- 
没有返回类型 (连 void都不能写)
- 
函数名必须与类名完全相同 
- 
在创建对象时自动调用 构造函数的特点 
| 特性 | 说明 | 
|---|---|
| 无返回值 | 不能写任何返回类型 | 
| 自动调用 | 对象创建时自动执行,无需手动调用 | 
| 只调用一次 | 每个对象在其生命周期内仅调用一次 | 
| 可重载 | 可以有多个构造函数(参数不同) | 
| 可带参数 | 支持参数初始化成员变量 | 
            
            
              c++
              
              
            
          
          #include <iostream>
using namespace std;
class Timer {
public:
    // 构造函数:开始计时
    Timer() {
        cout << "计时开始..." << endl;
    }
    
    // 析构函数:结束计时
    ~Timer() {
        cout << "计时结束!" << endl;
        cout << "任务完成!" << endl;
    }
};
void doWork() {
    Timer t;  // 创建对象,自动开始计时
    
    // 模拟做一些工作
    cout << "正在处理数据..." << endl;
    cout << "正在保存文件..." << endl;
    cout << "正在清理缓存..." << endl;
    
    // 函数结束时,t的析构函数自动被调用
}
int main() {
    cout << "程序开始" << endl;
    
    doWork();  // 调用函数
    
    cout << "程序结束" << endl;
    return 0;
} 析构函数:~类名(){ }
 析构函数的核心特点
| 特性 | 说明 | 
|---|---|
| 没有返回值 | 不能写任何返回类型(包括void) | 
| 无参数 | 不能有任何参数(包括void) | 
| 自动调用 | 对象销毁时自动执行 | 
| 只调用一次 | 每个对象在其生命周期内仅调用一次 | 
| 不能重载 | 一个类只能有一个析构函数 | 
            
            
              c++
              
              
            
          
          class 类名 {
public:
    // 构造函数 - 没有返回值,名字和类一样
    类名() {
        // 对象创建时自动执行
    }
    
    // 析构函数 - 名字前面加~
    ~类名() {
        // 对象销毁时自动执行
    }
};2.构造函数的分类及调用
构造函数的分类:
- 按参数分类
| 类型 | 示例 | 
|---|---|
| 无参构造 | Person() { } | 
| 有参构造 | Person(string name, int age) { } | 
- 按功能分类
| 类型 | 说明 | 
|---|---|
| 普通构造 | 包括无参和有参构造 | 
| 拷贝构造 | Person(const Person& p) { } | 
拷贝构造函数:
            
            
              c++
              
              
            
          
          #include <iostream>
#include <string>
using namespace std;
class Dog {
public:
    string name;
    
    Dog(string n) : name(n) {
        cout << "创建: " << name << endl;
    }
    
    // 拷贝构造函数
    Dog(const Dog& other) {
        name = "copy_of_" + other.name;
        cout << "复制: " << other.name << " → " << name << endl;
    }
};
int main() {
    Dog dog1("旺财");           // 普通构造
    
    Dog dog2(dog1);             // 调用拷贝构造
    // 输出: 复制: 旺财 → copy_of_旺财
    
    Dog dog3 = dog1;            // 也调用拷贝构造
    // 输出: 复制: 旺财 → copy_of_旺财
    
    return 0;
}注意事项:调用默认构造函数,不要加(),会被认为是一个函数的声明
Person p; // ✅ 调用无参构造,创建对象
Person p( ); // ❌ 这是一个函数声明!不是创建对象
拷贝构造函数调用时机:
1.使用一个已经创建完毕的对象来初始化一个新对象
2.值传递的方式给函数参数传值
3.值方式返回局部对象
            
            
              c++
              
              
            
          
          class Person {
public:
    // 拷贝构造函数
    Person(const Person& p) {
        cout << "拷贝构造函数被调用" << endl;
    }
};
int main() {
    Person p1;
    
    // 1. 用已创建的对象初始化新对象
    Person p2(p1);        // ✅
    Person p3 = p1;       // ✅
    
    // 2. 值传递给函数参数
    void func(Person p);  // 传参时调用拷贝构造
    func(p1);
    
    // 3. 值方式返回局部对象
    Person create() {
        Person temp;
        return temp;  // 返回时可能调用拷贝构造
    }
    
    return 0;
}构造函数调用规则:创建一个类,编译器会给每个类都添加至少3个函数
分别是默认构造函数 、默认析构函数 、拷贝构造(值拷贝)
如果用户定义有参构造函数,c++不提供默认无参构造,会提供默认拷贝构造
如果用户定义拷贝构造函数,c++不会在提供其他构造函数
3. 深拷贝与浅拷贝
4.初始化列表
5.类对象作为成员
6.静态成员
7.对象模型和this指针
8.友元
9.运算符重载
继承
多态
提高知识
模版
C++的另一种编程思想称为泛型编程,主要利用的技术就是模版;
C++提供两种模版机制:函数模版 和类模版
模版的语法:
            
            
              c++
              
              
            
          
          template<typename T>
函数声明或定义
解释:
template ---声明创建模版
typename ---表明其后面的符号是一种数据类型,可以用class代替
T ---通用的数据类型,通常为大写字母注意事项:
自动类型推导,必须推导出一致的数据类型T,才可以使用
模版必须要确定出T的数据类型,才可以使用
普通函数与函数模版区别:
普通函数调用可以发生隐式类型转换,函数模板调用不会发生隐式类型转换
如果利用显示指定类型的方式,可以发生隐式类型转换
普通函数与函数模版的调用规则:
如果函数模版和普通函数都可以实现,优先调用普通函数
可以通过空模版参数列表来强制调用函数模版
函数模版也可以发生重载
如果函数模版可以产生更好的匹配,优先调用函数模版
类模版
语法:
            
            
              c++
              
              
            
          
          template <typename T>
类
解释:
template  ---声明创建末模板
typename ---表明其后面的符号是一种数据类型,可以用class代替
T   ---通用的数据类型STL(Standard Template Library)
STL基本概念
STL从广义上分为容器(container)算法(algorithm)迭代器(iterator)
算法和容器之间通过迭代器进行无缝连接
STL六大组件
容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
1.容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据
2.算法:各种常用的算法
3.迭代器:扮演了容器与算法之间的胶合剂
4.仿函数:行为类似函数
5.适配器:一种用来修饰容器或者仿函数或迭代器接口的东西
6.空间配置器:负责空间的配置与管理
容器:
STL容器就是将运用最广泛的一些数据结构实现出来
常用的数据结构:数组、链表、树、队列、集合、映射表等
这些容器分为序列式容器和关联式容器:
 序列式容器:强调值的排序,序列式容器中的每个元素均有固定的关系
 关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系
算法(ALgorithms)
算法分为:质变算法和非质变算法
 质变算法:是指运算过程中会更改区间内元素的内容,例如拷贝、替换、删除等等
 非质变算法:是指运算过程中不会更改区间内元素内容,例如查找、计数、遍历、寻找极值等
迭代器:
提供一种方法,使之能够依寻访问某个日期所含的各个元素,而有又无需暴露该容器的内部表示方式
种类:
| 种类 | 功能 | 支持运算 | 
|---|---|---|
| 输入迭代器 | 对数据的只读访问 | 只读,,++、==、!= | 
| 输出迭代器 | 对数据的只写访问 | 只写,++ | 
| 前向迭代器 | 读写操作,并向前推进迭代器 | 读写,++、==、!= | 
| 双向迭代器 | 读写操作,并能向前和向后操作 | 读写,++,-- | 
| 随机访问迭代器 | 读写操作,可以以跳跃的方式访问任意数据 | 读写,++,--,[n],-n、<、<=、>、>= | 
容器算法迭代器初识
vector存放内置数据类型
容器: vector
算法: for_each
迭代器: vector<int>::iterator