重点
函数传递参数(接收数据)时,默认是多复制一份数据,不更改原数据(数组除外)
若传递参数为数组,则复制数组地址。可更改原数据。
函数传递参数,不想被多复制一份数据,直接引用时,需要在函数形参前面,加&符号。
不想被更改可以使用常量,需要在函数形参前面,加 const 。
重载:函数名相同,传递参数类型不同,是两个函数。
C++会自动判断输入的数据类型选择不同的函数执行。一般使用函数模板对应不同类型的参数情况。
函数
#include <iostream>
#include <vector>
#include <cstring>
using namespace std; // 命名空间定义 使用C++标识符 例如:cout
// 前向声明函数(无需先定义函数再调用)
// void SB(vector <int>);
void SB(vector<string> v);
int main()
{
// vector <int> my_vec{1, 2, 3};
vector<string> my_vec{"1","2","3"};
SB(my_vec);
return 0;
}
void SB(vector<string> v) // void 代表 无返回内容。
{
cout << "你觉得呢?" << endl;
for (auto i:v)
{
cout << i << endl;
}
}
函数内不释放变量(内存) 静态变量 (static) 静态函数 (static)
本次演示最简单的静态变量
面向对象的静态函数与静态变量:https://blog.csdn.net/qq_42102546/article/details/128836797
注意: 使用 static 的另一重含义是:当前文件的全局变量,不可以跨文件。
如果你想使用跨文件的全局变量,直接定义即可
例如:int n = 1;
如果你想跨文件获取n,需要在另一个文件中写
extern int n;
关键字:extern 是跨文件获取全局变量
#include <iostream>
#include <string.h>
using namespace std;
// 函数类型为 int 的指针
int* func()
{
// 使用 static 关键字 表示不释放该内存
// 在函数外依然可以调用
static int n = 100;
n++;
// 返回为内存首地址
return &n;
}
int main()
{
int* p = func();
cout << *p << endl;
func();
cout << *p << endl;
func();
cout << *p << endl;
func();
return 0;
}
指针
#include <iostream>
#include <vector> // 导入 vector
using namespace std; // 命名空间定义 使用C++标识符 例如:cout
int main()
{
// 指针 是变量 只存地址 (我的理解:路标用于指明方向,路标本身并不是目的地)
// 指针的大小是不变的,指针指向的数据类型需要固定
int *x1{nullptr}; // nullptr 是空
int f1{10};
int f2{20};
x1 = &f1; // 将f1的地址 放入x1的指针中
cout << "f1:" << &f1 << endl; // 获取f1的地址
cout << "x1:" << x1 << endl; // 获取x1指针的内容
cout << "x1与f1地址是相同的" << endl;
// 修改数据:通过指针操作被指向的数据
*x1 = 11;
cout << "f1:" << *x1 << endl; // 用指针 *x1 获取被指向的数据
// 修改指针指向地址
x1 = &f2;
cout << "f2:" << *x1 << endl;
// 用指针遍历vector容器
vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
// 注意:指针需要指向被遍历的地址
vector<int> *v_{&v};
for (auto i: *v_)
{
cout << i << endl;
}
//多维数组指针
int B[2][2][2] = {
{
{6, 2},
{11, 22},},
{
{111, 222},
{1111, 2222},
} };
// 指针要加括号
int(* pi) = B[0][0];
// 注意优先级 加括号
cout << *(pi + 2) << endl;
return 0;
}
强制更改指针类型
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int x1 = 1;
// 指针 包含 内存首地址与内存空间大小
// 起点:内存首地址
// 终点:内存空间大小
// 步长:类型占多少字节 sizeof()
//
// &获取内存的首地址
int* x2 = &x1;
// sizeof(x2)是 8 为什么?因为指针存储了起点和终点
// sizeof(x1)是 4 看原类型占字节多少是正确的
cout << sizeof(x1) << endl;
cout << x2 << endl;
cout << x2+1 << endl;
cout << *x2 << endl;
// 指针类型强制转换
char* p = (char*)x2;
// 查看类型
cout << typeid(p).name() << endl;
return 0;
}
void 指针
#include <iostream>
#include <string.h>
using namespace std;
void swap(void* x1, int size_1)
{
// 使用 void 指针 舍弃了指针类型(步长或者叫占多少字节sizeof()),只保留了首地址
// 这样就会被指针类型限制
int* x = (int *)x1;
int temp[5];
for (int i = 0; i < size_1; i++)
{
temp[i] = x[i];
cout << "输出:" << x[i] << endl;
}
for (int i = 0; i < size_1; i++)
{
cout << "最后输出:" << temp[i] << endl;
}
}
int main()
{
// 初始数组
int x[3] = { 1, 2, 3 };
// 首地址 赋值给 int类型指针
int* x1 = &x[0];
// 循环次数设定为3
int size_1 = 3;
// 调用函数
swap(x1, size_1);
return 0;
}
多级指针
// 多级指针
int n = 1;
int* n1 = &n;
int** n2 = &n1;
int*** n3 = &n2;
cout << ***n3 << endl; //还可以更多
指针数组
// 指针数组
int arr1[5] = { 1, 2, 3, 4, 5 };
int arr2[5] = { 2, 2, 3, 4, 6 };
int arr3[5] = { 3, 2, 3, 4, 7 };
int* p[3];
p[0] = arr1;
p[1] = arr2;
p[2] = arr3;
for (int i = 0; i < 3; i ++)
{
for (int j = 0; j < 5; j++)
{
// 这两个是等价的
// cout << *(*p+i) + j << endl;
cout << *p[i] + j << endl;
}
cout << "" << endl;
}