端午继续~

        C++对C的扩展

目录

引用

普通变量名引用

对数组的引用

对指针的引用

对函数的引用

引用作为函数的参数

引用作为函数的返回类型

常引用

内联函数

函数重载

函数的默认参数(缺省参数)

默认参数和函数重载的二义性

占位参数

extern "C" 浅析


引用

本质:给变量名取别名,可以通过别名间接操作变量

&:引用说明符(不是取地址符)

给哪个变量取别名,就定义该变量

普通变量名引用

void Test()
{int a = 0;//给变量a取一个别名叫b //&修饰变量为别名,b就是a的别名 --- 引用int& b = a;//必须初始化,这里&不是取地址,是引用
}

注意:系统并不会为引用开辟空间,a,b代表同一个空间。

我们可以看一下地址

void Test()
{int a = 0;//给变量a取一个别名叫b //&修饰变量为别名,b就是a的别名 --- 引用int& b = a;//必须初始化cout << "&a = " << &a << endl;cout << "&b = " << &b << endl;
}

运行结果:

操作b等价于操作a

b = 10; 等价于操作了 a = 10;

对数组的引用

void Test_2()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);//给数组arr取别名my_arr//注意这里要将&my_arr用括号括起来,否则my_arr会先于[10]结合int (&my_arr)[10] = arr;//访问的方式是一样int i = 0;for (i = 0; i < sz; i++){cout << my_arr[i] << " ";}
}

对指针的引用

void Test_3()
{int num = 6;int* p = &num;//给num取别名为 my_num int*& my_num = p;//这里&的优先级高于*,所以可以不用带括号//访问时,与指针的访问方法是一样的cout << "num = " << *my_num << endl;
}

对函数的引用

int main()
{//对函数Test_3取别名为My_Test_3void(&My_Test_3)() = Test_3;//注意括号不可省略//访问My_Test_3();return 0;
}

  这么多例子,我们为什么要用引用,引用能解决什么问题?

        咱往下走~

引用作为函数的参数

这是引用解决的主要问题,函数可以通过引用来操作外部变量

这里学过C语言的小伙伴可能注意到了,引用和指针十分相似

确实如此~

        指针有一些操作比较麻烦地方:

形参是带指针*,并且实参要取地址,相对于来说比较麻烦。

所以在之后的学习中需要用到指针的地方尽量换成用引用

我们来对比一下,指针操作和引用操作,交换两个变量:

void My_exchange_1(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}
void My_exchange_2(int& x, int& y)
{int tmp = x;x = y;y = tmp;
}
int main()
{int a = 6;int b = 8;cout << "交换前:a = " << a << " b = " << b << endl;My_exchange_1(&a, &b);//指针My_exchange_2(a, b);//引用cout << "交换后:a = " << a << " b = " << b << endl;return 0;
}

引用作为函数的返回类型

int& Ret()
{int num = 5;return num;
}
int main()
{int& b = Ret();//由于函数返回类型为int&,所以应该用别名类型来接收//这里相当于间接给num取了一个别名breturn 0;
}

但是,我们都知道,局部变量一旦出了函数,就销毁了,所以这里的相当于你给一个已经释放了的空间取别名,这是不因该的,(会出现段错误)所以函数返回时不应该返回局部变量 !

常引用

简而言之就是给常量取别名

注:不能通过常引用修改内容

可以看到这里编译器会报错,为什么呢?

给10这个常量取别名为num,10是一个常量,但num是一个变量, C++格式要求十分严格,所以这里会报错。

如何解决呢?

const修饰以下即可

有什么用呢?

防止函数内部修改外部的值

观察以下代码:

void Print(const int& x)
{//x = 100 //errcout << "num = " << x << endl;
}
int main()
{int num = 10;Print(num);return 0;
}

我们知道,用引用作为形参可以节省空间,x 和 num 表示一个空间,这里写一个函数,功能就是遍历,但同时我希望他的功能只是遍历,如果一不小心修改了形参 x,也意味着 num 被修改,很危险,所以这里可以用常引用修饰 x,使 x 不可被修改,既提高了安全性,有节省了空间。

内联函数

必须在定义函数的时候使用inline关键字修饰,声明时不需要

string Print();int main()
{cout << Print() << endl;return 0;
}inline string Print()
{string s1 = "端午节";string s2 = "快乐";return s1+s2;
}

直观感受是不是和普通函数差不多?

其实有很大滴作用!

  内联函数:在编译阶段,将内联函数中的函数体 替换 函数调用处 ,避免函数调用时的开销(类似于宏函数,内联函数只是编译阶段直接替换,宏函数在预处理阶段替换)。

注意事项:

1.不能存在任何形式的循环语句

