C++知识整理(上)

1、 C++的两个+代表类型的加强和函数的加强。
类型的加强指的是:C++所有的标识符都必须显示的声明类型;C++出现了布尔,类等新的数据类型等等
函数加强指的是:C++引入了内联函数,重载函数,构造函数,析构函数等新的函数。
2、 布尔类型
C++在C的基础上增加了bool类型,bool只有true和false。bool只占一个字节。
3、 C++输入输出(cin和cout)
例:

#include<iostream>
using namespace std;
int main(){
    int x;
    float y;
    cout<<"Please input an int number:"<<endl;
    cin>>x;
    cout<<"The int number is x= "<<x<<endl;
    cout<<"Please input a float number:"<<endl;
    cin>>y;
    cout<<"The float number is y= "<<y<<endl;   
    return 0;
}

C++ 中的输入与输出可以看做是一连串的数据流,输入即可视为从文件或键盘中输入程序中的一串数据流,而输出则可以视为从程序中输出一连串的数据流到显示屏或文件中。
在编写 C++ 程序时,如果需要使用输入输出时,则需要包含头文件iostream,它包含了用于输入输出的对象,例如常见的cin表示标准输入、cout表示标准输出、cerr表示标准错误。
iostream 是 Input Output Stream 的缩写,意思是“输入输出流”。
cout 和 cin 都是 C++ 的内置对象,而不是关键字。C++ 库定义了大量的类(Class),程序员可以使用它们来创建对象,cout 和 cin 就分别是 ostream 和 istream 类的对象,只不过它们是由标准库的开发者提前创建好的,可以直接拿来使用。这种在 C++ 中提前创建好的对象称为内置对象。
使用 cout 进行输出时需要紧跟<<运算符,使用 cin 进行输入时需要紧跟>>运算符,这两个运算符可以自行分析所处理的数据类型,因此无需像使用 scanf 和 printf 那样给出格式控制字符串。
endl 最后一个字符是字母“l”,而非阿拉伯数字“1”,它是“end of line”的缩写。表示换行,与C语言里的\n作用相同。
第7行代码表示从标准输入(键盘)中读入一个 int 型的数据并存入到变量 x 中。如果此时用户输入的不是 int 型数据,则会被强制转化为 int 型数据。
第8行代码将输入的整型数据输出。从该语句中我们可以看出 cout 能够连续地输出。。
4、引用(Reference)
引用是 C++ 相对于C语言的又一个扩充。
引用可以看作一个已定义变量的别名,通过这个别名和原来的名字都能够找到这份数据。
引用的语法:Type& name = var;
type 是被引用的数据的类型,name 是引用的名称,var 是被引用的数据。引用必须在定义的同时初始化,
并且以后也要从一而终,不能再引用其它数据,这有点类似于常量(const 变量)。
例如:

#include <iostream>
using namespace std;
int main(){
int a = 99;
int &b = a;     // b为a的别名
cout<<a<<", "<<b<<endl;
cout<<&a<<", "<<&b<<endl;
return 0;
}

注意,引用在定义时需要添加&,在使用时不能添加&,使用时添加&表示取地址。
引用在一些场合可以代替指针,函数的引用形参不需要进行初始化!
例如:

void swap(int& a,int& b)
{
    int c = a;
    a = b;
    b = c;
}

5、 const引用
语法:const Type& name = var;
const引用让变量拥有只读属性。
使用常量对const引用初始化后将生成一个只读变量
例如:

const int& b = 0;
int* p = (int*)&b; 
*p = 1;// 修改变量a的值

6、 内联函数inline
C++使用inline关键字声明内联函数,推荐使用内联函数替代宏代码片段。
例如:

inline int func (int a, int b)
{
    return a < b ? a : b;
}

编译器直接将内联函数函数体插入函数调用的地方;内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)。
注意:对函数作 inline 声明只是程序员对编译器提出的一个建议,而不是强制性的,并非一经指定为 inline 编译器就必须这样做。编译器有自己的判断能力,它会根据具体情况决定是否这样做。
注意:要在函数定义处添加 inline 关键字,在函数声明处添加 inline 关键字虽然没有错,但这种做法是无效的,编译器会忽略函数声明处的 inline 关键字。

7、 函数重载(Function Overloading)
用同一个函数名定义不同的函数叫做函数重载。
函数重载的条件:1、参数个数不同。2、参数类型不同。3、参数顺序不同。
重载函数的函数类型不同。
函数返回值不能作为函数重载的依据。
函数重载由函数名和参数列表决定。
函数重载仅仅是语法层面的,本质上它们还是不同的函数,占用不同的内存,入口地址也不一样。
8、 extern “C”
extern关键字能强制让C++编译器进行C方式的编译
例如:

extern “C{
……
}

9、_cplusplus
_cplusplus是C++编译器内置的标准宏定义。确保C代码以统一的C方式被编译成目标文件。
例如:

