1. 函数的语法
返回类型 函数名称(参数,参数,...)
{
函数的功能区
return 返回值;
}
int Add (int a, int b)
{
char c = a + b;
return c;
}
2. 函数参数
2.1. 指针参数
2.1.1. 概念
指针参考:C++笔记:指针(1)
int add(int* a, int* b) {
(*a) += 100;
(*b) += 10;
return (*a) + (*b);
}
int main() {
int a = 2, b= 1;
int c = add(&a, &b);
}
2.1.2. 指针参数的应用场景
- 使用结构体,参数
Role rl
占用内存16字节;
struct Role {
int hp;
int mp;
int dp;
int lp;
};
int Exp(Role rl) {
return rl.hp + rl.mp + rl.dp + rl.lp;
}
int main()
{
Role rl{ 200, 300 100, 50};
int c = Exp(rl);
}
- 使用指针参数
Role * rl
,才占用8个字节(64位指针占用8个字节。42位4个字节)
int Exp(Role* rl) {
return rl->hp + rl->mp + rl->dp + rl->lp;
}
int main()
{
Role rl{ 200, 300 100, 50};
int c = Exp(&rl);
}
2.2. 数组参数
2.2.1. 常规数组参数
因为数组的本质是一块连续的内存,所以数组参数本质还是传递指针,但是数组内存是连续的,所以除了指针,还必须要有元素的数量;
申明方式:
返回值 函数名(数组参数, unsigned count)
(推荐这种。同下,底层一样,效率一样,这种便于阅读。)返回值 函数名(指针参数, unsigned count)
void Sort(int ary[], unsigned count)
{
std::cout << sizeof(a);
}
void Sort(int* a, unsigned count)
{
std::cout << sizeof(a);
}
int main()
{
int a[5]{ 23, 33, 24, 26 };
Sort(a, 5);
}
2.2.2. 多维数组参数
- 注意:多维数组参数 第二维一定要指定具体数值,只能有第一维的变量;
void Sort(int ary[][2], unsigned cout) {
}
int main() {
int a[3][2]{{1, 2,}, {3, 4}, {5, 6}};
Sort(a, 3);
}
2.3. 引用参数
2.3.1. 概念
引用:C++笔记:引用;
注意:指针可以传入nullptr空指针,而引用不可以。
struct Role
{
int hp;
int mp;
int damage;
}
bool Act(const Role& Acter, Role*& beAct)
{
beAct->hp -= Acter.damage;
return beAct->hp < 0;
}
int main()
{
Role user {200, 300, 1000};
Role monster {80, 90, 200};
Role* pRole = &monster;
if(Act(user, pRole)) std::cout <<"123"<< std::endl;
}
解析:Role*& beAct
: Role*
指针类型的引用,所以本质还是一个引用;
2.4. 默认参数
格式:
void Sort(int ary[], unsigned count, bool bigSort = true);
注意:默认参数只能放在最后。
2.5. 不定量参数
2.5.1.
int main(int argcount, char* c_arg[])
{
std::cout << "一共有" << argcount << "个参数" << std::endl;
for (int i = 0; i < argcount; i++) std::cout << "参数【" << i << "】=【" << c_arg[i] << "】\n";
for (int i = 0; c_arg[i]; i++) std::cout << "参数【" << i << "】=【" << c_arg[i] << "】\n";
}
2.5.2.
- 格式:
int Add(unsigned count, ...)
- 特点:用数组做参数,元素都是相同的数据类型,用这种方式,可以混合各种类型的数据。
int test(int count, ...) {
//va_list arg; va_list 返回的就是 char*类型
char* arg;
//初始化
va_start(arg, count); //一个初始地址,一个数组个数
//读,每读一次,依次显示下一个数据
int x = va_arg(arg, int); //地址,要读的数据类型
std::cout << x << std::endl;
x = va_arg(arg, int);
std::cout << x << std::endl;
x = va_arg(arg, int);
std::cout << x << std::endl;
va_end(arg); //释放指针
return x;
}
int Add(unsigned cout, ...) {
int rt{};
char* c_arg; //声明一个指针变量
va_start(c_arg, cout); //将参数数据指针赋值给c_arg
std::cout << "start:" << std::hex << (int)c_arg;
for (int i = 0; i < cout; i++) {
std::cout << "\nc_arg:" << std::hex << (int)c_arg;
rt += va_arg(c_arg, int); //以 int 类型来读取c_arg
}
va_end(c_arg); //释放指针
return rt;
}
int main(int count, char* arc[]) {
int x = test(5, 2344, 354, 523, 5322, 235465);
std::cout << "\n和 = " << Add(5, 1, 2, 3, 4, 5) << std::endl;
return 0;
}
start:cffd24
c_arg:cffd24
c_arg:cffd28
c_arg:cffd2c
c_arg:cffd30
c_arg:cffd34
- 由打印结果可验证,每次
va_arg
获取值之后,指针c_arg
的地址就是偏移一个目标数据类型(如int
)的量。
2.6. 练习
E:\Learn\C++\函数_1\Debug>test id:123 pass:qwe country:China
char* ReadRef(const char*ref, const char* cmds)
{
for (int i = 0; cmds[i]; i++)
{
if (cmds[i] == ref[0])
{
bool bfind = true;
int x;
for (x = 0; ref[x]; x++)
{
if (ref[x] != cmds[i + x])
{
bfind = false;
break;
}
}
if (bfind) return (char*)&cmds[i + x];
}
}
return nullptr;
}
int main(int count, char* arc[]) {
char* id{};
char* pass{};
char* country{};
const char* idRef{ "id:" };
const char* passRef{ "pass:" };
const char* countryRef{ "country:" };
for (int i = 1; arc[i]; i++)
{
if (id == nullptr)
{
id = ReadRef(idRef, arc[i]);
if (id != nullptr) continue;
}
if (pass == nullptr)
{
pass = ReadRef(passRef, arc[i]);
if (pass != nullptr) continue;
}
if (country == nullptr)
{
country = ReadRef(countryRef, arc[i]);
if (country != nullptr) continue;
}
}
if ((int)id* (int)pass * (int)country)
{
std::cout << "账号:" << id << std::endl;
std::cout << "密码:" << pass << std::endl;
std::cout << "国家:" << country << std::endl;
}
else
{
std::cout << "格式错误" << std::endl;
}
}