C++:布尔类型bool,函数重载、参数缺省值、哑元参数、内联函数、引用
来源:互联网 发布:淘宝自创品牌 编辑:程序博客网 时间:2024/05/29 00:34
<tips>
"$: nautilus ." 打开文件夹
"$: nautilus jy/c++" 打开指定路径的文件夹
一、布尔类型 bool (C++98 新增的基础数据类型)
bool 类型的变量有两个可能的值:1 / 0
bool 类型的常量有两个可能的值:true / false
bool 类型的变量占用的字节数,因系统不同而不同,大多数系统为 1 字节。
1. bool 类型的赋值:
把非 0 值赋值给布尔类型变量时,此变量值为真值(true)
把 0 值赋值给布尔类型变量时,此变量的值为假值(false)
二、函数重载
1. 在C++中"函数可以同名",这种情况叫做 "函数重载"
2. 函数重载的定义:
在同一作用域内,相同的函数名,但参数个数或参数类型不同,构成重载。
foo();
foo(10);
foo(10);
foo(10L); //10L,10LL,10LLU(long, long long, unsigned long long)
foo(10.0);
return 0;
}
3. 函数重载的使用:
函数名 + 实参列表(来决定调用哪个函数)
4. 函数的返回值类型,不能区分函数是否重载
void foo(double d) {
cout << "foo(double)\n";
}
double foo(double d) { //不够成重载,编译出现起义,编译不过
cout << "foo(double)\n";
}
5. 重载的匹配规则
1)完全匹配 - 优先;
2)常量转换 - 次之;
3)升级转换 - 次之;//短字节到长字节
4)降级转换 - 次之;
5)省略号不定参转换;
6. 函数重载的原理
C++的函数的重载使用"函数的换名"来实现的。
可以用g++ -c编译出.o文件,nm filename.o 查看函数换名。
7. extern "C" 的作用:
告诉编译器由 extern "C"指定的函数,按照C语言的函数命名规则来调用编译(即不换名)。
用法有二:
1)加在函数名前;
extern "C" void foo() {...}
2)用 extern "C" { 多个函数声明 } 让多个函数都按着C语言的函数命名和调用规则来编译。"C/C++混合编程中使用"
三、函数参数的缺省值(默认值)
规则:
1)默认值必须为字面值常量,或无名对象;
2)默认值的出现必须自右至左依次有默认值;
void foo(int a, int b = 10); //合法
void foo(int a = 10, int b = 100); //合法
void foo(int a = 10, int b); //不合法
void foo(int a, int b = 0, int c, int d = 0); //不合法
注意事项:
1. 实现了重载的函数,容易出现调用冲突;
void foo(int a, int b);
void foo(int a, int b, int c = 10);
foo(1, 2); //调用冲突
2. 如果一个函数有声明和实现分开,则默认参数应当加在声明处;
void foo(int a, int b, int c = 100); //声明处
void foo(int a, int b, int c) {...} //实现处
四、C++函数的哑元参数
作用:
1)兼容已经写好的程序,增强兼容性;
func(100, 3.14); //已经写好的函数调用
2)C++的++/--运算符重载时,用来区分前置和后置;
++i/i++, --i/i-- (后面补充)
哑元说明:
1)哑元可以带缺省参数,作用也是为了兼容性:
void listen(int = 0) {...} //合法
listen(100); //100被忽略,编译能通过
listen(); //这么写也可以
1. 函数的调用过程
int getMax(int x, int y) {
return x > y ? x : y;
}
getMax(100, 200);
getMax函数的被调用过程示意如下:
1)向栈内压入一个空的返回值
| ret_value
2)把函数返回地址压入到栈内
| ret_value | ret_address
3)4)把 100,200 复制到栈顶
| ret_value | ret_address | 100 | 200
5)执行函数体内的代码
6)把返回值放到 ret_value
| 200 | ret_address | 100 | 200
7)弹出局部变量形参
8)将返回地址 ret_address --> PC
2. 内联函数的作用
告诉编译器如果在可能的情况下,把函数体的内部代码插入到调用的地方去编译,以去除函数压栈和弹栈的过程来提高程序的运行效率。
3. 内联的优缺点:
优点:减少了函数的传参和返回过程,提高了运行效率;
缺点:1)当一个比较大的函数被多次调用的时候,会造成调用函数的扩大
2)内联不能递归调用。
4. 内联说明:
应用:"多次被调用的小而简单"的函数,适合内联。
注意:内联函数不能取地址(没有函数地址)。
六、C++的引用 reference
1. C语言访问变量的方法:"变量名,地址(指针)"
int i = 10;
int *pi = &i; // *pi 用指针来访问
2. C++提供了第三种访问变量的方法:"引用"
对象类型 & 引用对象的别名 = 对象名;
3. 说明:
1)引用是对象的别名,通常不占用内存空间
2)引用"必须在定义的时候初始化"指向一个对象
指针可以有空指针,引用没有空引用。
int *p = NULL; //正确
int & p; 或 int & p = NULL; //都错误!!
3)引用在定义后,不能改变引用的对象,直至引用销毁,引用从一而终。
指针可以改变指向,引用不能改变指向。
int *p = &a; p = &b; //正确
int & p = a; p = b; //只是将b的值赋值给a,并没有改变p的指向
4)引用的类型必须和指向对象的类型一致。
int i = 100;
double & rd = i; //错误!!
5)具有非常属性的引用,不可以引用有常属性的对象;
int & rj = 200; //不合法
const double pi = 3.14; //定义
double & rpi = pi; //不合法,pi是有常属性的变量,只读变量
const double & crpi = pi; //合法
crpi = 7.8; //不合法
double & rd = i; //不合法
6)具有常属性的引用,可以引用非常属性的对象,也可以引用常属性的对象
int i = 100;
const int & cri = i;
i++; //合法
cout << cri << " " << i << endl; // 101 101
cri++; //不合法
4. 引用的实质:
引用的实质是'常量指针'。
int i = 100;
int * const pi = &i;
*pi //指针解引用运算符,或取值运算符
int & ri = i;
ri //C++的引用,相当于 int * const pi = &i; ri <==> *pi
1)有指针的引用,但没有引用的指针
int i = 100;
int *p = &i;
int * & rp = p; //指针的引用,合法。
cout << rp << endl; //0xbf985b84 地址
char c = 'a';
char & rc = c;
char & * prc = &rc; //不合法,没有引用的指针!!
2)有指针的指针,没有引用的引用
char c = 'a';
char *pc = &c;
char **p = &pc; //指针的指针,二级指针
char & rc = c;
char && rrc = rc; //没有引用的引用,错误!!!
&& 这在C++11 标准中叫右值引用。
5. 引用作为函数的参数:
引用可以作为函数的参数进行传递。"函数传参"
6. 引用作为函数的返回值:
1)不能返回局部对象的引用;(这点和指针类似)
2)多数传引用的目的是为了减少对象的复制次数,提高运行效率。
练习作业:使用引用参数完成两个字符串指针(const char *)的交换
七、操作符别名
{ <%
} %>
[ <:
] :>
# %:
! not
!= not_eq
& bitand
八、引用的扩展
1. 数组的引用
int arr[5] = {1, 2, 3, 4, 5};
int (& rarr)[5] = arr; //sizeof(rarr) = 20
2. 函数的引用
int mymax(int x, int y) {
return x > y ? x : y;
}
"$: nautilus ." 打开文件夹
"$: nautilus jy/c++" 打开指定路径的文件夹
一、布尔类型 bool (C++98 新增的基础数据类型)
bool 类型的变量有两个可能的值:1 / 0
bool 类型的常量有两个可能的值:true / false
bool 类型的变量占用的字节数,因系统不同而不同,大多数系统为 1 字节。
1. bool 类型的赋值:
把非 0 值赋值给布尔类型变量时,此变量值为真值(true)
把 0 值赋值给布尔类型变量时,此变量的值为假值(false)
bool b;int i = 100;b = i; // 1b = &i; // 1b = 'a'; // 1b = 3.14; // 1b = '\0'; // 0b = 0; // 0b = 0.0; // 0b = NULL; // 0注:long double(12 btyes / 16 byte)
二、函数重载
1. 在C++中"函数可以同名",这种情况叫做 "函数重载"
2. 函数重载的定义:
在同一作用域内,相同的函数名,但参数个数或参数类型不同,构成重载。
/** 代码演示如下 **/#include <iostream>using namespace std;void foo() { cout << "foo无参\n";}void foo(int i) { cout << "foo(int)\n";}void foo(long int l) { cout << "foo(long int)\n";}void foo(double d) { cout << "foo(double)\n";}int main() { //三个foo互为重载关系
foo();
foo(10);
foo(10);
foo(10L); //10L,10LL,10LLU(long, long long, unsigned long long)
foo(10.0);
return 0;
}
3. 函数重载的使用:
函数名 + 实参列表(来决定调用哪个函数)
4. 函数的返回值类型,不能区分函数是否重载
void foo(double d) {
cout << "foo(double)\n";
}
double foo(double d) { //不够成重载,编译出现起义,编译不过
cout << "foo(double)\n";
}
5. 重载的匹配规则
1)完全匹配 - 优先;
2)常量转换 - 次之;
3)升级转换 - 次之;//短字节到长字节
4)降级转换 - 次之;
5)省略号不定参转换;
/** 代码演示 **/#include <iostream>using namespace std;//以下两个函数示意升级转换 > 降级转换void foo(char c) { cout << "foo(char)\n";}void foo(int i) { cout << "foo(int)\n";}void foo(long int l) { cout << "foo(long int)\n";}void foo(double d) { cout << "foo(double)\n";}void bar(const char *p, char i) { cout << "bar(const char *, char)\n";}void bar(char *p, double d) { cout << "bar(char *, double)\n";}//以下两个函数示意降级转换 > 不定参转换void hum(char c, short s) { cout << "hum(char, short)\n";}void hum(char c, ...) { cout << "hum(char, ...)";}int main() { hum('a', 1000000); //hum(char, short) foo('a'); //foo(int) char a[] = "hello"; bar(a, 'A'); //bar(const char *, char) short s = 300; foo(s);//foo(int) return 0;}
6. 函数重载的原理
C++的函数的重载使用"函数的换名"来实现的。
可以用g++ -c编译出.o文件,nm filename.o 查看函数换名。
7. extern "C" 的作用:
告诉编译器由 extern "C"指定的函数,按照C语言的函数命名规则来调用编译(即不换名)。
用法有二:
1)加在函数名前;
extern "C" void foo() {...}
2)用 extern "C" { 多个函数声明 } 让多个函数都按着C语言的函数命名和调用规则来编译。"C/C++混合编程中使用"
#ifdef __cplusplus //与此预处理宏配合使用,C/C++可通用编译不出错extern "C" { //gcc 和 g++均兼容,C中编译会去掉,C++编译会加上#endifvoid foo();void bar();int hum(int i, double d);...#ifdef __cplusplus}#endif注:extern "C" 通常可预处理指令#ifdef __cplusplus 配合使用。
三、函数参数的缺省值(默认值)
规则:
1)默认值必须为字面值常量,或无名对象;
2)默认值的出现必须自右至左依次有默认值;
void foo(int a, int b = 10); //合法
void foo(int a = 10, int b = 100); //合法
void foo(int a = 10, int b); //不合法
void foo(int a, int b = 0, int c, int d = 0); //不合法
注意事项:
1. 实现了重载的函数,容易出现调用冲突;
void foo(int a, int b);
void foo(int a, int b, int c = 10);
foo(1, 2); //调用冲突
2. 如果一个函数有声明和实现分开,则默认参数应当加在声明处;
void foo(int a, int b, int c = 100); //声明处
void foo(int a, int b, int c) {...} //实现处
/** 代码演示如下 **/#include <iostream>using namespace std;double myadd(int a, double b, short c = 0, char d = '\0') { return a+b+c+d;}int main() { myadd(10, 3.14); //(10, 3.14, 0, '\0') myadd(10, 3.14, 100); //(10, 3.14, 100, '\0') cout << myadd(10, 20.0, 30, ' ') << endl; //(10, 20.0, 30, 32) return 0;}
四、C++函数的哑元参数
/** 代码演示 **/#include <iostream>using namespace std;void func(int i, double) { // double处为哑元参数,C的无名形参 cout << "i=" << i << endl; // i=100}int main() { func(100, 200); return 0;}
作用:
1)兼容已经写好的程序,增强兼容性;
func(100, 3.14); //已经写好的函数调用
2)C++的++/--运算符重载时,用来区分前置和后置;
++i/i++, --i/i-- (后面补充)
哑元说明:
1)哑元可以带缺省参数,作用也是为了兼容性:
void listen(int = 0) {...} //合法
listen(100); //100被忽略,编译能通过
listen(); //这么写也可以
1. 函数的调用过程
int getMax(int x, int y) {
return x > y ? x : y;
}
getMax(100, 200);
getMax函数的被调用过程示意如下:
1)向栈内压入一个空的返回值
| ret_value
2)把函数返回地址压入到栈内
| ret_value | ret_address
3)4)把 100,200 复制到栈顶
| ret_value | ret_address | 100 | 200
5)执行函数体内的代码
6)把返回值放到 ret_value
| 200 | ret_address | 100 | 200
7)弹出局部变量形参
8)将返回地址 ret_address --> PC
2. 内联函数的作用
告诉编译器如果在可能的情况下,把函数体的内部代码插入到调用的地方去编译,以去除函数压栈和弹栈的过程来提高程序的运行效率。
/** 代码演示 **/#include <iostream>using namespace std;inline int getMax(int x, int y) { return x > y ? x : y;}int main() { cout << (100 > 200 ? 100 : 200) << endl; cout << getMax(100, 200) << endl;//inline的作用和上1行一样高效率 return 0;}
3. 内联的优缺点:
优点:减少了函数的传参和返回过程,提高了运行效率;
缺点:1)当一个比较大的函数被多次调用的时候,会造成调用函数的扩大
2)内联不能递归调用。
4. 内联说明:
应用:"多次被调用的小而简单"的函数,适合内联。
注意:内联函数不能取地址(没有函数地址)。
六、C++的引用 reference
1. C语言访问变量的方法:"变量名,地址(指针)"
int i = 10;
int *pi = &i; // *pi 用指针来访问
2. C++提供了第三种访问变量的方法:"引用"
对象类型 & 引用对象的别名 = 对象名;
/** 代码演示 **/#include <iostream>using namespace std;int main() { int i = 100; int & ri = i; //ri为i的别名(引用) cout << ri << " " << i << endl; //100 100 i++; cout << ri << " " << i << endl; //101 101 ri++; //也是对变量i的操作 cout << ri << " " << i << endl; //102 102 return 0;}
3. 说明:
1)引用是对象的别名,通常不占用内存空间
2)引用"必须在定义的时候初始化"指向一个对象
指针可以有空指针,引用没有空引用。
int *p = NULL; //正确
int & p; 或 int & p = NULL; //都错误!!
3)引用在定义后,不能改变引用的对象,直至引用销毁,引用从一而终。
指针可以改变指向,引用不能改变指向。
int *p = &a; p = &b; //正确
int & p = a; p = b; //只是将b的值赋值给a,并没有改变p的指向
4)引用的类型必须和指向对象的类型一致。
int i = 100;
double & rd = i; //错误!!
5)具有非常属性的引用,不可以引用有常属性的对象;
int & rj = 200; //不合法
const double pi = 3.14; //定义
double & rpi = pi; //不合法,pi是有常属性的变量,只读变量
const double & crpi = pi; //合法
crpi = 7.8; //不合法
double & rd = i; //不合法
6)具有常属性的引用,可以引用非常属性的对象,也可以引用常属性的对象
int i = 100;
const int & cri = i;
i++; //合法
cout << cri << " " << i << endl; // 101 101
cri++; //不合法
4. 引用的实质:
引用的实质是'常量指针'。
int i = 100;
int * const pi = &i;
*pi //指针解引用运算符,或取值运算符
int & ri = i;
ri //C++的引用,相当于 int * const pi = &i; ri <==> *pi
1)有指针的引用,但没有引用的指针
int i = 100;
int *p = &i;
int * & rp = p; //指针的引用,合法。
cout << rp << endl; //0xbf985b84 地址
char c = 'a';
char & rc = c;
char & * prc = &rc; //不合法,没有引用的指针!!
2)有指针的指针,没有引用的引用
char c = 'a';
char *pc = &c;
char **p = &pc; //指针的指针,二级指针
char & rc = c;
char && rrc = rc; //没有引用的引用,错误!!!
&& 这在C++11 标准中叫右值引用。
5. 引用作为函数的参数:
引用可以作为函数的参数进行传递。"函数传参"
/** 代码演示:交换两个值 **/#include <iostream>using namespace std;//传值void myswap1(int a, int b) { int tmp = a; a = b; b = tmp;}void myswap2(int *pa, int *pb) { int tmp = *pa; *pa = *pb; *pb = tmp;}void myswap3(int & ra, int & rb) { //类型必须相同 int tmp = ra; ra = rb; rb = tmp;}int main(void) { int x = 100; int y = 200; myswap1(x, y); cout << "x=" << x << " " << "y=" << y << endl;//100 200 myswap2(&x, &y); //第一次交换成功 cout << "x=" << x << " " << "y=" << y << endl;//200 100 myswap3(x, y); //第二次交换成功,直接变量做实参 cout << "x=" << x << " " << "y=" << y << endl;//100 200 return 0;}
6. 引用作为函数的返回值:
1)不能返回局部对象的引用;(这点和指针类似)
2)多数传引用的目的是为了减少对象的复制次数,提高运行效率。
/** 代码演示 **/#include <iostream>using namespace std;int getmax1(int a, int b) { return a > b ? a : b;}static int s_max = 0;int & getmax2(int a, int b) { //会少一次返回值这个值的复制 s_max = a > b ? a : b; return s_max;// return a > b ? a : b; //返回局部对象的引用,野引用,不能出现!!}int & getmax3(int & a, int & b) { //没有任何一个参数的复制,仅需传值 return a > b ? a : b;}int main(void) { int x = 100; int y = 200; cout << getmax1(x, y) << endl; //200 cout << getmax2(x, y) << endl; //200 cout << s_max << endl; //200 int & rmax = getmax2(x, y); cout << rmax << endl; //200 s_max++; //验证rmax是s_max的引用 cout << rmax << endl; //201 rmax = 500; cout << s_max << endl; int m = getmax2(x, y); //会多一次复制,复制1份返回值赋值给m int & rm = m; cout << rm << endl; cout << "getmax3= " << getmax3(x, y) << endl; return 0;}
练习作业:使用引用参数完成两个字符串指针(const char *)的交换
#include <iostream>using namespace std;void myswap(const char *& str1, const char *& str2) { const char *tmp = str1; str1 = str2; str2 = tmp;}int main() { const char * s1 = "hello"; const char * s2 = "world"; cout << "s1 = " << s1 << endl; //hello cout << "s2 = " << s2 << endl; //world myswap(s1, s2); cout << "交换后:" << endl; cout << "s1 = " << s1 << endl; //world cout << "s2 = " << s2 << endl; //hello return 0;}
七、操作符别名
{ <%
} %>
[ <:
] :>
# %:
! not
!= not_eq
& bitand
八、引用的扩展
1. 数组的引用
int arr[5] = {1, 2, 3, 4, 5};
int (& rarr)[5] = arr; //sizeof(rarr) = 20
2. 函数的引用
int mymax(int x, int y) {
return x > y ? x : y;
}
int (& rmax)(int, int) = mymax;
0 0
- C++:布尔类型bool,函数重载、参数缺省值、哑元参数、内联函数、引用
- C++【函数(重载/缺省参数/哑元/内联)】
- Day37、函数重载、缺省参数、哑元参数、内联函数inline、内存分配、引用
- day02 C++的函数重载、内联函数 、哑元参数、动态内存分配 、引用
- [c/c++]函数参数缺省值
- [c/c++]函数参数缺省值
- 037day(动态内存分配和内联函数,重载函数,函数参数缺省值的学习)
- 函数重载,覆盖,参数缺省值,不能被重载的运算符,元芳,你怎么看?
- 内联函数&&函数重载&&函数缺省值
- C/C++的区别(默认值、内联函数、函数重载、const、引用、参数、返回值)
- 函数重载,覆盖与隐藏;参数缺省值;运算符重载
- 第八章 C++函数的高级特性(8.3 参数的缺省值 8.4 运算符重载 8.5 函数内联)
- c++函数功能 引用 & 重载 & 默认参数 & 内联
- C++学习笔记(四)--内联函数,引用参数,默认参数,函数重载,函数模板
- 在函数重载和设定参数缺省值间慎重选择
- 函数重载与参数缺省值共用可能引起两意性
- 内联函数,重载函数,默认参数
- 内联函数,引用变量,按引用传递参数,默认参数,函数重载,函数模板,函数模板具体化,decltype
- HDU2005 第几天?
- 请问企业要开发官网,能要源代码吗?
- 关于Tarjan(3)——离线LCA
- HDU2006 求奇数的乘积
- 输入一个字符串,计算字符串中子串出现的次数
- C++:布尔类型bool,函数重载、参数缺省值、哑元参数、内联函数、引用
- Problem C. Jane's Flower Shop Google APAC 2017 University Test Round A
- 12.2.2
- javascript展开与收起效果
- 小白自总结【pLSA】实验详细记录
- tween.js详解
- 贪心,二分,半平面交(丛林警戒队,LA 4992)
- Jackson操作方法
- 比特币『私钥』『公钥』『钱包地址』间的关系