#ifdef _cplusplus
extern “C”
{
#endif
……
#ifdef _cplusplus
}
#endif

10、 new
C++通过new关键字进行动态内存申请。且动态内存申请是基于类型进行的。delete关键字用于内存释放。
例如:
变量申请:

Type* p = new Type;
……
delete p;

数组申请:

Type* p = new Type[N];
……
delete[] p;

在C++中,建议使用 new 和 delete 来管理内存,它们可以使用C++的一些新特性,最明显的是可以自动调用构造函数和析构函数。
11、 命名空间(Namespace)
为了解决合作开发时的命名冲突问题,C++ 引入了命名空间(Namespace)的概念。请看下面的例子:

namespace Li{  //小李的变量定义
    FILE fp = NULL;
}
namespace Han{  //小韩的变量定义
    FILE fp = NULL
}

小李与小韩各自定义了以自己姓氏为名的命名空间,此时再将他们的 fp 变量放在一起编译就不会有任何问题。
命名空间有时也被称为名字空间、名称空间。
namespace 是C++中的关键字,用来定义一个命名空间,语法格式为:

namespace name{
    //variables, functions, classes
}

name是命名空间的名字,它里面可以包含变量、函数、类、typedef、#define 等,最后由{ }包围。
使用变量、函数时要指明它们所在的命名空间。以上面的 fp 变量为例,可以这样来使用:

Li :: fp = fopen("one.txt", "r");  //使用小李定义的变量 fp
Han :: fp = fopen("two.txt", "rb+");  //使用小韩定义的变量 fp

::是一个新符号,称为域解析操作符,在C++中用来指明要使用的命名空间。
除了直接使用域解析操作符,还可以采用 using 声明,例如:

using Li :: fp;
fp = fopen("one.txt", "r");  //使用小李定义的变量 fp
Han :: fp = fopen("two.txt", "rb+");  //使用小韩定义的变量 fp

在代码的开头用using声明了 Li::fp,它的意思是,using 声明以后的程序中如果出现了未指明命名空间的 fp,就使用 Li::fp;但是若要使用小韩定义的 fp,仍然需要 Han::fp。

using 声明不仅可以针对命名空间中的一个变量,也可以用于声明整个命名空间,例如:

using namespace Li;
fp = fopen("one.txt", "r");  //使用小李定义的变量 fp
Han :: fp = fopen("two.txt", "rb+");  //使用小韩定义的变量 fp

如果命名空间 Li 中还定义了其他的变量,那么同样具有 fp 变量的效果。在 using 声明后,如果有未具体指定命名空间的变量产生了命名冲突,那么默认采用命名空间 Li 中的变量。
命名空间内部不仅可以声明或定义变量,对于其它能在命名空间以外声明或定义的名称,同样也都能在命名空间内部进行声明或定义,例如类、函数、typedef、#define 等都可以出现在命名空间中。
站在编译和链接的角度,代码中出现的变量名、函数名、类名等都是一种符号(Symbol)。有的符号可以指代一个内存位置,例如变量名、函数名;有的符号仅仅是一个新的名称,例如 typedef 定义的类型别名。
12、C++函数的默认参数
所谓默认参数,指的是当函数调用中省略了实参时自动使用的一个值,这个值就是给形参指定的默认值。下面是一个简单的示例:

#include<iostream>
using namespace std;

//带默认参数的函数
void func(int n, float b=1.2, char c='@'){
  cout<<n<<", "<<b<<", "<<c<<endl;
}

int main(){
    //为所有参数传值
    func(10, 3.5, '#');
    //为n、b传值,相当于调用func(20, 9.8, '@')
    func(20, 9.8);
    //只为n传值,相当于调用func(30, 1.2, '@')
    func(30);

    return 0;
}

本例定义了一个带有默认参数的函数 func(),并在 main() 函数中进行了不同形式的调用。为参数指定默认值非常简单,直接在形参列表中赋值即可,与定义普通变量的形式类似。

指定了默认参数后,调用函数时就可以省略对应的实参了。

默认参数除了使用数值常量指定,也可以使用表达式指定,例如:

float d = 10.8;
void func(int n, float b=d+2.9, char c='@'){
    cout<<n<<", "<<b<<", "<<c<<endl;
}

C++规定,默认参数只能放在形参列表的最后,而且一旦为某个形参指定了默认值,那么它后面的所有形参都必须有默认值。实参和形参的传值是从左到右依次匹配的,默认参数的连续性是保证正确传参的前提。

下面的写法是正确的:

void func(int a, int b=10, int c=20){ }
void func(int a, int b, int c=20){ }

但这样写不可以:

void func(int a, int b=10, int c=20, int d){ }
void func(int a, int b=10, int c, int d=20){ }

默认参数并非编程方面的重大突破,而只是提供了一种便捷的方式。在以后设计类时你将发现,通过使用默认参数,可以减少要定义的析构函数、方法以及方法重载的数量。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值