六、C++的布尔类型(bool)

1.bool类名是C++中的基本数据类型,专门负责表示逻辑值:真/假

注:C语言的C99标准里加入了布尔类型

2.bool类型内存占一个字节,1表示true,0表示false

3.bool类型的变量可以接收任意类型表达式的结果,其值非0则为true,0则为false

bool func()
{return true/false;
}

4.插入流控制符`boolalpha`:以字符串的形式打印bool值(就是打印true/false不打印数字)

cout << "b=" << boolalpha << b << endl; 

参考代码:

#include <iostream>
using namespace std;
int main(void)
{bool b = false;cout << "size=" << sizeof(b) << endl;//1cout << "b=" << b << endl;//0b = 3+5;cout << "b=" << b << endl;//1b = 1.2 * 3.4;cout << "b=" << b << endl;//1char* p = NULL;//NULL-->(void*)0b = p;cout << "b=" << b << endl;//0return 0;
}

七、操作符别名

&& <==> and
|| <==> or
!  <==> not
{  <==> <%
}  <==> %>
......

参考代码:

#include <iostream>
using namespace std;
int main(void)
<%int a=3;int b=0;if(a or b)<%cout << "true" << endl;%>else<%cout << "false" << endl;%>return 0;
%>

★八、C++函数

1.函数重载

1)定义:在相同作用域下,定义同名的函数,但是他们的参数必须有所区分,这样的多个函数构成重载关系

//C语言方式实现
void drawRect(int x,int y,int w,int h){}
void drawCircle(int x,int y,int r){}
......
//C++方式实现
void draw(int x,int y,int w,int h){}
void draw(int x,int y,int r){}
......

函数重载特征:

①相同的作用域(在同一个类中)

②函数名相同

③参数不同(与返回值类型,参数常属性,volatile和默认参数无关),或者其常函数:当编译器决定哪个函数被声明,定义或调用时,每个参数的const和volatile类型和修饰和默认参数会被忽略掉。

特例:

void f(int * x)
void f(const int *x)或void f(int const *x)   // 编译正常
//但是,第二个不能为void f(int * const x)void f(int * x)
void f(volatile int *x)或void f(int volatile *x)   // 编译正常
//但是,第二个不能为void f(int * volatile x)

④virtual关键字可有可无没有影响

参考代码:

#include <iostream>
using namespace std;
int func(int i){cout << "func(int)" << endl;
}
void func(int i,int j){cout << "func(int,int)" << endl;
}
void func(int a,float b){cout << "func(int,float)" << endl;
}
int main(void)
{func(100);func(100,200);func(100,1.23f);//通过函数指针调用重载关系的函数时,由//函数指针的类型决定其匹配的重载版本void (*pf)(int,float) = func;pf(100,200);return 0;
}

2)函数重载匹配

调用重载关系函数时,编译器将根据实参和形参的匹配程度,自动选择最优的版本

当前g++编译器的匹配规则:

完全匹配 >= 常量转换 > 升级转换 > 降级转换 > 可变参数(...)

参考代码:

#include <iostream>
using namespace std;
//char->int:升级转换
void foo(int i){cout << "foo(1)" << endl;
}
//char->const char:常量转换
void foo(const char c){cout << "foo(2)" << endl;
}
//short->char:降级转换
void fun(char c){cout << "fun(1)" << endl;
}
//short->int:升级转换
void fun(int i){cout << "fun(2)" << endl;
}
//省略号匹配(最差)
void bar(int i,...){cout << "bar(1)" << endl;
}
//double->int:降级转换
void bar(int i,int j){cout << "bar(2)" << endl;
}
int main(void)
{char c = 'A';foo(c);short s = 10;fun(s);bar(10,1.23);
}

3)函数重载的原理:
C++编译器通过对函数进行换名,将参数表的类型信息整合到新的名字中,解决函数重载和名字冲突的矛盾

问:extern "C"的作用?

答:在C++函数声明时加入extern "C",可以强制要求C++编译器不对该函数进行换名,方便C程序调用该函数

注:extern "C"声明的函数不能重载

extern "C" void func(void)
{......;
}

2.哑元参数

1)定义:定义函数时,只有类型而没有变量名的形参称为哑元

void func(int)//哑元参数
{......;
}

2)应用场景:
①操作符重载时区分前后++/--

②兼容旧代码

//算法库
void video_math(int a,int b){...;}
//使用者
int main()
{video_math(10,20);......;video_math(30,40);......;
}
_____________________________________
//算法库省级
void video_math(int a,int)//第二个参数为哑元参数
{video_math(10,20); //不影响旧代码的函数调用......;video_math(30,40);......;
}

