C++对C的扩充

来源:互联网 发布:pmp培训 知乎 编辑:程序博客网 时间:2024/05/22 01:11
一、C++对C的扩充

1、用cout进行输出,cout必须和输出运算符<<一起使用。<<起插入作用,其结合方向是自左向右;用cin进行输入,输入流是指从输入设备向内存流动的数据流,标准输入流cin是从键盘向内存流动的数据流。>>从输入设备键盘取得数据送到输入流cin中,然后送到内存,>>常被称为提取运算符。

2、用const定义常量,在C语言中常用#define命令来定义符号常量,如
#define PI 3.1415926
在预编译时,会进行字符置换,把程序中所有的字符串PI全部置换为3.1415926。在预编译后,程序中不再有PI这个标识符。所以PI不是变量,它没有类型,也不占用内存单元,且容易出错。
而C++中可用const定义常量,如
const float PI = 3.1415926
这个PI有变量的属性,有数据类型,占用存储单元 ,有地址,可以用指针指向它,只是在程序运行期间此变量的值是固定的,不可改变。

3、在C++中,如果函数调用的位置在函数定义之前,则要求在函数调用之前必须对所调用的函数作函数原型声明,这样做的目的是使编译系统对函数调用的合法性进行严格检查,尽量保证程序的正确性。而原型声明的要求在C语言中并没有那么严格。

4、函数重载:允许一个运算符用于不同的场合时,有不同的含义,这是运算符重载(overloading)。在C++中,函数也可以重载。在C语言中,同一作用域(如同一文件模块中)中不能有同名的函数。而C++允许在同一作用域中用同一函数名定义多个函数,这些函数的参数个数和参数类型不相同,这些同名的函数用来实现不同的功能,这就是函数重载,即一个函数名多用。注意:重载函数的参数个数或类型必须至少有其中一个不同,函数返回值类型可以相同也可以不同。但是不允许参数和类型都相同而只有返回值类型不同,因为系统无法根据函数的调用形式上判断哪一个函数与之匹配。

5、函数模板:如果函数参数个数相同而类型不同,且函数体相同,那么就可以用上函数模板了。函数模板实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。在对程序进行编译时,编译系统会将实参的类型取代函数模板中的虚拟类型。函数模板的一般形式为
template<typename T>    或    template<class T>

6、有默认参数的函数:有时候在进行多次函数调用时,给形参传递的都是相同的实参值,但是其实没必要每次调用都传递这些值,为此C++提供了默认参值。如
float value(float t=1.68);
这样,t的默认值就是1.68了,如果不想取默认值,则可通过实参另外给出。如
value(8.8);
实参与形参的结合是从左至右的顺序进行的,所以指定默认值的参数必须放在形参表列中的最右端。
注意:一个函数不能既作为重载函数,又作为有默认参数的函数,因为当调用函数时如果少写一个参数,系统就无法判定是利用重载函数还是利用默认参数的函数,会出现二义性。

7、变量的引用:在C++中,变量的引用就是变量的别名,因此引用也可称为别名(alias)。建立引用的作用是为一个变量起另一个名字,以便在需要时可以方便、间接地引用该变量,这就是引用的由来。对一个变量的引用的所有操作,实际上都是对其所代表的(原来的)变量的操作。声明引用时必须同时为其初始化,即声明它代表哪个变量。在声明一个变量的引用后,在本函数执行期间,该引用一直与其代表的变量相联系,不能再作为其他变量的别名。声明引用例子如下
int a;
int &b = a;
这样,a和b代表的是同一个变量,它们代表相同的内存单元。

  C++之所以增加“引用”这个概念,主要是利用它作为函数参数,以扩充函数传递数据的功能。所以C++调用函数时有两种传递数据的方式,一种是常用的方法:将实参的值传递给形参,形参是实参的一个拷贝(形参和实参代表不同的内存单元),这种方式被称为传值方式调用(call by value); 另一种方式是将实参的地址传递给引用型形参,这时形参与实参是同一个变量(形参和实参代表相同的内存单元),这种方式被称为引用方式调用(call by reference)

  对于引用,要注意以下几点:
