【CC++】基础知识点 简单汇总

目录


1. C语言 基础知识概述

  1. 优先级部分:
    1. 数组下标[] () .(成员选择) ->(成员选择)
    2. 自右到左运算: - ~ ++ – *(指针变量) & ! (类型) sizeof
    3. 算数运算符 逻辑运算符&& ||
  2. switch() 参数只能是整型变量;
  3. while语句与do…while语句的不同在于:do…while先执行一次循环条件,再判断循环条件;
  4. break语句作用是跳出最近的内循环语句,或者终止switch中的case并跳出该switch结构;continue则是终止本次循环,并执行下一次循环;
  5. c语言中使用char数组来实现字符串;以数字0或’\0’结尾,若不是该结尾方式,则是普通的字符数组;
  6. 字符串处理函数:
    1. gets()和scanf()无法知道字符串的大小,且易越界;fgets()避免了这些问题;
    2. puts()在输出完成后,自动输出’\n’;而 fputs()不会输出;
    3. strlen()计算字符串长度不包含结束符’\0’; sizeof() 计算时包含’\0’;
    4. strcpy(char *dest, const char *src),结束符也将被拷贝;strncpy()只拷贝指定长度;
    5. strncat()只是将src的前n个字符连接到dst上,后面追加’\0’;
    6. sprintf(),sscanf()涉及转换及格式化数据;
    7. strchr()用于查找字符串中的字符,并返回第一次出现的地址;而strstr查找的是字符串的地址;
  7. 子函数中使用return代表子函数结束,调用exit()表示程序终止;
  8. 避免同一个文件被多次include:
    1. 使用 #ifndef #define #endif
    2. 使用 #pragma once
  9. NULL是一个值为0的宏常量;
  10. 指针:
    1. const 指针具有左定值,右定向的功能;当const (指针类型) (指针变量)时,指针指向的值保持不变;当 (指针类型) const (指针变量) 时,指针的指向保持不变;
    2. 数组名是数组的首元素地址,是一个常量,不能够被修改;
    3. 指针+±-操作的是指针指向的类型宽度;
  11. 变量
    1. static局部变量作用域是在定义的函数内有效,其生命周期和程序的运行周期一致;
    2. 静态全局变量在函数外定义,作用范围被限制在所定义的文件中;
    3. 不同文件的static函数名可以相同,只能在定义这个函数的文件中使用;
  12. 打印–输出
    1. %p是打印地址的, %x是以十六进制形式打印;
//sizeof  strlen
#include<stdio.h>
#include<string.h>

main()
{
	char x[]="STRING";
	x[0]=0; x[1]='\0';x[2]='0';
	printf("%d %d\n",sizeof(x),strlen(x));
   // 输出 7,0
}

参考:

  1. 黑马:C基础讲义.doc

  2. 与 或 异或

& 按位与, | 按位或 , ^ 按位异或
AND (位与&) OR ( 位或| ) XOR ( 位异或^ )
1 & 1 = 11 | 1 = 11 ^ 1 = 0
1 & 0 = 01 | 0 = 11 ^ 0 = 1
0 & 1 = 00 | 1 = 10 ^ 1 = 1
0 & 0 = 00 | 0 = 00 ^ 0 = 0