2.不能存在过多的判断语句

3.函数体不能过于庞大

4.不能对函数取地址

所以,加上inline并不是使函数成为内联函数的充要条件,他只是必要条件

加上inline只是告诉编译器,希望使其成为内联函数,最终是不是,还是有编译器决定

函数重载

表示同一个函数在不同的场景下可以有不同的含义

同一个作用域,函数的参数类型,个数,顺序不同都可以重载(返回类型不能作为重载的条件)。

void print_1(int a)
{cout << "int" << endl;
}
void print_1(char a)
{cout << "char" << endl;
}
void print_1(int a, char b)
{cout << "int char" << endl;
}
void print_1(char b, int a)
{cout << "char int" << endl;
}
int main()
{print_1(50);print_1('a');print_1(60,'b');print_1('c',70);//根据参数自动匹配return 0;
}

可以看到这里,函数名都一样,只是参数的类型,个数,顺序不一样,只要一种或多种,都可以重载。

        重载函数的底层原理:实际上这些函数在linux编译之后会产生不同的函数名,然后根据参数自动匹配不同函数的。

函数的默认参数(缺省参数)

#include<iostream>using namespace std;void test_1(int a = 10, int b = 20)//这里的int a = 10,被赋值10,说明只是一个默认参数
{cout << "a + b = " << a + b << endl;
}//注意1
//如果b设为默认参数,则从b往右的参数都必须设为默认参数
//也就是说,此时a不受影响,c是必须设为默认参数
//因为形参位置与实参位置保持一致,假设c没有默认参数
//调用test_2(100,200),这时,a,b都被赋值,c没有赋值,编译器就会报错(缺少参数)void test_2(int a, int b = 20, int c = 30)
{cout << "a + b = " << a + b << endl;
}
//还有值得注意的一点:如果函数声明与函数定义分开,想要设置默认参数,只需在声明里设置即可,函数定义无需再设。
int main()
{test_1();//可以什么参数都不传,这里就会使用默认参数test_1(30);//将30这个实参传给a,这时,函数就不会使用默认参数,而是a = 30;test_1(40, 50);//同理,此时a,b的默认参数失效, a,b的值因为 40 , 50return 0;
}

默认参数和函数重载的二义性

void fun(int a)
{cout << "a = " << a << endl;
}void fun(int a, int b = 20)
{cout << "a = " << a << endl << "b = " << b << endl;
}int main()
{fun(10);return 0;
}

此时编译器会报错:

什么意思呢?

就是说,此时调用fun(10)传入一个参数,既可以传给第一个fun,也可以传给第二个fun(第二个fun的第二个参数有默认参数,所以传入一个参数也正确),编译器不知到传给哪个fun,所以就报错 ,但如果这样调用fun(10,20)就是正确的,他会自动匹配到第二个fun。

占位参数

占位参数只有类型声明,没有参数名声明,一般情况下,函数体内部无法使用占位参数。

//形式一
void test_1(int a , int)
{;//这里的int就是占位参数
}
//形式二
void test_2(int a , int = 20)
{;//int = 20是占位参数,其实这里只是有一个隐形的参数名,但也只是表现形式,无法使用
}
int main()
{test_1(10, 20);//传参依然要传两个,并且类型对应,否则报错(缺少参数)test_2(10);//占位参数有缺省值,所以可以只传一个参数test_2(10, 20);//当然传两个也okkreturn 0;
}

也就是说,占位参数位置必须要传入参数,除非有缺省值。

至于怎么用,以后章节会细讲滴。

extern "C" 浅析

C++编译函数和C编译器编译函数的方式是不同的,假设定义一个Fun函数,经过C编译后会产生一个新的函数名叫Fun,而经过C++编译器编译后产生的新函数名可能(不同的C++编译器效果不一样)叫Funv,所以如果调用函数可能就会存在连接错误,那么为了能在C++的环境下调用C语言函数,就引入了extern "C",这部分代码也将按照C语言的编译方式取运行。

使用如下:

#if __cplusplus //检测当前是否是C++工程
extern "C"//满足则执行这里
{
#endif//不满足则执行这里,因为不满足说明就是C语言工程,直接引用以下就可以extern//引入你想要实现的C语言的函数声明//...;
#if __cplusplus
}
#endif

码字不易~

