内容:
(1)C++中的函数
(2)动态内存
(3)引用
(4)类型转换
(5)C++社区对C程序员的建议
1.C++中的函数
1.1 函数的重载
(1)重载的概念
在同一个作用域中,函数名相同,函数的参数列表不同构成重载关系,在不同的作用域中遵循标示符隐藏原则
(2)函数重载的方式
a.函数名相同,参数类型不同
b.函数名相同,参数个数不同
c.函数名相同,参数顺序不同
d.函数名相同,const修饰的常函数和普通成员函数构成重载(以后讲到)
(3)比较特殊的重载方式
(4)重载匹配的原则
完全匹配 > 常量转换 > 升级转换
> 标准转换 > 自定义类型转换(以后讲到) > 省略匹配
1.2 函数重载的原理
(1)C++编译器通过对函数进行换名,将参数表信息体现在新的函数名中,从而实现重载
如:
void show(int i,int j){}
=> _Z4showii; 换名之后的新名字
void show(int j,int i)
=> _Z4showii;
(2)C程序也可以通过C++编译器换名后的新函数名调用C++模块中的函数
(3)通过extern "C" 关键字可以明确要求C++编译器不要对函数进行换名的操作,以满足C程序可以直接调用C++模块中的函数
1.3 缺省参数
函数的参数有缺省值,也就是默认值
如:
void foo(int i,char c = 'A',char* p = NULL) {...}
foo(66,'B',"hello");
foo(66,'B'); // p = NULL;
foo(66); // c = 'A',p = NULL
注意:
(1)缺省参数必须靠右。如果某一个参数带有缺省值,那么该参数右边的所有参数都必须有缺省值
如:
void foo(int i,char c = 'A',char* p){} // error
foo(66,"hello");
(2)如果函数的声明和定义分开,那么缺省参数的值只能写在函数的声明部分
如:
void foo(int i,char c = 'A',char* p = NULL);
void foo(int i,char c,char* p){}
(3)注意防止由于缺省参数而引发的重载冲突问题
扩展:
(1)void fn(){}; 在C语言中表示可以接受任意多个任意类型的实参;在C++中表示不接受任何实参
(2)在C语言中可以不对函数进行声明,会自动做隐式声明;在C++中调用函数之前必须对所调用的函数进行声明,或者将被调用函数的定义放在调用函数之前
1.4 哑元
只有数据类型没有名称的参数叫哑元
如:
void fn(int){}
fn(); //error
fn(66); // ok
用途:
(1)为了兼容以前的代码
(2)用于运算符重载,主要用于区分前后缀自增减运算符(以后讲到)
1.5 内联
使用inline关键字修饰的函数叫做内联函数
类似于C语言中的宏函数,可以进行指令的替换,相对于宏函数有一定的优势,可以检查数据类型,可以计算表达式的值等等
注意:
inline关键字修饰函数,仅仅表示这是一种建议而不是要求,所有使用inline关键字修饰的函数不一定会做内联的处理;反之,没有使用inline关键字修饰的函数也可能根据编译器的优化策略进行内联处理
练习:
自定义一个计算int类型参数平方的函数,并且通过返回值返回计算的结果,分别使用inline修饰和不修饰去观察是否内联
扩展:
(1)多次调用的小而简单的函数适合内联
(2)调用次数极少并且大而复杂的函数不适合内联
(3)递归函数无法内联
2.动态内存
C语言中: malloc/calloc/realloc/free 函数
C++中:
除了提供对C的兼容之外,还提供了 new/delete运算符来管理动态内存
2.1 申请指定数据类型变量大小的内存
int* pi = new int;
delete pi; pi = NULL;
int* pi = new int(66);
delete pi; pi = NULL;
2.2 申请指定的数组大小的内存
int* pi = new int[10];
delete[] pi; pi = NULL;
//C++11/C++0x标准支持
int* pi = new int[10]{...};
delete[] pi; pi = NULL;
提问:
int* pi = new int; //ok
int* pi = new int[5]; //ok
int* pi = new int[3][4];//error
int** pi = new int[3][4]; error
2.3 使用new操作符分配N维数组时,返回N-1维的数组指针
如:
int (*pi)[4] = new int[3][4];
delete[] pi; pi = NULL;
int (*pi)[3][4]
= new int[2][3][4];
delete[] pi; pi = NULL;
在[]后面使用{}进行初始化,需要C++11/C++0x标准的支持
2.4 定位分配
new(指针) 数据类型(初始值);
|
这里的指针表示分配内存的起 始位置
功能:
主要用于在一个已经分配好的内存空间再次分配内存
3.引用
3.1 概念
引用并不是一种独立的数据类型,类似于C中的指针,其实是变量的别名
如:
int a = 10;
int& b = a;
=> 给a起了个别名叫b,b = 10;
int& c = b;
=> int& c = a; c = 10;
3.2 引用和指针的区别
(1)引用必须初始化,指针可以不初始化
int& a; // error
int* pa; // 野指针
(2)引用不可以为空,指针可以为空
int& a = NULL; //error
const int& a = NULL; //常引用
const int& a = 11; // ok
int* pi = NULL; //空指针
(3)引用不可以更换目标,指针可以
int a = 10;
int& b = a;
int m = 20;
b = m; => a = m; 赋值
int* pi = &a;
pi = &b;
(4)不能声明引用型数组,可以声明指针型数组
int& arr[10]; //error
int* arr[10]; //ok
int arr[10]; //ok
int (*arr)[10]; //ok
建议:
在C++程序尽量去使用引用,而少使用指针,因为指针容易出现野指针,容易出现段错误
作业:
查询signal函数,并且将signal函数的原型组合出来
明日预报:
(1)引用
(2)类型转换
(3)C++社区给C程序员的建议
(4)面向对象编程的概念
(5)类和对象
(6)构造函数
(7)初始化列表及其必要性
复习:
1.C++的简介和编程变化
1.1 C语言的简介
贝尔实验室 汤普逊 B语言,在B语言的基础上修改和扩展,New B语言,后来改名为 C语言,出生于1972年
1.2 C++简介
在C语言的基础上,BS扩展C语言,New C语言,改名为 C With Classes(带类的C),++运算符,C++
1.3 历史事件
1998年 出现C++的标准 C++98
2003年 C++98修订 C++03
2011年 C++11标准(C++0x)
1.4 C++和C语言的比较
(1)都是编译型语言
(2)属于强类型语言
(3)C++兼容C,提供了更多的特性
a.语言风格更加简洁
b.类型检查更加严格(void* int*)
c.支持面向对象编程
d.支持异常处理
e.支持运算符重载
f.支持泛型编程
1.5 用途
(1)用于游戏开发
(2)系统开发和驱动开发
1.6 编程变化
(1)文件的扩展名
源文件:.cc/.C/.cxx/.cpp
头文件:.hpp .h
(2)头文件
#include <iostream>
#include <cstdio>
(3)输入输出
cout << / cin >>
(4)编译器变化
g++/c++ xxx.cpp
gcc/cc xxx.cpp -lstdc++
(5)命名空间
using namespace std;
2.命名空间
2.1 自定义命名空间
namespace 命名空间名
{
变量、函数等等
}
2.2 使用命名空间的方式
(1)使用名字空间指令的方式
using namespace std;
(2)使用作用域限定符
std::cout << "大家好才是真的好" << std::endl;
(3)使用名字空间声明的方式
using std::cout;
using std::endl;
cout << "大家好才是真的好" << endl;
2.3 无名命名空间
如果一个标示符没有被放置于任何命名空间中,默认放在无名/匿名名字空间中,使用方式:
::标示符
2.4 扩展
(1)命名空间中的内容可以分开去写
(2)命名空间中的函数声明和定义分开
(3)命名空间可以嵌套
3.结构体、联合、枚举不同
3.1 结构体的不同
(1)定义结构体变量时可以省略struct关键字
(2)结构体中可以定义函数
3.2 联合的不同
(1)定义联合变量时可以省略union关键字
(2)支持匿名联合
3.3 枚举的不同
(1)定义枚举类型变量时可以省略enum关键字
(2)枚举是一种独立的数据类型,不能使用整型进行赋值
4.bool类型和运算符别名
4.1 bool类型
bool 是C++中的基本数据类型,数值有两种:true 和 false, 也就是1和0,
本质上是单字节的整数,对于任意的基本数据类型都可以隐式的转换为bool类型,使用boolalpha指定输出的格式为:true 和 false
bool类型可以定义变量,作为函数的返回值和参数,也可以定义指针
4.2 别名
&& and & bitand
|| or | bitor ...
----------------------------------
今天内容:
(1)C++中的函数
(2)动态内存
(3)引用
(4)类型转换
(5)C++社区对C程序员的建议
1.C++中的函数
1.1 函数的重载
(1)重载的概念
在同一个作用域中,函数名相同,函数的参数列表不同构成重载关系,在不同的作用域中遵循标示符隐藏原则
(2)函数重载的方式
a.函数名相同,参数类型不同
b.函数名相同,参数个数不同
c.函数名相同,参数顺序不同
d.函数名相同,const修饰的常函数和普通成员函数构成重载(以后讲到)
(3)比较特殊的重载方式
(4)重载匹配的原则
完全匹配 > 常量转换 > 升级转换
> 标准转换 > 自定义类型转换(以后讲到) > 省略匹配
1.2 函数重载的原理
(1)C++编译器通过对函数进行换名,将参数表信息体现在新的函数名中,从而实现重载
如:
void show(int i,int j){}
=> _Z4showii; 换名之后的新名字
void show(int j,int i)
=> _Z4showii;
(2)C程序也可以通过C++编译器换名后的新函数名调用C++模块中的函数
(3)通过extern "C" 关键字可以明确要求C++编译器不要对函数进行换名的操作,以满足C程序可以直接调用C++模块中的函数
1.3 缺省参数
函数的参数有缺省值,也就是默认值
如:
void foo(int i,char c = 'A',char* p = NULL) {...}
foo(66,'B',"hello");
foo(66,'B'); // p = NULL;
foo(66); // c = 'A',p = NULL
注意:
(1)缺省参数必须靠右。如果某一个参数带有缺省值,那么该参数右边的所有参数都必须有缺省值
如:
void foo(int i,char c = 'A',char* p){} // error
foo(66,"hello");
(2)如果函数的声明和定义分开,那么缺省参数的值只能写在函数的声明部分
如:
void foo(int i,char c = 'A',char* p = NULL);
void foo(int i,char c,char* p){}
(3)注意防止由于缺省参数而引发的重载冲突问题
扩展:
(1)void fn(){}; 在C语言中表示可以接受任意多个任意类型的实参;在C++中表示不接受任何实参
(2)在C语言中可以不对函数进行声明,会自动做隐式声明;在C++中调用函数之前必须对所调用的函数进行声明,或者将被调用函数的定义放在调用函数之前
1.4 哑元
只有数据类型没有名称的参数叫哑元
如:
void fn(int){}
fn(); //error
fn(66); // ok
用途:
(1)为了兼容以前的代码
(2)用于运算符重载,主要用于区分前后缀自增减运算符(以后讲到)
1.5 内联
使用inline关键字修饰的函数叫做内联函数
类似于C语言中的宏函数,可以进行指令的替换,相对于宏函数有一定的优势,可以检查数据类型,可以计算表达式的值等等
注意:
inline关键字修饰函数,仅仅表示这是一种建议而不是要求,所有使用inline关键字修饰的函数不一定会做内联的处理;反之,没有使用inline关键字修饰的函数也可能根据编译器的优化策略进行内联处理
练习:
自定义一个计算int类型参数平方的函数,并且通过返回值返回计算的结果,分别使用inline修饰和不修饰去观察是否内联
扩展:
(1)多次调用的小而简单的函数适合内联
(2)调用次数极少并且大而复杂的函数不适合内联
(3)递归函数无法内联
2.动态内存
C语言中: malloc/calloc/realloc/free 函数
C++中:
除了提供对C的兼容之外,还提供了 new/delete运算符来管理动态内存
2.1 申请指定数据类型变量大小的内存
int* pi = new int;
delete pi; pi = NULL;
int* pi = new int(66);
delete pi; pi = NULL;
2.2 申请指定的数组大小的内存
int* pi = new int[10];
delete[] pi; pi = NULL;
//C++11/C++0x标准支持
int* pi = new int[10]{...};
delete[] pi; pi = NULL;
提问:
int* pi = new int; //ok
int* pi = new int[5]; //ok
int* pi = new int[3][4];//error
int** pi = new int[3][4]; error
2.3 使用new操作符分配N维数组时,返回N-1维的数组指针
如:
int (*pi)[4] = new int[3][4];
delete[] pi; pi = NULL;
int (*pi)[3][4]
= new int[2][3][4];
delete[] pi; pi = NULL;
在[]后面使用{}进行初始化,需要C++11/C++0x标准的支持
2.4 定位分配
new(指针) 数据类型(初始值);
|
这里的指针表示分配内存的起 始位置
功能:
主要用于在一个已经分配好的内存空间再次分配内存
3.引用
3.1 概念
引用并不是一种独立的数据类型,类似于C中的指针,其实是变量的别名
如:
int a = 10;
int& b = a;
=> 给a起了个别名叫b,b = 10;
int& c = b;
=> int& c = a; c = 10;
3.2 引用和指针的区别
(1)引用必须初始化,指针可以不初始化
int& a; // error
int* pa; // 野指针
(2)引用不可以为空,指针可以为空
int& a = NULL; //error
const int& a = NULL; //常引用
const int& a = 11; // ok
int* pi = NULL; //空指针
(3)引用不可以更换目标,指针可以
int a = 10;
int& b = a;
int m = 20;
b = m; => a = m; 赋值
int* pi = &a;
pi = &b;
(4)不能声明引用型数组,可以声明指针型数组
int& arr[10]; //error
int* arr[10]; //ok
int arr[10]; //ok
int (*arr)[10]; //ok
建议:
在C++程序尽量去使用引用,而少使用指针,因为指针容易出现野指针,容易出现段错误