函数重载
在这个问题前需弄明白,为什么c语言不支持函数重载,而祖师爷在c++创作出来却支持,c与c++的思考方式到底有那些区别
#include<iostream>
using namespace std;
void func(int i, double d)
{
cout << "void func(int i, double d)" << endl;
}
void func(double d, int i)
{
cout << "void func(int i, double d)" << endl;
}
int main()
{
func(1, 1.1);
func(1.1, 1);
}
从本质开始,代码运行后会经历一下四个阶段:
test.cpp :预处理 头文件展开/宏替换/去掉注释/条件编译
test.i :编译 检查语法, 生成汇编代码(指令级代码)
test.s :汇编 将汇编代码生成二进制机械码
test.o :链接 合并链接, 生成可执行程序
于是c++在编译时与c产生差别,使其能分辨同名韩式使函数重载,这个规则是函数名修饰规则
c++修饰规则:
在编译中讲int类型记作H,double类型记作N,以不同的标记使函数重载,来分开同名函数。
c语言修饰规则:
仅仅只是用函数名字来区分,并不会深入分析,这就造成c语言无法开辟同名函数。
但是返回值有无情况下无法构成函数重载:
除非使用红字方式,但是这样颇为麻烦。最后附上一张转换表。
引用:
引用使本贾尼祖师爷为了修改指针的不足而设立。
void TestRef()
{
int a = 10;
int& ra = a;
printf("%p\n", &a);
printf("%p\n", &ra);
}
引用特性:
1,引用在定义时必须初始化。
2,一个变量可以多个引用。
3,引用一旦引用一个实体,在不能引用其他实体。
void TestRef()
{
int b = 0;
int a = 10;
int& ra = a;
int& ra = b;//无法再次引用
printf("%p\n", &a);
printf("%p\n", &ra);
}
引用对我们的好处:
1,
void swap(int& x1, int& x2)
{
int tmp = x1;
x1 = x2;
x2 = tmp;
}
int main()
{
int size;
preorderTraversal(nullptr, size);
int x = 0, y = 1;
swap(x, y);/这里能够直接交换。
return 0;
}
2,c的玩法:
//c语言二级指针的玩法
void PushBack(ListNode** pphead, int x)
{
ListNode* newnode;
if (*pphead == NULL)
{
*pphead = newnode;
}
else
{
}
}
int main()
{
ListNode* plist = NULL;
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
return 0;
}
c++玩法:
// CPP,引用的玩法
void PushBack(ListNode*& phead, int x)
//void PushBack(PListNode& phead, int x)//取ListNode地址
{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
// ...
if (phead == NULL)
{
phead = newnode;
}
else
{
}
}
int main()
{
ListNode* plist = NULL;
PushBack(plist, 1);
PushBack(plist, 2);
PushBack(plist, 3);
return 0;
}
关于有返回值函数的调用:
int Count1()
{
int n = 0;
n++;
// ...
return n;
}
int& Count2()
{
int n = 0;
n++;
// ...
return n;
}
int main()
{
int ret = Count1();//值会正常传,但是可能是1,可能是随机值,但是值未被清,正常传
int ret = Count2();// 这里打印的结果可能是1,也可能是随机值,是值被清,无法传
cout << ret << endl;
cout << ret << endl;
return 0;
}
传值和引用作为函数参数传参的速度比较:
#include <time.h>
struct A { int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a; }
// 引用返回
A& TestFunc2() { return a; }
void TestReturnByRefOrValue()
{
// 以值作为函数的返回值类型
size_t begin1 = clock();
for (size_t i = 0; i < 100000; ++i)
TestFunc1();
size_t end1 = clock();
// 以引用作为函数的返回值类型
size_t begin2 = clock();
for (size_t i = 0; i < 100000; ++i)
TestFunc2();
size_t end2 = clock();
// 计算两个函数运算完成之后的时间
cout << "TestFunc1 time:" << end1 - begin1 << endl;
cout << "TestFunc2 time:" << end2 - begin2 << endl;
}
// 传引用传参(任何时候都可以用)
// 1、提高效率
// 2、输出型参数(形参的修改,影响的实参)
// 传引用返回(出了函数作用域对象还在才可以用)!!!
// 1、提高效率
// 2、修改返回对象
c++比c修改值方便的最后一处:
C的接口设计
读取第i个位置的值
int SLAT(struct SeqList* ps, int i)
{
assert(i < ps->size);
// ...
return ps->a[i];
}
修改第i个位置的值
void SLModify(struct SeqList* ps, int i, int x)
{
assert(i < ps->size);
// ...
ps->a[i] = x;
}
CPP接口设计
读 or 修改第i个位置的值
int& SLAT(struct SeqList& ps, int i)
{
assert(i < ps.size);
// ...
return (ps.a[i]);
}
int main()
{
struct SeqList s;
s.size = 3;
// ...
SLAT(s, 0) = 10;
SLAT(s, 1) = 20;
SLAT(s, 2) = 30;
cout << SLAT(s, 0) << endl;
cout << SLAT(s, 1) << endl;
cout << SLAT(s, 2) << endl;
return 0;
}
最后,引用只能缩小或者平等原来的权力,不能超过:
int func()
{
int a = 0;
return a;
}
int main()
{
const int& ret = func();
const int a = 0;
// 权限的放大
// int& b = a;
//int b = a; 可以的,因为这里是赋值拷贝,b修改不影响a
// 权限的平移
const int& c = a;
// 权限的缩小
int x = 0;
const int& y = x;
int i = 0;
const double& d = i;
return 0;
}
新手还有诸多不足,多多包涵!!!