C++入门必掌握知识点总结

7 篇文章 0 订阅

C++发展历史:

C with classes : 类及派生类、公有和私有成员、类的构造和析构、友元、内联函数、赋值运算符重载等。
C++ 1.0:添加虚函数概念,函数和运算符重载,引用、常量等。
C++ 2.0:更加完善支持面向对象,新增保护成员、多重继承、对象的初始化、抽象类、静态成员以 及const成员函数。
C++ 3.0:进一步完善,引入模板,解决多重继承产生的二义性问题和相应构造和析构的处理。
C++ 98:C++标准第一个版本,绝大多数编译器都支持,得到了国际标准化组织(ISO)和美国标准化 协会认可,以模板方式重写C++标准                   库,引入了STL(标准模板库).
C++ 03:C++标准第二个版本,语言特性无大改变,主要:修订错误、减少多异性。

C++ 05C++标准委员会发布了一份计数报告(Technical Report,TR1),正式更名C++0x,即:计 划在本世纪第一个10年的某个时间发布。

C++ 11:增加了许多特性,使得C++更像一种新语言,比如:正则表达式、基于范围for循环、auto 关键字、新容器、列表初始化、标准线                程库等。

C++ 14:对C++11的扩展,主要是修复C++11中漏洞以及改进,比如:泛型的lambda表达式, auto的返回值类型推导,二进制字面常量

C++ 17:在C++11上做了一些小幅改进,增加了19个新特性,比如:static_assert()的文本信息可 选,Fold表达式用于可变的模板,if和                     switch语句中的初始化器等。

C++ 20:  马上出。

   

C++语言入门知识:

1.关键字

2.命名空间(一个新作用域)

   为避免命名冲突,而设定的命名规则,即把变量、函数名和类等名称定义在一个命名域内,对标识符进行本地化操作。

  1)定义

       关键字 namespace   +   命名空间名称

//定义命名空间L
namespace L
{
    int a = 10;
    int b = 20;   //命名空间内 可以是变量、也可是函数
    int add(int left, int right)
    {
        return left + right;
    }
}

       命名空间可以嵌套定义:

//定义命名空间L
namespace L
{
    int a = 10;
    int b = 20;   //命名空间内 可以是变量、也可是函数
    int add(int left, int right)
    {
        return left + right;
    }
    namespace N  //N为L内的命名空间
    {
        int c;   //使用的时候强调两次  L:N:c 即可
    }
}

         

     同一个工程中允许存在多个相同名称的命名空间 ,编译器会自动把他们和在同一个命名空间内。

 2)命名空间的使用(三种方式)

      加命名空间名称及作用域限定符
      使用using将命名空间中成员引入
      使用using namespace 命名空间名称引入     

#include <iostream>
using namespace std;   //方式3

namespace Li
{
	int a = 10;
	int b = 20;

	int add(int left, int right)
	{
		return left + right;
	}
}

using Li::a;   //方式2

void namespace_test()
{
	cout << "a = " << a << endl;
	cout << "b = " << Li::b << endl;   //方式1
	cout << Li::add(10, 20) << endl;
	cout << "holle word!" << endl;
}

3.C++输入 & 输出(cin   cout)

    使用cout标准输出(控制台)和cin标准输入(键盘)时,必须包含< iostream >头文件以及std标准命名空 间。

    使用C++输入输出更方便,不需增加数据格式控制,比如:整形--%d,字符--%c
    编译器可自动识别输入参数类型,来调整标准输入/输出。

#include <iostream> 
using namespace std;
 
int main() 
{ 
    int a; 
    double b; 
    char c;
 
    cin>>a; 
    cin>>b>>c;   //输入输出时不用管参数类型
 
    cout<<a<<endl;    //编译器自动识别输出
    //输出cout   换行endl
    cout<<b<<"  "<<c<<endl;
 
    return 0; 
}

4.缺省参数

   含义:是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默 认值,否则使用指定的实                   参。

void TestFunc(int a = 0)  //0就是a的缺省参数
{ 
    cout<<a<<endl; 
}
 
int main() 
{ 
    TestFunc();     // 没有传参时,使用参数的默认值 
    TestFunc(10);   // 传参时,使用指定的实参 
}

注: 

         1)半缺省参数必须从右往左依次来给出,不能间隔着给 

         2)缺省参数不能在函数声明和定义中同时出现
         3)缺省值必须是常量或者全局变量 

         4)C语言不支持(编译器不支持)

5.函数重载

   含义: 是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形 参列表(参数个数 或 类型 或                顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。

int Add(int left, int right)
{ 
    return left+right; 
} 
double Add(double left, double right) 
{ 
    return left+right; 
}
long Add(long left, long right) 
{ 
    return left+right; 
}
 
int main() 
{ 
    Add(10, 20);     //函数名相同但传入的参数的类型不同
    Add(10.0, 20.0); //C++可支持名字修饰的编译规则
    Add(10L, 20L);   //来处理相同函数不同参数类型的问题
 
    return 0; 
}

    程序在编译器中的编译过程:main.c

       1)预处理://宏替换、头文件展开、条件编译、去掉注释  --> 生成  main.i  文件

       2)编译:// 检查语法、生成会变代码   --->  生成 main.s 文件

       3)汇编:// 把汇编代码转换成机器码  ---> 生成  main.o  文件

       4)链接:// 生成可执行程序   --->  a.out

名字修饰规则:

        C语言编译时对函数名只是前面加上下划线,来区分函数,所以不支持函数重载。

        C++的名字修饰规则不仅针对函数名,还有函数参数的类型相比比较复杂。根据这两点来区分函数。

        在不同编译器下,底层的修饰规则不同。

