前言
在设计一个程序之前,可以把它提前分解好
,这个程序大概需要什么功能;在设计阶段,具体的代码实现
不必去考虑,从而实现团队协作,这就是架构能力。
一.函数的使用场景
当代码超过一屏,就需要把多行代码中的变量
抽离成函数参数
,封装成函数进行调用,使得数据流
具有层次感。
二.指针(参数类型)
应用场景:避免内存空间的
重复申请
(局部变量,实参),可以把形参设计为局部变量的指针
,从而使得函数内部可以直接
访问它
里面的值。
#include <iostream>
#include <bitset>
using namespace std;
int Add(int x, int y) {
x *= 100;
y *= 10;
return x + y;
}
int main(int count, char* argv[], char* env[])
{
int x = 2, y = 1;
int c = Add(x, y);
std::cout << "c=" << c << "x=" << x << "y=" << y;
}
常量指针:这个指针存储的值
只能读取
,不能写入。(用于保护一段重要数据)
三.数组(参数类型)
0x1
一维数组
没有效率上
的影响,底层汇编
是一样的。建议使用左边
的表达形式,这样很容易就知道传递进来的数据结构
就是数组
0x1
二维数组(必须使用数组形式
传递)
#include <iostream>
#include <bitset>
using namespace std;
void Sort(int ary[][2], unsigned count) {
};
int main(int count, char* argv[], char* env[])
{
int a[3][2]{ {1,2},{3,4},{5,6} };
Sort(a, 3);
}
四.引用(参数类型)
0x1 访问方式
和调用方式
的改变了;调用的时候实参不能为空指针
;
bool Act(const Role& Acter, Role& beAct) {
beAct.hp -= Acter.damage;
return beAct.hp < 0;
}
int main(int count, char* argv[], char* env[])
{
Role user{ 200, 300, 850 };
Role monster{ 800, 300, 50 };
if (Act(user, monster)) std::cout << "死掉了!";
}
0x2 Role*&
遇到再去重新理解。
五.默认参数
0x1 默认参数只能
放在最后面,否则编译会报错
0x2 可以有多个
默认参数
void Swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
void Sort(int arr[], unsigned count, bool isRise = true)
{
for (int i = 1; i < count; i++)
{
for (int i = 1; i < count; i++)
{
bool bcase = isRise ? arr[i] < arr[i - 1] : arr[i] > arr[i - 1];
if (bcase) Swap(arr[i], arr[i-1]);
}
}
};
int main(int count, char* argv[], char* env[])
{
int arr[5]{ 11,33,10,56,28 };
Sort(arr, sizeof(arr) / sizeof(int));
for (auto x : arr) std::cout << x << std::endl;
return 0;
}
六.不定量参数(数组形式)
#include <iostream>
#include <bitset>
using namespace std;
int main(int argCount/*有效参数个数*/, char* argv[], char* env[])
{
//std::cout << "argCout:" << argCount << (char)10;
//int* ptr = (int*)argv[1];
//std::cout << std::hex << ptr << std::endl;
//int pNum = sizeof(*env) / 4;
for (int i =0;env[i];i++)
{
std::cout << "第" << i << "个环境变量" << env[i] << (char)10;
}
}
练习1:获取程序路径和名称
#include <iostream>
using namespace std;
int main(int argCount/*有效参数个数*/, char* argv[], char* env[])
{
int end = strlen(argv[0]) - 1;
char* ptrStr = argv[0];
for (; end; end--)
{
if (ptrStr[end] == '\\') {
ptrStr[end] = 0;
break;
}
}
std::cout << "程序路径:" << ptrStr << (char)10;
std::cout << "程序名称:" << ptrStr + end+1 << (char)10;
}
七.不定量参数二(目的:体会这个设计思维,在实际中不推荐使用)
有空的时候再去看
毕业项目:注册命令的设计
#include <iostream>
#include <map>
#include <string>
using namespace std;
void argParse(map<string, char*>& mapArg, char* argv[]) {
mapArg["exeName"] = argv[0];
for (size_t i = 1; argv[i]; i++)
{
string mapKey{};
char* ptr = argv[i];
size_t index{};/*字符数组索引值*/
for (; ptr[index] != ':'; index++) mapKey += ptr[index];
mapArg[mapKey] = ptr + index;
}
};
void Print(int argCount, map<string, char*>& mapArg) {
if (argCount == 2) cout << "没有帮助信息!请自己尝试,啊啊哈哈哈哈哈哈";
else if (argCount == 1) {}
else{
cout << "注册成功!" << (char)10;
cout << "=======================" << (char)10;
cout << "账号:" << mapArg["id"] << (char)10;
cout << "密码:" << mapArg["pass"] << (char)10;
cout << "国家:" << mapArg["country"] << (char)10;
};
}
int main(int argCount/*有效参数个数*/, char* argv[], char* env[])
{
//用户输入格式:"x86Study.exe id:wutongshan pass:wish_123 country:China"
map<string, char*> mapArg;
argParse(mapArg, argv);
Print(argCount, mapArg);
return 0;
}
八.函数返回值(指针和引用)
原则1:不返回局部变量
#include <iostream>
using namespace std;
int clen(const char* str) {
int i;
for (i = 0; str[i]; i++);
return ++i;
}
char* cstr(const char* str) {
size_t len = clen(str);
char strRet[20];
memcpy(strRet, str, len);
return strRet;
}
int main(int argCount/*有效参数个数*/, char* argv[], char* env[])
{
char* str;
str = cstr("rffasfjsa");
cout << str;
}
原则2:禁止返回结构体
(性能损失太大)
反复练习返回指针
和引用
九.右值引用
用到的时候再认真去看
十.函数的本质
函数名是内存地址
;函数的功能是编译好的二进制代码