实参是函数调用的实际值,是形参的初始值
int f()
{
int s;
//...
return s;
}
void f2(int i) {/*...*/}
int clac(int v1,int v2) {/*...*/}
double square(double x) {return x*x;}
#include
using namespace std;
int fact(int val);
int main()
{
cout << fact(5) << endl;
return 0;
}
int fact(int val)
{
int ret = 1;
while (val > 1)
{
ret *= val--;
}
return ret;
}
#include
using namespace std;
int fact(int val);
int main()
{
cout << "Please enter a number: " << endl;
int i = 0;
cin >> i;
cout << fact(i);
}
int fact(int val)
{
int ret = 1;
while (val > 1)
{
ret *= val--;
}
return ret;
}
#include
using namespace std;
double myAbs(double val);
int main()
{
cout << "Please enter a number: " << endl;
double i = 0;
cin >> i;
cout << myAbs(i);
}
double myAbs(double val)
{
if (val > 0)
return val;
else
return - 1 * val;
}
形参定义在函数形参列表里面;局部变量定义在代码块里面;局部静态变量在程序的执行路径第一次经过对象定义语句时初始化,并且直到程序终止时才被销毁
#include
#include
using namespace std;
void fun(int val);
int main()
{
fun(3);
fun(8);
fun(5);
fun(7);
}
void fun(int val)
{
static int p = 0;
int ret = val;
while (ret > 1)
{
cout << "*";
--ret;
}
cout << " " << ++p <<" Times"<< endl;
}
#include
using namespace std;
int pplus();
int main()
{
cout << pplus() << endl;
cout << pplus() << endl;
cout << pplus() << endl;
}
int pplus()
{
static int p = 0;
return p++;
}
Chapter6.h文件
int fact(int val);
double myAbs(double val);
fact.cpp文件
#include "Chapter6.h"
int fact(int val)
{
int ret = 1;
while (val > 1)
{
ret *= val--;
}
return ret;
}
factMain.cpp文件
#include
#include "Chapter6.h"
using namespace std;
int main()
{
cout << fact(5);
return 0;
}
#include
using namespace std;
void mySwap(int* a, int* b);
int main()
{
int i = 99, j = 1;
cout << i << " " << j << endl;
mySwap(&i, &j);
cout << i << " " << j << endl;
return 0;
}
void mySwap(int* a, int* b)
{
int temp = 0;
temp = *a;
*a = *b;
*b = temp;
}
#include
using namespace std;
void reset(int& val);
int main()
{
int i = 100;
cout << i << endl;
reset(i);
cout << i;
return 0;
}
void reset(int& val)
{
val = 0;
}
#include
using namespace std;
void swap(int& a, int& b);
int main()
{
int i = 999, j = 888;
cout << i << " " << j << endl;
swap(i, j);
cout << i << " " << j << endl;
return 0;
}
void swap(int& a, int& b)
{
a = a + b;
b = a - b;
a = a - b;
}
引用更易于使用,更加简洁
void f(T)
的参数通过值传递,在函数中 T 是实参的副本,改变T不会影响到原来的实参void f(T&)
的参数通过引用传递,在函数中的T是实参的引用,T的改变也就是实参的改变交换两个整数的值时,形参应该是引用类型,当实参是右值时,形参不应该是引用类型
s是常量引用是因为,string字符串可能很大,使用引用效率较高,而函数并不会改变s,故使用常量。c是普通char,是因为c可能会是一个右值,故不能是引用。occurs是普通引用是因为,函数要改变它,故用引用,也因此不能是常量。
常量字符串和字符串字面值无法作为该函数的实参,改为
bool is_empty(const string &s) {return s.empty();}
#include
#include
using namespace std;
bool isBig(const string &s);
string toSmall(string &s);
int main()
{
if (isBig("huShun"))
{
cout << "yes" << endl;
}
else
{
cout << "no" << endl;
}
string s = "HUsHuN";
cout << toSmall(s);
return 0;
}
bool isBig(const string &s)
{
for (char ch : s)
{
if (isupper(ch))
return true;
}
return false;
}
string toSmall(string &s)
{
for (char &ch : s)
{
ch = tolower(ch);
}
return s;
}
不一样,isBig不改变s,为常量引用,toSmall改变s,为普通引用
bool compare(matrix&,matrix&);
vector::iterator change_val(int,vector::iterator);
应该尽量将引用形参设为常量引用,除非有明确的目的是为了改变这个引用变量。如果形参应该是常量引用,而我们将其设为了普通引用,那么常量实参将无法作用于普通引用形参
#include
using namespace std;
int whoBig(const int i, const int *j);
int main()
{
int a = 100, b = 108;
cout << whoBig(a, &b);
return 0;
}
int whoBig(const int i, const int *j)
{
return i > *j ? i : *j;
}
应该是const int*
#include
using namespace std;
void swapAdd(int *&p1, int *&p2);
int main()
{
int i = 999, j = 0, *p1 = &i, *p2 = &j;
cout << *p1 << " " << *p2 << endl;
swapAdd(p1, p2);
cout << *p1 << " " << *p2 << endl;
}
void swapAdd(int *&p1, int *&p2)
{
int *temp = p1;
p1 = p2;
p2 = temp;
}
#include
using namespace std;
void print(const int i);
void print(const int *arr, int i);
int main()
{
int i = 0, j[8] = { 0,1,9,14,45 };
print(i);
cout << endl;
print(j,8);
return 0;
}
void print(const int i)
{
cout << i;
}
void print(const int *arr, int i)
{
for (int n = 0; n < i; ++n)
cout << arr[n] << " ";
}
当数组作为实参的时候,会被自动转换为指向首元素的指针。因此函数形参接受的是一个指针。如果要让这个代码成功运行,可以将实参改为数组的引用
void print(const int (&ia)[10])
{
for (size_t i = 0; i != 10; ++i)
cout << ia[i] << endl;
}
#include
#include
int main(int argc, char **argv)
{
std::string str;
for (int i = 1; i != argc; ++i)
str += std::string(argv[i]) + " ";
std::cout << str << std::endl;
return 0;
}
#include
#include
int main(int argc, char **argv)
{
std::string str;
for (int i = 1; i != argc; ++i)
str += std::string(argv[i]) + " ";
std::cout << str << std::endl;
return 0;
}
#include
using namespace std;
int sum(initializer_list il);
int main()
{
cout << sum({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
return 0;
}
int sum(initializer_list il)
{
int sum = 0;
for (auto beg = il.begin(); beg != il.end(); ++beg)
sum += *beg;
return sum;
}
const string&
应该使用常量引用类型。initializer_list
对象中的元素都是常量,我们无法修改initializer_list
对象中的元素的值
当返回局部变量的引用时无效。当我们希望返回的对象被修改时,返回常量的引用无效。
合法,get函数返回数组各元素的引用
#include
#include
using namespace std;
typedef vector::const_iterator itc;
void print(itc first,itc last);
int main()
{
vector ivec = { 0,9,8 };
print(ivec.cbegin(),ivec.cend());
return 0;
}
void print(itc first, itc last)
{
if (first == last)
return;
cout << *first << " ";
print(++first, last);
}
如果val小于0,则递归调用永远不会结束
val–返回改变前的值的副本,即一直传入相同的值来调用函数,函数永不结束
string (&func())[10];
using str_arr=string[10];str_arr& func();
auto func()->string(&)[10];
string s[10];decltype(s)& func();
尾置返回类型更好,更简洁明了
decltype(odd)& arrPtr(int i)
{
return (i % 2) ? odd : even;
}
#include
#include
using namespace std;
string make_plural(int ctr, const string &word, const string &ending = "s")
{
return (ctr > 1) ? word + ending : word;
}
int main()
{
cout<< make_plural(1, "success", "es") << " "
<< make_plural(1, "failure") << endl;
cout<< make_plural(2, "success", "es") << " "
<< make_plural(2, "failure") << endl;
return 0;
}
inline bool is_shorter(const string &lft, const string &rht)
{
return lft.size() < rht.size();
}
一般来说,内联机制用于优化规模小、流程直接、频繁调用的函数
不能。constexpr函数的返回值类型及所有形参都得是字面值类型
#include
#include
using namespace std;
using Iter = vector::const_iterator;
#define NDEBUG
void print(Iter first, Iter last)
{
#ifndef NDEBUG
cout << "vector size: " << last - first << endl;
#endif
if (first == last)
return;
cout << *first << " ";
print(++first, last);
}
int main()
{
vector vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
print(vec.cbegin(), vec.cend());
return 0;
}
不合理
候选函数:与被调用函数同名,其声明在调用点可见
可行函数:其形参数目与本次调用提供的实参数量相等,每个实参的类型与对应的形参类型相同,或者能转换成形参的类型
首先对这四个函数编号依次为1,2,3,4号
#include
using namespace std;
void f() { cout << 1 << endl; }
void f(int) { cout << 2 << endl; }
void f(int, int) { cout << 3 << endl; }
void f(double, double = 3.14) { cout << 4 << endl; }
int main()
{
f(2.56, 42);
f(42);
f(42, 0);
f(2.56, 3.14);
return 0;
}
int fun(int,int);
vector
#include
#include
using namespace std;
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return b != 0 ? a / b : 0; }
int main()
{
int func(int, int);
vector v;
v.push_back(add);
v.push_back(subtract);
v.push_back(multiply);
v.push_back(divide);
for (auto i : v)
{
cout << i(6, 2) << " "; // 8, 4, 12, 3
}
cout << endl;
return 0;
}
8, 4, 12, 3