【C++】引用、内联函数、函数重载、函数默认参数(缺省参数)与占位参数、extern “C“ 浅析相关推荐

  1. C++内联(inline)函数

    内联函数 内联函数是一种特殊类型的函数,内联函数在定义或声明时前面加上"inline"关键字.比如: inline int max(int a,int b) { return (a ...

  2. C++学习笔记之——引用 内联函数

     本文为原创作品,转载请注明出处 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和http://www.cnblogs.com/xujianqing/ 作者 ...

  3. C++ C++基础语法入门总结(二)引用-内联函数-C++11新特性

    C++基础语法入门总结 C++引用 再谈引用和指针 C++内联函数 附加C++11新特性 auto关键字 基于范围的for循环 指针空值nullptr C++引用 引用:就是某一变量(目标)的一个别名 ...

  4. C++入门之命名空间、缺省函数、重载函数及引用

    目录 一.命名空间 1.概念 (1)流插入运算符和流提取运算符 2.命名空间出现的意义 (1)c语言的命名缺陷 (2)如何解决命名冲突 3.命名空间的使用 (1)不展开使用 (2)完全展开使用 (3) ...

  5. matlab私有函数,MATLAB 嵌套函数,子函数,私有函数,重载函数

    MATLAB函数嵌套 MATLAB中M文件有两种类型,脚本M文件和函数M文件.脚本M文件是将可执行程序语句放入M文件中,就像在命令窗口那样,按其语句顺序及逻辑关系执行,可以理解为一般的顺序执行程序语句 ...

  6. C++ 函数匹配 重载函数的调用规则

    学习<C++ Primer>一书中,函数匹配这一节内容信息较多,现截取重点内容记录于此.便于你对本文内容更好的理解,你需对类型提升.算术类型转换以及顶层cosnt,底层const有一定的了 ...

  7. C# 虚函数和重载函数

    虚函数就是在这个函数声明前加上virtual  这样这个函数在它的派生类(子类)中可以被重写 而子类在重写父类的虚函数时,要显式的加上override 用处:就是可以在子类中被重写,当你继承一个类时, ...

  8. C++文件头,命名空间,new和delete,内联函数,引用,函数重载,构造函数和析构函数,深拷贝和浅拷贝,explict,this指针

     目 录 1      开始学习C++............................................................................... ...

  9. C++ 基础 : 函数重载、引用、内联函数、auto、范围for循环

    函数重载 引用 内联函数 auto 范围for循环 函数重载 C++中引入了一个新特性,函数重载. 在同一个作用域下,对于相同的函数名,函数的参数不同,不同类型的参数顺序不同,参数的个数不同,都可以形 ...

  10. c++之头文件基本输出,输入,名字空间,引用,内联函数,函数重载,缺省参数

    c++之头文件,基本输出,输入,名字空间,引用,内联函数,函数重载,缺省参数 文章目录 c++之头文件,基本输出,输入,名字空间,引用,内联函数,函数重载,缺省参数 前言 一.头文件,基本输出,输入 ...

最新文章

  1. 机器学习:信用风险评估评分卡建模方法及原理
  2. 正则表达式二 :贪婪与非贪婪
  3. JAVA_NIO ,走进JavaNIO的世界
  4. 2016计算机课程设计,2016年计算机组成原理课程设计-硬布线控制器的设计.doc
  5. 3-4 网络编程 练习题
  6. Python3 实现单例设计模式
  7. 手写table用ajax遍历,原生js把数据循遍历到前端table
  8. html5群组选择器,css选择器
  9. java 中的单引号报错_shell中的单引号,双引号,反引号
  10. linux协议栈网桥部分之cam表操作,Docker网络基础 - Linux网桥工作原理与实现
  11. IOS-播放器开发(1)-视频基本原理
  12. 【ADNI】数据预处理(2)获取 subject slices
  13. Lrc文件与音乐的同步显示
  14. JS内功修炼-基础篇
  15. 计算机二级word海报体,2016年计算机二级《MSOffice》全真模拟试题
  16. 高效人士的116个IT秘诀
  17. QT:模仿腾讯会议(低配版)
  18. IRQL深入解析(1)--IRQL级别
  19. 29_ElasticSearchIK中文分词器的安装和使用
  20. Android:实现安卓小程序-记事本(备忘录)的开发

热门文章

  1. asp.net mysql 查询_asp.net 多条件查询数据库
  2. android 人生日历,人生日历Android版 功能初体验
  3. 中国芯片人才大军在哪里?IEEE Fellow,投资人,创业者,工程师
  4. apk部分手机安装失败_安装apk解析包时出现错误怎么办?小编快速帮你解决
  5. E+H超声波物位计FMU42
  6. 保姆级人工智能学习成长路径
  7. 用ENSP华为模拟器做图书馆得网络配置和设计
  8. 一位资深程序员的亲身经历:跳槽国企要注意啥
  9. 计算机c盘加容量,两种方法,给电脑C盘增加10G的容量,电脑焕然一新
  10. 将系统必备组件打包进安装文件(以vs15打包.net formwork 4.5为例)有点鸡肋