(1)不能建立void类型的引用,因为void的含义是无类型或空类型,void只是在语法上相当于一个类型而已,而任何实际存在的变量都是属于非void类型的。所以
void &a = 10;
这样的语句是错误的。
(2)不能建立引用的数组,因为数组名只代表数组首元素的地址,本身并不是一个占有存储空间的变量,所以
char name[10] = "lion";
char &rc[10] = name;
这样的写法是错误的。
(3)可以将变量的引用的地址赋给一个指针,此时指针指向的是原来的变量,如
int a = 10;
int &b = a;
int *p = &b;
这三句就相当于下面这句
int *p = &a;
但是不能定义指向引用类型的指针变量,即不能写成下面这种形式
int& *p = &a;
因为引用不是一种独立的数据类型,因此不能建立指向引用类型的指针变量。
(4)可以建立指针变量的引用,如
int a = 10;
int *p  = &a;
int* &pt = p;
这样pt就是一个指针变量的引用,这个指针变量指向整型变量,pt初始化为p
(5)可以用const对引用加以限定,不允许改变该引用的值,如
int a = 5;
const int &b = a;
b = 10; //试图修改引用a的值,错误
但是它并不阻止改变引用所代表的变量的值,如
a = 20; //合法
(6)可以用常量或表达式对引用进行初始化,但此时必须用const作声明,
int a = 10;
const int &b = a + 3;
对于这两名,编译会这样处理:生成一个临时变量,用来存放该表达式的值 ,引用是该临时变量的别名,系统把 const int &b = a + 3;转换成
int temp = a + 3;
const int &b = temp;
临时变量是在系统内部使用的,用户是无法访问到的。
  用这种方法不仅可以表达式对引用进行初始化,还可以用不同类型的变量对之初始化(只在能赋值兼容的类型就行),如
double d = 3.14;
const int &a = d;
编译把const int &a = d; 转换成
int temp =d;
const int &a = temp;
此时a的值就变成3,而不是3.14了。如果对上面的声明引用不用const,则会发生错误。
double d = 3.14
int &a = d; //没有加const,错误

8、内联函数:函数调用是需要一定时间和系统开销的,如果有的函数需要频繁地调用,则累计开销会比较大,这样会降低程序的效率。为了解决这个问题,C++提供了一种高效的方法:即在编译时将所调用函数的代码嵌入到主函数中,这种嵌入到主函数中的函数称为内联函数(inline function )。要把一个函数指定为内联函数,只需要在函数首行的左端加一个关键字inline即可。
  内联函数和用#define来实现的带参宏定义有些相似,但是不完全相同。宏定义是在编译前由预处理程序对其预处理的,它只作简单的字符置换而不作语法检查,往往容易出错。
如果一个函数有下面两个特点,可考虑把它作为内联函数:
(1)调用频繁,次数多;
(2)语句数量少。
如果一个函数有以下特点,则应该把它作为内联函数:
(1)函数体内有switch语句、循环控制语句;
(2)递归调用函数;
(3)内联函数不能进行异常接口声明。

9、作用域运算符(:::每个变量都有其作用域,只能在变量的作用域内使用该变量,不能直接使用其他作用域中的变量。局部变量会屏蔽全局变量。C++中提供使用域运算符 ::,它能指定所需的作用域。如
#include<iostream>
using namespace sdt;
float pi = 3.14;
int main()
{
    float pi = 3.14159;
    cout << pi << endl; //输出局部变量pi的值
    cout << ::pi << endl; //输出全局变量pi的值
}
:: 运算符不能访问函数中的局部变量。

10、字符串变量:除了可以使用字符数组处理字符串外,C++还提供了一种更方便的方法,即用字符串类型(string类型)定义字符串变量。要想使用C++标准库中的string,就必须把string的头文件加进来,即加上
#include<string>
(1)实际上,string并不是C++语言本身具有的类型,它是在C++标准库中声明的一个字符串类,用这种类可以定义对象。
注意:字符串常量以“\0”作为结束,但将字符串常量存放到字符串变量中时,只存放字符串本身而不包括“\0”。所以对下面这两句
string name = "loon";
name[1] = 'i';
name中的字符串为“lion”(共四个字符),而不是“lion”再加上“\0”。

(2)字符串变量的运算:如果用字符数组存放字符串,那么字符串的运算要用字符串函数,如strcat(连接)、strcmp(比较)、strcpy(复制),而对于string类对象,可以不用这些函数,而直接用简单的运算符。如
<1> 用赋值运算实现字符串复制:
string 1 = string2;
这句的作用与strcpy(string1, string2);相同。
<2>用加法运算符实现字符串连接
string string1 = "I love ";
string string2 = "lion";
string1 = string1 + string2;
连接后string1为“I love lion”
<3>用关系运算符实现字符串比较
可以直接 用==、>、<、!=、>=、<=等关系运算符来进行字符串的比较。

11、动态分配/撤销内存的运算符new和delete:C++为了分配和撤销内存的方便,引入了new和delete来取代C语言中的malloc和free函数,但是仍兼容这两个函数。
使用new运算符的一般格式为:
new 类型 [初值];
用new分配数组空间时不能指定初值
使用delete运算符的一般格式为:
delete [] 指针变量
new和delete是运算符,不是函数,因此执行效率高。

0 0
原创粉丝点击