2. C++知识

  1. 命名空间std封装的是标准库的名称,标准程序库为了和以前的头文件区别,一般不加 .h;

  2. C C++ 区别

    1. C语言中只有一个全局作用域;所有的全局标识符共享一个作用域;
    2. C++变量检测增强,不允许定义多个同名的全局变量;C++对于struct一组变量的集合,c++认为是一个新类型的定义说明;
    3. int fun( ); c语言中可以接受任意参数的函数;C++中表示无参函数;
    4. C++中新增bool类型;
  3. C++ 中const修饰的,是一个真正的常量,而不是c中的只读变量,有自己的存储空间;

    1. C++中为全局变量且在其他文件中使用,或使用&取const常量地址时,会分配存储空间,const修饰引用时,也会分配存储空间;
  4. 引用:

    1. 引用在C++的内部实现是一个常量指针;Type& name 等价于Type* const name;
    2. 引用所占用的内存空间与指针保持一致;在64位系统中占用8个字节;
    3. 引用,指针,复制;
    4. 当函数的返回值为引用时,若返回栈区变量,不能成为其他引用的初始值,不能作为左值使用;若返回静态变量或全局变量,可以成为其他引用的初始值,既可以作为右值使用,可以作为左值使用;
    5. 被调用函数作为左值时,必须返回一个引用;const Type& name = var;让变量拥有只读属性;
  5. 函数的扩展:

    1. C++中的const常量替代宏常数定义;使用inline声明的内联函数替代宏代码片段;宏代码片段有预处理器处理,进行简单地文本替换,没有任何编译过程;
    2. inline只是一种请求,编译器不一定响应;内联函数省去了普通函数调用时的压栈、跳转和返回的开销;
    3. 默认参数和函数的占位参数结合可以为以后的程序扩展留下空间,兼容C程序;
    4. 函数重载:同一个函数名搭配不同的函数参数;参数个数/参数类型/参数顺序三者其一,注意重载中的默认参数,发生在一个类中;
  6. struct定义类,所有成员的默认属性是public;class的默认属性是private;

  7. C++ 编译器提供的默认copy构造函数、等号操作均属于浅拷贝;

    1. 成员变量的初始化顺序与声明的顺序相关,与在初始化列表中的顺序无关;
    2. 构造函数:当类中成员变量是其他类的对象时,首先调用成员变量的构造函数,调用顺序与声明顺序相同,之后调用自身类型的构造函数;析构函数(destructor)调用顺序与对应的构造函数相反;
  8. 对象的动态建立与释放:

    1. new delete : 用 new 分配数组空间时,不能够指定初始值;且应该判断返回值是否是空指针;
    2. Box *pt=new Box(12,15,18); new时可以直接对新建立的对象进行初始化;new申请堆空间未必成功,应判断返回值;
    3. malloc不会调用类的构造函数, Free不会调用类的析构函数;
    4. static静态成员变量由多个对象共享,局部于类,不是对象成员;
    5. 静态成员函数提供不依赖类数据结构的共同操作,没有this指针;调用:使用 类名:: 作限定词或通过对象调用;不能调用普通成员变量;
  9. 面向对象模型:

    1. 成员变量:普通成员变量 存储在对象中;静态成员变量存储在全局数据区中;
    2. 当类中含有static成员变量时,该变量是存储在静态区当中的,它是一个共享的量,因此,在类创建一个实例对象的时候,是无需再为static成员变量分配空间的,sizeof(对象)的大小排除静态成员变量;
    3. 成员函数存储在代码段
    4. C++中的普通成员函数 都隐式包含一个指向当前对象的this指针;静态成员函数不包含指向具体对象的指针;
  10. 友元

    1. 若类B是类A的友元类,则B类中的所有成员函数均是类A的友元函数;
    2. 友元类通常设计为一种对数据操作或类之间传递消息的辅助类;
  11. 运算符重载

    1. 函数重载:一个函数名可以代表不同功能的函数;对一个已有函数赋予新的含义;
    2. 运算符重载的本质是一个函数;不能够进行重载的运算符: . :: .* ?: sizeof
    3. 可以对运算符做出新的解释;但不改变运算符的优先级、结合性、所需要的操作数,不创建新的运算符;
    4. 运算符重载只是定义了相对于一个特定类的新运算符,原有意义没有失去;
    5. 运算符重载的两种方法:   //全局什么的看不懂;
    6. 运算符函数可以重载为 成员函数 或是 友元函数 ,区别在于成员函数有 this指针,而友元函数没有;但两者的使用方法相同;-- 但是传参的方法不同,实现代码不同,使用场合不同;
    7. 在参数需要隐式转换的情况下,使用友元函数 重载运算符是正确的的决定;
    8. 数组下标运算符[]
    9. 是 二元运算符;
    10. 只能用于 成员函数重载,不能用于友元函数重载;
    11. x[y] 可以理解为: x.operator
    12. x ( arg1, arg2, … ) 可以理解成: x . operator () (arg1, arg2, … )
    13. 以上两式 x 为对象;

    看到5 没看完 P92

  12. 继承和派生

    1. C++的 继承方式(public、private、protected) 会影响子类的对外访问属性;
    2. 继承
      1. 子类 拥有父类的所有成员变量和成员函数;
      2. 子类可以拥有父类 没有的属性和方法;
      3. 子类对象 可以当做 父类对象使用;
    3. 派生
      1. 访问控制
        1. 派生类 继承了 除了构造和析构成员方法 之外的基类的全部成员函数及成员方法;
        2. 这些成员的访问属性,可在派生的过程中调整;
    4. 继承方式改变继承成员的访问属性:
      1. public继承: 所有父类成员在子类中保持原有的 访问级别;
      2. private继承: 所有父类成员在子类中变成 private成员;
      3. protected继承: 父类中,public 变 protected;
        protected 仍是 protected;
        private 仍是 private;
      4. private成员: 在子类中仍然存在,但却无法访问;
        1. 无论哪种方式继承 基类, 派生类都不能直接使用基类的私有成员;
    5. public、protected、private 的访问级别:
      1. public: 能够被外界访问的成员;
      2. protected: 当前类和子类中 被访问;
      3. private: 只能在当前类中被访问;
    6. 继承中的 构造和析构
      1. 公有派生类 具备了基类的所有功能,在需要基类对象的任何地方,都可以使用 公有派生类的对象进行替代;
      2. 子类就是特殊的父类;
    7. 继承中的对象模型
      1. 类 在C++编译器的内部可以理解为结构体;
      2. 子类 是由父类成员叠加子类新成员得到的;
      3. 基类、派生类    – 父类、子类
      4. 继承中的构造 & 析构
        1. 子类对象构造时,需要调用 父类构造函数 对继承来的成员进行初始化;
        2. 子类对象析构时,需要调用 父类析构函数 清理继承来的成员;
      5. 继承中的 构造析构调用原则:
        1. 子类对象 在创建时会首先调用父类的构造函数
        2. 当父类的构造函数执行结束后,执行子类的构造函数
        3. 当父类的构造函数有参数时,需要在子类的初始化列表中 显式调用;
        4. 析构函数调用的先后顺序 与构造函数相反;
        5. 调用顺序: 继承与组合混合搭配的情况下:
          1. 先构造父类,再构造成员变量,最后构造自己的; //依次序多重继承时,先构造第一父类,依次继承构造;
          2. 先析构自己,再析构成员变量,最后析构父类;  //与构造顺序 相反;
          3. 先构造的对象,后释放;
        6. 继承中同名成员变量 处理方法:
          1. 子类成员变量 与 父类成员变量 同名时,子类从父类中继承同名成员;
          2. 使用作用域 :: 进行同名成员的区分;-- 在派生类中使用基类的同名成员,要显式使用 类名限定符::
            // d.base::b = 2; – d derived 派生类;
          3. 同名成员存储在 内存的不同位置;
        7. 基类成员 的作用域延伸到所有派生类;
          1. 派生类的重名成员 屏蔽基类的同名成员; 屏蔽基类的同名成员函数,调用自身的成员函数;
      6. 派生类中的static 关键字:
        1. 基类定义的静态成员,将被所有派生类共享;
        2. 派生类中访问静态成员: 类名::成员 或是 对象名.成员
      7. static 访问
        1. 也遵守:3个访问原则: private protected public
        2. 派生类 对基类成员的访问 由继承方式和成员性质决定;
        3. 不但要初始化,更重要的 显式高速编译器分配内存;
        4. 构造函数默认private;
  13. 多继承

    1. 一个类 有多个直接基类的几个关系:   --直接继承自多个基类;
    2. 虚继承:
      1. 一个派生类从多个基类派生,而这些基类又有共同的基类:则在对该类声明的名字进行访问时,可能产生二义性; 使用上层基类::x 访问上上层基类的成员;   --P117
      2. 使公共基类在派生类中只产生一个子对象,必须将该基类声明为 虚继承; 使公共基类成为虚基类;
      3. 虚基类 声明使用关键字 virtual; ---- 再看 P119 图片分析;
  14. 多态

    1. 概述:

      1. 父类中被重写的函数依然会继承给子类; 默认情况下,子类中重写的函数将隐藏父类中的函数;
      2. 通过 作用域符号:: 可以访问父类中的被隐藏的函数;    – 多态 看不懂了;
      3. 多态: 同样的调用语句 有不同的表现形态;
        根据实际的对象类型决定函数调用语句的具体调用目标;
      4. 父类和子类指针的步长不同,不要用父类指针++ 方式操作数组;
    2. 多态 实现

      1. C++通过virtual关键字对多态进行支持;
      2. 使用 virtual 声明的函数被重写后可以展现出多态特性;
    3. 多态成立的3个条件:

      1. 要有继承;
      2. 要有函数重写;
      3. 要有父类指针(父类引用)指向子类对象; --重要
        – 根据指针所指向的实际对象类型 来判断如何调用;
        // 多态时设计模式的基础,是框架的基础;
    4. 理论基础

      1. 静态联编 动态联编
        1. 联编: 一个程序模块、代码之间互相关联的过程;
        2. 静态联编: 程序的匹配、连接在编译阶段完成; --重载函数使用静态联编; – golang只有静态编译;
        3. 动态联编:程序联编推迟到运行时进行(迟绑定); --switch、if语句是动态联编;
    5. 函数重载 & 函数重写

      1. 函数重载
        1. 必须发生在同一个类中;
        2. 子类无法重载父类的函数,父类同名函数将被覆盖;
        3. 重载是在 编译期间 根据参数类型和个数决定函数调用;
      2. 函数重写
        1. 必须发生在 父类和子类 之间;

        2. 并且父类与子类中的函数必须具有完全相同的原型;

        3. 使用 virtual 声明之后能够产生多态,(如果不使用virtual,叫重定义)

        4. = 多态是在运行期间根据 具体对象的类型决定函数调用;

          一、重载(overload)
          (1)相同的范围(在同一个作用域中) ;
          (2)函数名字相同;
          (3)参数不同;
          (4)virtual 关键字可有可无。
          (5)返回值可以不同;
          
          二、覆盖(override)是指派生类函数覆盖基类函数,特征是:
          (1)不在同一个作用域(分别位于派生类与基类) ;
          (2)函数名字相同;
          (3)参数必须相同,即使参数协变也不行
          (4)基类函数必须有 virtual 关键字。
          (5)返回值相同(或是协变),否则报错;
                有关 协变 的概念见 请见本人的另一篇文章http://blog.csdn.net/miyunhong/archive/2009/09/16/4557517.aspx
          
          三、重写 (overwrite)
          (1)不在同一个作用域(分别位于派生类与基类) ;
          (2)函数名字相同;
          (3)返回值可以不同;
          (4)参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别与重载混淆) 。
          (5)参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆) 。
          
          ==参考:==
          1. []()
          
    6. 派生类的 析构函数

      1. 析构 由基类指针建立的派生类对象 没有调用派生类的析构函数;
      2. 析构 由派生类指针建立的派生类对象 正确使用派生类析构函数;
  15. 多态原理探究

    1. 理论
      1. 虚函数表的指针 (vptr)
    2. 多态的实现原理
      1. 类中 声明虚函数时,编译器会在类中生成一个虚函数表;
      2. 虚函数表是一个存储类成员指针的数据结构;
      3. 虚函数 是有编译器自动生成与维护的;
      4. virtual成员函数会被编译器放入到虚函数表中;
      5. 存在虚函数时,每个对象都有一个指向虚函数表的指针; --vptr指针
    3. 编译器确定 函数是否是虚函数
      1. 不是虚函数,编译器可直接确定被调用的函数; --静态编译;
      2. 是虚函数,根据对象的vptr指针,在所指的虚函数表中查找fun()函数,并调用;
        – 查找和调用 在运行时完成(实现所谓的动态编译)
        与普通函数相比,虚函数的效率要低很多;
        子类对象构造时,在父类的构造函数中调用虚函数,产生不了多态;
  16. 纯虚函数和抽象类

    1. 基本概念
      1. 纯虚函数: 是一个在基类中说明的虚函数,在基类中没有定义,要求 任何派生类都定义自己的版本;
      2. 纯虚函数为各派生类提供了一个公共界面(接口的封装和设计、软件的模块功能划分);
      3. 说明式: virtual 类型 函数名(参数表) = 0;
      4. 一个具有纯虚函数的基类 称为抽象类;
    2. 抽象类
      1. 抽象类不能建立对象; ???
      2. 抽象类不能作为返回类型;
      3. 抽象类不能作为参数类型;
      4. 可以声明抽象类的引用; 可以声明抽象类的指针;
    3. 抽象类在多继承中的应用:
      1. 抽象类 可以模拟java的接口类;
      2. 多继承带来的代码复杂性远胜于其带来的便利;
      3. 在设计方法上,任何多继承都可以用单继承代替;
      4. C++中使用纯虚函数 实现接口;绝大多数面向对象的语言都不支持多继承;
    4. 多继承应用场景
      1. 接口类只有函数原型定义,没有任何数据的定义;
      2. 接口类 只是一个功能说明,而不是功能实现; 子类需要根据功能说明定义功能实现;
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值