3.函数缺省参数(默认参数)

1)可以为函数的部分参数或全部参数指定缺省值,调用该函数时,如果不给实参,就取缺省值作为相应的值

2)靠右原则,如果一个参数有缺省值,那么该参数右侧的所有形参都必须带有缺省值

3)如果函数的定义和声明分开,缺省参数应该写在函数的声明部分,而定义部分不写

#include <iostream>
using namespace std;void func(int a,int b=200,int c=300); //函数的声明int main()
{func(111);//111,200,300func(111,222); //111,222,300func(111,222,333); //111,222,333
}void func(int a,int b/*=200*/,int c/*=300*/) //函数的定义
{cout << "a=" << a << ",b=" << b << ",c=" << c << endl;
}

4.内联函数(inline)

1)定义:使用inline关键字修饰函数即为内联函数,编译器会尝试对内联进行优化,避免函数的调用开销,提高程序的执行效率

2)使用说明:

①多次调用小而简单的函数适合内联

②调用次数极少或者大而复杂的函数不适合内联

③递归函数不能内联

④虚函数不能内联

注:内联函数只是一种建议而不是强制要求,一个函数能否内联优化取决于编译器,有些函数不加inline关键字也会默认处理为内联优化,有些函数即便加了inline修饰也会被编译忽略

九、动态内存分配

1.C++使用操作符实现动态内存的分配

分配:new/new[]

释放:delete/delete[]

错误处理:异常机制

#include <iostream>
using namespace std;int main(void)
{//int* pi = new int;//*pi = 100;//分配内存同时初始化int* pi = new int(100);cout << *pi << endl;delete pi;//防止内存泄露pi = NULL;//放置野指针int* pi2 = new int(100);(*pi2)++;cout << *pi2 << endl;//101delete pi2;pi2=NULL;/*int* parr = new int[10];for(int i=0;i<10;i++){parr[i] = i;cout << parr[i] << ' ';}*///new数组同时初始化,C++11int* parr = new int[10]{1,2,3,4,5,6,7,8,9,10};for(int i=0;i<10;i++){cout << parr[i] << ' ';}cout << endl;delete[] parr;parr=NULL;return 0;
}

2.C++中的new/delete和C中malloc/free的区别和联系

1)两者都是在堆上进行的内存操作

2)new与delete只能在C++中使用,但malloc和free可以在C++和C中使用,new与delete是操作符,可以重载,malloc和free是库函数

3)使用new分配内存的时候,会自动相应类的构造函数进行初始化,而malloc只是单纯的分配内存,不进行初始化,delete释放内存时会调用相应类的析构函数,free单纯的释放内存

4)Malloc函数的返回值是void*类型的,new的返回值某种类型指针,无需再进行类型转换

5)Malloc分配内存时,分配内存的大小需要自己计算,但new是自动计算的

3.delete和delete[ ]的区别

1)当new[]中的数组元素是基本类型时,通过delete和delete[]都可以释放数组空间;

2)当new[]中的数组元素是自定义类型时,只能通过delete[]释放数组空间。当数组中的元素是自定义类型时,delete在释放空间时只会调用数组中首个元素的析构函数,而delete[]在释放空间时会调用数组中所有元素的析构函数

★十、C++的引用

1.定义:

1)引用即别名,引用就是某个变量的别名,对引用的操作与对该变量本身操作完全相同

2)语法:

类型 & 引用名 = 变量名;

注:引用在定义时必须初始化,初始化以后就不能修改目标
注:引用的类型与绑定的目标变量类型一致

参考代码:

int a = 10;
int& b = a;
b++;
cout << a << endl;//11
int c = 20;
b = c; //不是让b引用c,而是将c赋值给b
cout << a << endl; //20

2.常引用

1)定义引用时加const修饰,即为常引用,不能通过常引用修改引用的目标的值

const 类型 & 引用名 = 变量;
类型 const & 引用名 = 变量;
//两种效果一样
int a = 10;
const int& b = a;//b是a的常引用
b++;//error
a++;//ok
cout << b << endl;

2)普通的引用也可以叫做左值引用,只能引用左值,而常引用也叫万能引用,既可以引用左值,也可以引用右值

3)关于左值和右值

左值(lvalue):可以放在赋值操作符左边,可以被修改

常见左值情况:

①普通变量

②前++/-- ——表达式结果是左值(++a)

③赋值表达式结果是左值(=/+=/-=......)

右值(rvalue):智能放在赋值操作符右边,不能被修改

