CD3.【C++ Dev】头文件、缺省参数
目录
1.头文件为什么没有以.h为后缀
2.缺省参数
单参
多参
注意
全缺省和半缺省
缺省参数的规则
1.函数的定义
2.如果函数有声明,不能在定义中写缺省参数的默认值
缺省参数的应用
1.头文件为什么没有以.h为后缀
现代C++的头文件都是不带.h的,例如<iostream>、<vector>、<queue>等,其实很早以前是带.h的
例如C++之父写的头文件:https://www.softwarepreservation.org/projects/c_plus_plus/cfront/release_1.0/src/cfront.tar.gz
不带.h是为了和带.h的区分,也防止头文件的名字和C语言的冲突
2.缺省参数
缺省含义与“默认”相同,缺省参数即默认参数
单参
示例代码
#include <iostream>
using namespace std;
void function(int a = 0)
{
cout << "a==" << a << endl;
}
int main()
{
function();
function(1);
return 0;
}
运行结果
解释:function();没有传参,而函数的定义上的形参表写着int a = 0,说明如果不传参则a的默认值为0
function(1);为a指定了值,即a的值为1
结论:如果没有传参,那么使用参数的默认值;如果传参,那么使用指定的实参
多参
示例代码
#include <iostream>
using namespace std;
void function(int a = 0, int b = 1, int c = 2)
{
cout << "a==" << a << endl;
cout << "b==" << b << endl;
cout << "c==" << c << endl;
cout << "------------" << endl;
}
int main()
{
function();
function(1);
function(1, 2);
function(1, 2, 3);
return 0;
}
运行结果
从代码中可以看出,如果有多个参数,则参数是从左向右传给a,b,c的,例如function(1, 2);说明a的值为1,b的值为2,c没有传值,则使用默认的值2
结论:从左往右为参数分配数据
注意
不能跳跃着传参!
例如void function(int a = 0, int b = 1, int c = 2){......},不能为a和c传值而不为c传值,即不能写成function(1,,2);C++不允许这种写法
全缺省和半缺省
全缺省指全部使用缺省参数
半缺省不是指缺省一半的参数,而是指部分使用缺省参数
例如:
#include <iostream>
using namespace std;
void function(int a = 0, int b = 1, int c = 2)
{
//......
}
int main()
{
function();//全缺省
function(1);//半缺省
function(1, 2);//半缺省
return 0;
}
缺省参数的规则
1.函数的定义
下面的代码的函数的写法是错误的,没有遵守缺省参数的规则
void function(int a = 0, int b = 1, int c)
{
//......
}
VS上的报错显示: error C2548: “function”: 缺少形参 3 的默认实参
例如:function(1),这个1给a还是给c的呢?有歧义,不允许这样写!
改成下面这样就行了
void function(int c,int a = 0, int b = 1)
{
//......
}
结论:从右往左缺省,为了防止歧义,即所有有默认值的参数必须位于参数列表的末尾
2.如果函数有声明,不能在定义中写缺省参数的默认值
从下面这个应用讲起:
缺省参数的应用
可以改造栈的初始化,之前在99.【C语言】数据结构之栈文章中模拟过栈,部分代码如下:
typedef struct stack
{
int* a;
int capacity;
int top;
}ST;
void STInit(ST* ps)
{
ps->a = (int*)malloc(sizeof(int) * 4);
if (ps->a == NULL)
{
perror("malloc");
return;
}
ps->capacity = 4;
ps->top = 0;//top栈顶元素的下一个位置
}
上面的4可以用缺省参数来写,如下
void STInit(ST* ps, int default_capacity = 4)
{
ps->a = (int*)malloc(sizeof(int) * default_capacity);
if (ps->a == NULL)
{
perror("malloc");
return;
}
ps->capacity = default_capacity;
ps->top = 0;//top栈顶元素的下一个位置
}
int main()
{
ST st1,st2;
STInit(&st1);//使用默认的大小,为4
STInit(&st2,10);//使用指定的大小
return 0;
}
可以对比C语言的写法:
#define default_capacity 4
void STInit(ST* ps)
{
ps->a = (int*)malloc(sizeof(int) * default_capacity);
if (ps->a == NULL)
{
perror("malloc");
return;
}
ps->capacity = default_capacity;
ps->top = 0;//top栈顶元素的下一个位置
}
发现用宏定义没有用缺省参数来的方便
确保各个文件写入了以下代码:
stack.h:
#pragma once
#include <iostream>
#include <stdlib.h>
typedef struct stack
{
int* a;
int capacity;
int top;
}ST;
void STInit(ST* ps, int default_capacity = 4);
stack.cpp
#include "stack.h"
void STInit(ST* ps, int default_capacity = 4)
{
ps->a = (int*)malloc(sizeof(int) * default_capacity);
if (ps->a == NULL)
{
perror("malloc");
return;
}
ps->capacity = default_capacity;
ps->top = 0;//top栈顶元素的下一个位置
}
main.cpp
#include "stack.h"
using namespace std;
int main()
{
ST st1,st2;
STInit(&st1);//使用默认的大小,为4
STInit(&st2,10);//使用指定的大小
return 0;
}
编译时报错: error C2572: “STInit”: 重定义默认参数 : 参数 1
简单原因:定义不用写缺省参数,防止函数定义和函数声明的缺省参数不一致
改成下面这样就能编译通过了