extern “C“:

        有时候在C++工程中可能需要将某些函数按照C的风格来编译,在函数前加extern "C",意思是告诉编译器,将 该函数按照C语言规则来编译 

extern "C" int Add(int left, int right);
 
int main() 
{    
    Add(1,2);     //按照c语言的方式来编译
    return 0; 
}

6.引用

概念:定义一个变量的引用就是给已存在的变量起个别名,等于它和最早的变量名指向同一块内存。

类型& 引用变量名(对象名) = 引用实体 ( int&  b = a), 注意:引用类型必须和引用实体是同种类型的。

特性:引用在定义时必须初始化;一个变量可以有多个引用;一个引用只能作用一个实体。

           引用只能指向变量,不能指向常量,引用和实体之间类型必须相同。

#include <iostream>
using namespace std;

void Swap(int& left, int& right)
{
    int t = left;   //利用引用作为函数参数,可实现变量的交换
    left = right;
    right = t;
}

int main()
{
    int a = 10;
    int& c = a;       //引用定义是必须初始化
    //int& e = 10;    //此句编译不过,引用不能指向常量
    int b = 20;
    //c = b;          //一个引用只能指向一个变量
    Swap(a, b);
    cout << a << endl;
    cout << b << endl;
    return 0;
}

 引用作为函数返回值时,应注意其生命周期。

int& Add(int a, int b) 
{    
    int c = a + b;    
    return c; 
}
 
int main() 
{    
    int& ret = Add(1, 2);    
    Add(3, 4);    
    cout << "Add(1, 2) is :"<< ret <<endl;    //此句输出的ret为随机数,或引用作为函数返回时
    return 0;                                 //内存中的数
}   

注意:如果函数返回时,离开函数作用域后,其栈上空间已经还给系统,因此不能用栈上的空间作为引用类型 返回。如果以引用类型返回,返回值的生命周期必须不受函数的限制(即比函数生命周期长)。

使用引用作为函数参数和函数返回值时,其效率比直接传值搞得多

引用与指针的区别:

     1. 引用在定义时必须初始化,指针没有要求 ;2. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体 ;3. 没有NULL引用,但有NULL指针; 4. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4 个字节) ;5. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小 ;6. 有多级指针,但是没有多级引用; 7. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理; 8. 引用比指针使用起来相对更安全。 

7.内联函数

概念:以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销, 内联函数提升程序运行            的效率。

 特性 : 
                 1. inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜使 用作为内联函数。                    2. inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等 等,编译器优化时会忽                       略掉内联。 3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

#include <iostream> 
using namespace std;
 
inline void f(int i);  //内联函数
                       //只用在声明时带上函数内联
 
#include "F.h" 
void f(int i) 
{
    cout << i << endl; 
}
int main() 
{
    f(10);
    return 0; 
}

宏 的优缺点:

    优点: 1.增强代码的复用性。 2.提高性能。

    缺点: 1.不方便调试宏(因为预编译阶段进行了替换) 2.导致代码可读性差,可维护性差,容易误用。3.没有类型安全的检查 。

   常见宏函数的书写:

//使用宏,写MAX比较函数

#define MAX(a, b) (a) > (b) ? (a) : (b)


//使用宏, 写add函数

#define ADD(a, b)  (a) + (b)

//使用宏, 写SWAP函数

#define SWAP(a, b)        \                  
    (b) = (a) + (b);      \
    (a) = (b) - (a);      \
    (b) = (b) - (a);      

宏与内联函数的区别 
(1)内联函数在编译时展开,宏在预编译时展开; 
(2)编译内联函数可以嵌入到目标代码,宏只是进行简单的字符串替换; 
(3)内联会做类型和语法检查,而宏不具有这样的功能; 
(4)inline函数是函数,而宏不是函数; 
(5)宏定义处理宏参数时存在边界问题(一般参数都要用括号括起来),而内联函数定义不会出现这样的问题。

宏与函数的选择
以下情况选择宏,其他情况选择函数:
(1)用宏代表简短的表达式时;
(2)在考虑效率的时候,可以考虑用宏或者内联函数;
(3)在头文件保护(防止重复编译)的时候,如:条件编译中的#ifdef、#if defined以及assert的实现。

8.aotu关键字

C++11中:auto不再是一个储存类型指示符, 它作为一个新的类型指示符来,auto声明变量时,必须指向一个已经指定类型的变量。

int main()
{
    int a = 10;
    auto b = a;  //auto定义变量必须对其进行初始化

    //用auto声明指针类型时,用auto和auto*没什么区别
    //用auto生命引用类型时则必须加&
    int x = 10;
    auto y = &x;
    auto* z = &x;
    auto& w = x;
}

注:1. auto不能作为函数的参数

        2.auto不能直接用来声明数组。

        3.auto不能定义类的非静态成员变量。

        4.实例化模板不能使用auto作为模板参数。    auto缺点:可读性差。

9. 基于范围的for循环

基本含义:解决循环范围说明的问题。

for(     :       )  :分为两部分:1.第一部分是范围内用于迭代的变量。2.第二部分则表示被迭代范围。

#include <iostream>
using namesapce std;

int main()
{
    int array[] = {1, 2, 3, 4, 5};
    for(auto& e : array)
        e *= 2;       //在数组的范围内实现每个数乘2
    for(auto e : array)
        count << e << " " << endl;

    return 0;
}

注:与普通循环类型,可以用continue来结束本次循环,也可用break来跳出整个循环。

 

10.指针空值nullptr(C++11)

C语言中:空指针用NULL来表示,而NULL是用0定义的宏。  是int型,不合适用来表示指针。

                int* p1 = NULL;  int* p2 = 0;   0 和 NULL 两个是一样的东西。

C++11:使用nullptr来表示控指针,它是char型的。

int* p = nullptr;  //nullptr-->(void*)类型

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值