常见右值情况:

①常量,字面值常量

②多数算数表达式结果都是右值(+/-/*/......)

③后++/-- ——表达式结果是右值(a++)

临时变量都是右值(隐式转换)

⑤一般函数返回的临时变量也是右值(引用型返回值是个左值)

#include <iostream>
using namespace std;
int func(void){int num = 10;cout << "&num:" << &num << endl;return num;//int tmp = num;
}
int main(void)
{//int r = tmp//r实际引用的函数返回的临时变量(tmp)const int& r = func();cout << r << endl;//10cout << "&r=" << &r << endl;int a = 10;//将a隐式转换为char类型,结果保存临时变量//rc实际要引用的是临时变量//char& rc = a;//errorconst char& rc = a;//okcout << "&a=" << (void*)&a << endl;cout << "&rc=" << (void*)&rc << endl;return 0;
}

3.引用型函数参数

1)将引用用于函数的参数,这时形参就是实参的别名,可以通过形参直接修改实参,同时可以避免参数传递的过程,减小函数的调用开销,提高代码的执行效率

2)引用型参数有可能意外修改实参的值,如果不希望修改实参本身,可以将形参声明为常引用,可提高传参效率的同时还可以接收常量型的实参

参考代码:

#include <iostream>
using namespace std;
void swap1(int* x,int* y){*x = *x ^ *y;*y = *x ^ *y;*x = *x ^ *y;
}
void swap2(int& x,int& y ){x = x ^ y;y = x ^ y;x = x ^ y;
}
int main(void)
{int a=3,b=5;//swap1(&a,&b);swap2(a,b);cout << "a=" << a << ",b=" << b << endl;
}

4.引用型函数返回值

1)可以将函数的返回类型声明为引用,避免函数返回值带来的内存开销,提高代码执行效率

2)如果函数返回左值引用,那么该函数调用结果就也是一个左值

注:不要从函数中返回局部变量的引用,因为所引用的内存在函数返回以后将被释放,使用非常危险,但是可以从函数中返回成员变量、静态变量、全局变量引用

参考代码:

#include <iostream>
using namespace std;
struct A{int data;int& func(void){return data;}int& func2(void){int i=100;//返回局部变量引用,危险!return i;}
};
int main(void)
{A a = {0};//data = 123;a.func() = 123;cout << a.data << endl;//123return 0;
}

5.引用和指针

1)从C语言的角度看待引用,引用本质就是指针,但是在C++中推荐使用引用而不是指针

int i = 100;
int& ri = i;
int* const pi = &i;
ri <=等价=> pi

2)指针定义时可以不做初始化,其指向目标可以初始化后再修改(指针常量除外),而引用定义时必须初始化,且一旦初始化后,其引用目标不能在改变

int a,b;
int* p;//ok
p = &a;//p指向a
p = &b;//p指向b
------------------
int& r;//error
int& r = a;//r引用a,r只能是a的别名
r = b;//ok,但不是修改引用目标,仅是赋值操作

了解:

3)可以定义指针的指针(二级指针),但是不能定义引用的指针(指向引用的指针)

        int a;int* p = &a;int** pp  = &p;//ok,pp称为二级指针------------------------------int& r = a;int&* pr = &r;//errorint* pr = &r;//ok,但是就是一个普通指针

4)可以定义指针的引用(指针变量的别名),但是不能定义引用的引用

 int a;int* p = &a;int*& rp = p;//ok,指针的引用----------------------------int& r = a;int&& rr = r;//error,C++中叫右值引用int& rr = r;//ok,但是就是一个普通的引用

5)可以定义指针数组,但是不能定义引用数组

 int a,b,c;int* parr[3] = {&a,&b,&c};//okint& rarr[3] = {a,b,c};//error 

6)可以数组引用(数组的别名)

 int arr[3] = {1,2,3};int (&rarr)[3] = arr;//ok

7)和函数指针类似,也可以定义函数的引用(函数的别名),其语法特性和函数指针一样

 void func(int a,int b){...}int main(void){void (*pf)(int,int) = func;pf(100,200);//ok---------------------void (&rf)(int,int) = func;rf(100,200);//ok}

7.C++的引用和 C 语言的指针有什么区别

①值:指针指向一块内存,它的内容是指向内存的地址;引用是某变量的别名

②初始化:引用在定义的时候必须初始化,且不能为空,指针定义时可以为空

③改变:引用在定义是被初始化一次,之后不可变;指针可变

④存储:程序为指针变量分配内存区域,而引用不需要分配内存区域

⑤使用:引用使用是无需解引用,指针需解引用

C++学习——布尔型,操作符别名,函数和引用相关推荐

  1. Go 学习笔记(4)— Go 标识符、数据类型之间转换、布尔型、整型、浮点型、interface 类型

    1. 标识符整体分类 Go 标识符整体分类如下图所示: 2. 数据类型分类 Go 语言按类别有以下几种数据类型: 类型 描述 布尔型 布尔型的值只可以是常量 true 或者 false 数字类型 整型 ...

  2. R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:基于条件判断创建布尔型指示变量、将异常离散编码转化为NA值

    R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:基于条件判断创建布尔型指示变量.将异常离散编码转化为NA值 目录

  3. 前端:JS/17/前篇总结(JS程序的基本语法,变量),数据类型-变量的类型(数值型,字符型,布尔型,未定义型,空型),数据类型转换,typeof()判断数据类型,从字符串提取整数或浮点数的函数

    JS程序的基本语法 1,JS是区分大小写的,如:Name和name是不同的: 2,JS中每一条语句,一般以英文的分号(;)结束,在Java中是严格地一定要加上分号,不然会报错:但在JavaScript ...

  4. C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象

    重载操作符与转换 --调用操作符和函数对象 引言: 能够为类类型的对象重载函数调用操作符:一般为表示操作的类重载调用操作符! struct absInt {int operator() (int va ...

  5. (四)Flutter 学习之 Dart 操作符、控制流和异常处理

    Flutter系列文章目录导读: (一)Flutter学习之Dart变量和类型系统 (二)Flutter学习之Dart展开操作符 和 Control Flow Collections (三)Flutt ...

  6. 《Go语言圣经》学习笔记 第五章函数

    <Go语言圣经>学习笔记 第五章 函数 目录 函数声明 递归 多返回值 匿名函数 可变参数 Deferred函数 Panic异常 Recover捕获异常 注:学习<Go语言圣经> ...

  7. Phoenix的数据类型和操作符、函数

    Phoenix的数据类型和操作符.函数 官方文档 http://phoenix.apache.org/language/functions.html http://phoenix.apache.org ...

  8. python中复数的实部和虚部都是浮点数_Python基础:数值(布尔型、整型、长整型、浮点型、复数)...

    一.概述 Python中的 数值类型(Numeric Types)共有5种:布尔型(bool).整型(int).长整型(long).浮点型(float)和复数(complex). 数值类型支持的主要操 ...

  9. Kotlin学习(七):函数

    Kotlin学习(七):函数 函数基本用法 Kotlin 函数必须用 fun 关键字开头,后面紧跟着函数名,以及一对小括号,小括号中是函数参数列表,如果函数有返回值,在小括号后面加冒号 (:),冒号后 ...

最新文章

  1. 36 张图详解 ARP :网络世界没有我,你哪也别想去
  2. 随机分配效果在task中的应用,公司内部代码片
  3. ICPC2008哈尔滨-E-Gauss Elimination
  4. 【计网】计算机网络期末总复习-谢希仁(个人总结)理论概念
  5. Python——文本进度条
  6. Redis之Hash数据结构
  7. 我两个月来对Quarkus的了解
  8. Leetcode--80. 删除排序数组中的重复项Ⅱ
  9. Linux学习总结(18)——Linux使用init命令关机、重启、切换模式
  10. python中join和split使用
  11. React从0到1--JSX样式
  12. CSDN如何获取积分
  13. arcgis分析道路节点中心性degree,closeness,betweenness
  14. 为什么计算机使用二进制,你知道吗?
  15. 工赋开发者社区 | 抛弃 Google,Debian 改将 DuckDuckGo 作为默认搜索引擎
  16. 证:单层感知机不能表示异或逻辑
  17. flex+java项目创建_创建Flex 4和Java Web应用程序
  18. windows10无法连接远程桌面的问题的解决方法
  19. 机器人中的 jog 是什么意思?
  20. 评分卡模型案例(一)| 基础知识

热门文章

  1. 如何破解excel打开密码
  2. NPDP知识推送-第七章产品生周期管理(2)
  3. 【Python】胡渊鸣的99行代码——冰雪奇缘
  4. 微信小程序-仿朋友圈点赞评论操作面板
  5. 2021年危险化学品经营单位安全管理人员考试试卷及危险化学品经营单位安全管理人员实操考试视频
  6. oracle创建存储过程,hibernate调用
  7. 图片太大怎么办?压缩图帮你几秒搞定在线图片压缩
  8. Android布局原理与优化
  9. Word文档转PDF
  10. R语言空间面板数据统计分析