C++之再看笔记

来源:互联网 发布:网络给人们带来的好处 编辑:程序博客网 时间:2024/05/22 23:51

第一章 C++的基本知识
1.标识符是由大小写字母、数字字符和下划线组成,且以字母和下划线开始的字符序列。标识符可用作
变量名、常量名、函数名、自定义的数据类型等。
    定义标识符时应注意一下几点:
    ●  标识符的有效长度不能超过247个字符,当超过限制时,系统
        只能识别前247个字符,其余无效。
    ●  区分大小写。
    ●  采用标识符含义的英文单词或汉语拼音来命名。
    ●  命名标识符时,不采用关键字。
2.
----------------------------------------------------------------------------------------------
   类    型                    名     称         占用字节数            取值范围
----------------------------------------------------------------------------------------------
  char                       字符型                   1                -128·127        
  [signed] char              有符号字符型             1                -128·127           
  unsigned char              无符号字符型             1                0·255                
  short [int]                短整型                   2                -32768·32767                       
  signed short [int]         有符号短整型             2                -32768·32767                       
  unsigned short [int]       无符号短整型             2                0·65535                       
  int                        整形                     4                -2e31·(2e31)                       
  signed [int]               有符号整形               4                -2e31·(2e31)                       
  unsigned [int]             无符号整形               4                0·(2e31)                      
  long [int]                 长整形                   4                -2e31·(2e31)                                                               
  signed long [int]          有符号长整形             4                -2e31·(2e31)                       
  unsigned long [int]        无符号长整形             4                0·(2e31)                       
  float                      实型                     4                约-3.4e38·3.4e38
  double                     双精度型                 8                约-1.7e308· 1.7e308
  long double                长双精度型               8                约-1.7e308· 1.7e308
  void                       无值型                   0                              
----------------------------------------------------------------------------------------------
注意:上表中,【】表示可以省略,比如,在int之前有修饰符时,可以省去关键字int,即short等价于
short int等等。另外,无修饰词的int和char,编译程序认为是有符号的,即int等同于signed int,char
等同于signed char.

3.常量具有固定的值,在程序执行期间不发生变化。常量分为两类,一类是直接使用的常量,称为字面
常量;一类是经过说明或定义后才能使用的常量,称为标识符常量。

4.八进制数常量,以0(零)为前缀,其后面有0·7中的数字组成。
  十六进制数常量,以0x或0X为前缀,其后面由0·9之间的数字和a·f或A·F之间的字母组成。

5.整形常量中的长整形有L(或l)作后缀表示。123L和123从值的大小上来看没有区别,但在内存
  空间中的存储格式却不一样。

6.当没有明确指定为长整形或无符号整形常量时,编译时可根据常数的大小,由编译系统自动进行识别。

7.<小数>E(或e)<指数> 小数部分不能省,指数部分可正可负,但必须是整数。

8.“/”、“’”、“””,特殊字符,‘//’表示字符“/”‘/’’表示单引号“’”
  ‘/”’表示双引号“””。

9./后跟八进制数或十六进制数,表示ASCII码为该八进制数或十六进制数的字符。其取值范围必须在
  0·255(十进制)之间。当用八进制数时,前面的0可以省去,二十六进制数必须以x(X)或0x(0X)
  开头。

10./a    响铃

11.用常量说明符const定义常量时,必须对它初始化,一经定义,程序中不能改变它的值。
   用#define定义常量时,标识符与常量之间不用等号。

12.同一个变量在同一作用域内只能作一次定义性的说明。

13.把sizeof当作了求数组元素的个数,那么应该怎么求数组元素的个数呢Easy,通常有下面两种写法:
  int c1 = sizeof( a1 ) / sizeof( int ); // 总长度/单个元素的长度
  int c2 = sizeof( a1 ) / sizeof( a1[0] ); // 总长度/第一个元素的长度

14.取余运算符(%)的两个操作数只能为int 型或char型,其结果为整除后的余数

15.int a=34,b=2,c;
   c=a<<b;  //将a的二进制形式的各位数向左移位2位
   此时a的值保持不变,依然为34,而将移位后的结果136赋给c

16.单目运算符(++,--)操作数必须为变量

17.在计算逻辑表达式的过程中,一旦可以确定整个表达式的值,就不在继续计算该表达式的剩余部分

18.赋值表达式的值为左操作数的值,即最左边的变量的值

19.都好运算符的结合性为右结合,且整个逗号表达式的值和类型与最后一个表达式的值和类型一致

20.将实行数(双精度数)赋给整形变量时,值取实型数的整数部分,何去小数部分
   当整数部分超过整数的范围时,赋值的结果错误。

21.float a=3.4;
   int b=(int)a;  //对a进行强制转换后,a依然为float类型,值依然为3.4
   对一个变量无论进行强制转换还是自动转换,只是以该变量的转换类型参与运算,
   变量本身的类型和值都没有改变

22.int a=2,b=3,c=5,d=6;
   float x=3.2,y=4.6;
   cout<<4<<'/t'<<5.34<<endl;
   cout<<a<<'/t'<<b<<'/t'<<c+d<<endl;
   cout<<x<<'/t'<<y+2<<endl;
   运行该代码,输出结果为:
   4 5.34
   2 3 11
   3.2 6.6
   系统在运行cout的一系列“<<”操作时,想将各表达式的值从右向左一次存储到缓冲区,
   当刷新缓冲区,则按从左到右的顺序输出,因为插入运算符的结合性为右结合


第二章 流程控制语句

1.x>y?1.5:1
  如果x>y为真,该表达式的值为1.5;若x>y为假,则该表达式的值为1.0

2.default分支语句可以放在switch语句中的任何位置,但通常为最后一个分支,因为在它后面的case分支
  不起任何作用

3.goto语句可以从条件语句或循环语句的内部跳转到条件语句或循环语句的外部,但不能从条件语句或
  循环语句的外部跳转到条件语句或循环语句的内部。一个函数体内的goto语句不能跳转到函数体外,
  也不能跳转到另一个函数


第三章 函数和编译预处理

1.函数返回值为整形时,可省略类型标识符int。当函数没有返回值时,必须规定其类型为void。

2.在一个函数中可以有多个return语句,遇到return语句,立即结束函数的执行。

3.函数调用的过程是:先计算各实参表达式的值(对有参函数),然后将所求的值传递给相应的形参。

4.函数的重载:参数必须满足两个条件之一:●  参数的个数不同  ●  参数的类型不同
  仅仅是函数的返回值不同不能区分两个函数

5.编译调用内联函数的语句时,编译器将内联函数的代码插入到函数调用处,这样在运行过程中,将直接
  运行插入的代码,而不需要花费实参入栈等一系列的开销,从而可以提高程序运行的速度。
  在内联函数中不能包含复杂的结构控制语句,比如循环语句、switch语句和嵌套的if语句,否则编译
  系统将该函数作为普通函数处理

6.void Block3(int s)
     {
      if(s>0) int i=1;      //i的作用域从此开始,到此结束
      else double i=2.1;    //i的作用域从此开始,到此结束
      cout<<i<<endl;        //错误,因为在此块内,没有变量i的存在!
      }
  块嵌套问题:当块A包含B,则在块B中可以使用在快A中的定义的标识符,反过来则不行。另外当块A中
  定义的标识符与块B中定义的标识符同名时,则在块B中的标识符将屏块A中的同名标识符,即局部优先

7.void Block4()
     {
      if(int i=2) i+=1;       //i的作用域从此开始
      else i+=2;              //i的作用域到此结束
      cout<<i<<endl;          //错误,i没有定义
      }
  对if语句或switch语句的表达式中定义的标识符,其作用域在该语句内

8.void Block5()
 {
  int i,j=3;
  for(i=0;i<10;i++)
  {
           cout<<"i="<<i<<endl;//依次输出1·10
   int j=9;
   int i=4;
   cout<<"i="<<i<<endl;//每次输出4
   cout<<j<<endl;      //每次输出10
  }
  cout<<"i="<<i<<endl;        //只输出一次10
  cout<<j<<endl;              //只输出一次3
 }
  在for语句的第一个表达式中声明的标识符,其作用域为包含该for循环语句的那个快

9.函数原型声明(没有函数体)中参数的作用域称为函数原型作用域。此时,参数的作用域开始于函数
  原型声明的左括号,结束于函数原型声明的右括号

10.静态类型变量属于静态存储变量,即在程序开始运行时就为其分配存储空间,当程序结束时才释放其
   所占用的存储空间
   在程序开始执行时,就对静态类型变量初始化,在其后的函数执行过程中,由于这种变量已经存在,
   系统就不再为其初始化

11.寄存器变量不能长期保存变量的值,因此,静态变量和全局变量不能定义为寄存器类型变量

12.int a=2,b=10;
   Volume(float=a+b,float=a*b);    //正确没有错
   参数的默认值可以是表达式,但表达式必须有确定的值

13.具有默认值的参数必须位于参数表中的最右边

14.在宏定义中可以使用已经定义过的宏名,但对程序中或宏定义中用双引号括起来的字符序列中的字符,
   即使与宏名相同,也不进行宏扩展

15.宏定义可出现在程序中的任何位置,宏名的作用域为从宏定义开始到本源程序文件结束,且宏定义不受
   块作用域的限制


第四章   数  组

1.数组定义中的<常量表达式>必须由字面常量、const类型的常量或宏定义的标识符构成,不能含有变量。
  另外<常量表达式>的值一定要为正整数

2.int a[3][4]={{1,2},{4}};              // 正确  第二行的元素都为0
  int a[3][4]={{1,2},{4},{  }};         // 错误 第三行花括号中不能为空
  在利用这种方法进行初始化时,花括号划定的数组可以小于数组的行数,但花括号中不能为空

3.在定义二维数组时,只能省略数组的行数,不能省略数组的列数。而且在省略行数时,必须同时对该
  数组进行初始化

4.char str2[6]={'a','b','c','d','e','f'};
  cout<<str2;            //除了输出abcdef外,后面还有一串其他字符
  当字符数组的整体输出时,它输出到'/0'为止

5.字符串连接函数:strcat(str1,str2)
  在调用strcat函数时,注意必须保证str1所在的字符数组要有足够剩余空间容纳str2,
  即要满足sizeof(str1)>strlen(str1)+strlen(str2)   //是对的

6.在进行部分字符串拷贝和连接操作时,由于新的字符串没有指定结束标志,因此要另外加上


第五章  结构体、共用体和枚举类型

1.struct stru
 {
         auto int x;                //错误  结构体的成员不能指定为自动存储类型
         regiser float y;           //错误  结构体的成员不能指定为寄存器存储类型
         extern char z[10];         //错误  结构体的成员不能指定为外部存储类型
  static in i;               //正确
 };//注意后面的分号

2.struct data
 {
  unsigned x:1;
   unsigned y:4;
  unsigned z:8;
 };
  在每一个位域变量中,成员x占用1个二进制位,y占用4个二进制位,z占用8个二进制位。因此成员x只能
  为0或1,成员y的值在0·15之间,二成员z的值的0·255之间

3.在一个结构体中定义的任一个位域都必须在同一个存储单元中(4个字节共32位)

4.可以定义位数为0的位域成员,表示其下一个位域成员从下一个存储单元开始

5.一个位域成员的长度不能大于一个存储单元的长度(32位)


第六章  指针和引用

1.在对指针变量所指向的存储单元赋值之前,该指针变量必须有一个确定的值,否则将是十分危险的

2.char *pch[]={"NanJing","BeiJing","WuHan","ShenYang"};
  strcmp(pch[1],pch[2]);
  strcmp函数内的pch指针指向的不是整个数组  只是单个字符(即N或B)

3.pInt=a;                        //错误   类型不匹配
  pInt=&a[0];                    //错误   类型不匹配
  将指向数组的指针pInt指向一维数组a,注意,由于pInt是行指针,而a是一维数组名,它表示该一维数
  的首地址

4.在用new运算符为某个指针变量所指向的数据动态分配存储空间之后,必须用delete运算符进行撤销,
  否则该存储空间将一直被占用,直到关闭计算机

5.int (*p)[8]
  p=(int (*)[8])new int [8];
  p=new int[1][8];
  由于p是行指针因此在用new运算符时一定要进行强制转换

6.在用delete运算符时,只是撤销为某个指针变量所指向的数据所动态分配的空间,并没有取消该指针
  变量

7.pn=new node(3,4.5,"abc");             //错误
  在为结构体类型的指针动态分配内存空间时,不能进行初始化

8.float *fp;
  fp=new float[6000];
  if(fp==0)
 {
         cout<<"动态分配内存失败,程序终止执行!"<<endl;
  exit(3);
 }

9.new动态分配内存空间的指针必须保护起来

10.int &ref1;               //错误  没有初始化
   int i;                  
   float &ref2=i;           //错误  类型不一致
   int &ref3=4;             //错误  不能用常量初始化引用类型的变量
   在定义引用类型的变量时,必须用同类型的已定义的变量对它进行初始化。对于不同类型的变量或
   常量是不能用来对它初始化

11.可以定义对引用类型变量的引用,但不能定义引用的引用

12.用空指针,但没有空引用,也没有void类型的引用

13.float &ref1=* new float(2);
   float * &ref2=new float;
   ref2=5;
   在用new运算符为引用变量动态分配内存空间时,在其之前加上运算符*
   因为new运算符返回的是一个指针


第九章  类及对象的封装性
224 225 226 228
1.设定访问权限的关键字的访问范围为:从该关键字后的第一个成员开始,到下一个限定访问权限的
  关键字之前的所有的成员

2.类中的成员数据不能使用关键字extern、outo以及register等(static除外)

3.定义了一种数据类型,此时并没有给所定义的类分配存储空间,因此这时不能对类中的成员数据初始化

4.class
 {
  public:
 int x,y;
 }x1,x2={56,68};
  在创建对象时不允许利用这种方式对对象的私用或保护成员数据进行初始化

5.在对象是使用过程中要注意一下几点:
  ●  可用成员运算符“.”来访问对象的公有成员
  ●  同类型的对象之间可以整体赋值
  ●  对象可作为函数的参数此时属于值调用;函数也可以返回一个对象
  ●  一个类的对象可以作为另一个类的成员,称为对象成员


第十章  类的成员

1.在类体外定义成员函数时,需要在类体内作该函数的原型说明,定义时必须在函数名前加上类名与
  作用域运算符“::”表明是该类的成员函数

2.成员函数:
  ● 成员函数可以直接调用类中的任一成员数据或成员函数
  ● 一个类必须至少有一个公有成员函数,否则该类不能与外界交互
  ● 成员函数与普通函数的区别仅在于其作用域不一样

3.构造函数没有返回值,在声明和定义构造函数时,不能说明它的返回类型,即使void类型也不行

4.在创建对象引用时,由于它只是另一个对象的别名,此时不会调用构造函数。同样,在创建对象指针时,
  也不会调用构造函数,除非用new运算符或其他方法对它初始化

5.与普通函数不同的是,如果在创建对象时没有向构造函数传递实参,则在对象名后面不需要叫括号

6.要在创建对象的同时对其中的成员数据初始化,就必须定义构造函数

7.具有默认值的参数必须在参数表的右侧

8.通常,一个类中只有一个具有默认参数值的构造函数

9.当一个类能够创建带有一个实参的(类型为T)对象时:
  ● 在创建对象时可以用赋值语句进行初始化
  ● 对已创建的对象,可以将T类型的数据赋给该对象

10.在创建具有对象成员的类的对象时,先按对象成员的先后次序调用各个对象成员的构造函数

11.● const对象:a.不能改变const对象中的成员数据
                 b.const对象还有一个更苛刻的限制,即它只能访问对象中的const成员
   ● const成员函数:a.const对象只能调用const成员函数
                     b.普通对象优先调用非const成员函数
   Others:
   ● 如果将一个对象声明为const对象,则该对象中的所有成员数据均为常量,声明的同时初始化
   ● 如果将一个对象声明为const对象,该对象只能调用const成员函数,当const对象可以调用公有
      成员数据
   ● 对于const成员数据,只能在构造函数中用初始化列表的方法对它进行初始化

12.友元函数:
   ● 友元函数并不是相应的成员函数,不能像成员函数那样直接访问和修改类的成员
   ● 友元函数必须在类的定义中说明,在类外定义时在函数的前面不要加作用域运算符“::”
      也不要加关键字 friend
   ● 可以把它放在类的私有部分、公有部分或保护部分,其作用都是一样的

13.由于类CMyClass中有指针类型的数据,且用动态方式分配,因此在友元函数中CMyClass类型的参数都
   要用引用类型

14.完整地定义一个静态成员数据应该由两部分组成:
   ● 在类体内用关键字static声明静态成员数据
   ● 在类体外再一次声明该静态成员数据并进行初始化

15.对静态成员数据初始化的顺序为它们在类体外声明的顺序


第十一章  继   承


1.C++规定派生类只能继承基类中的公有成员和保护成员

2.下列成员不能被继承:构造函数、析构函数、友元函数、重载的new和delete运算符

3.私有派生,派生类中通过继承得到的基类中的公有成员和保护成员均变为私有的,即在派生类中仍可以
  直接访问它们,但在派生类之外不可以直接访问

4.C++规定,在创建派生类对象时,首先调用基类构造函数,然后再调用派生类构造函数,当撤销派生类
  对象时,析构函数的调用次序与构造函数的调用次序相反

5.构造函数的调用顺序只与派生类的基类的顺序有关,而与初始化成员列表中构造函数顺序无关,
  与派生类中参数的顺序也无关

6.class CDerived:CBase
   {
  protect:
    int CBase::y;                   //错误  数据成员的访问声明中不能有类型
  public:
  int CBase::Fun(int,int);        //错误  成员函数的访问声明不能有参数和返回值类型
 };
  正确的程序:
  class CDerived:CBase
   {
  protect:
    CBase::y;                  
  public:
  CBase::Fun;       
 };
  在访问声明时仅仅说明基类成员名,即对成员数据不可以为它说明数据类型,而对成员函数不可以说明
  参数和返回值类型

7.访问声明不允许在派生类中改变基类成员的访问类型

8.派生类的对象在调用该函数时,在没有特别说明的情况下依然是派生类中的函数优先

9.当派生类作为基类,派生出新的类时,作用域运算符不能连续使用,即下列形式是不允许的
  CName1::Cname2::.......Cnamen

10.在将公有派生类的对象赋给基类对象之后,基类对象只能访问派生类中从基类继承的公有成员,不能
   访问派生类中增加的公有成员

11.只有公有派生类的对象可以直接赋值给基类的对象、对象指针或引用。私有和保护派生是不可以的。
   在任何情况下都不能将基类对象直接赋给派生类对象

12.虚基类初始化:
   ● 为虚基类定义一个具有默认值的构造函数
   ● 在它的每一个派生类的构造函数的初始化成员列表中调用虚基类的构造函数


第十二章   虚函数和多态性


1.当编译器编译虚函数时,编译系统将用动态链接的方式进行编译。即在编译时不确定该虚函数的版本,
  而是利用一种机制(虚函数表),在运行过程根据其所指向的实例决定使用哪一个函数版本

2.虚函数的使用:
  ● 虚函数必须是类的一个成员函数,但不能是静态的成员函数
  ● 若要实现这种类型的多态性,必须使用基类的指针或引用
  ● 若虚函数为外联函数,则在外面定义函数体时,在函数名前不要加virtual
  ● 通过域运算符"::"可以抑制虚函数调用

3.当重载一个虚函数时,也就是说在派生类中重新定义此虚函数时,要求函数名、返回类型、参量个数、
  参量类型和顺序都与基类中原型完全相同,不能有任何的不同

4.当将基类指针或引用new运算符指向派生类实例时,为了在释放派生类实例时能调用派生类的
  析构函数,必须将基类析构函数定义为虚函数

5.抽象类的使用:
  ● 抽象类只能用作其他类的基类,不能建立抽象类实例(对象)
  ● 抽象类不能用做参数类型、函数返回类型或显式类型转换
  ● 可以声明抽象类的指针或引用,此指针或引用可以指向它的派生类

6.纯虚函数的使用:
  ● 定义纯虚函数时,不能定义虚函数的实现部分(函数体)
  ● 虚函数函数名赋值0并没有特别的含义,只是表明该虚函数为纯虚函数
  ● 在定义具有纯虚函数的类(抽象类)的派生类时,必须对纯虚函数重新定义,否则该类还是抽象类
  ● 当创建具有纯虚函数的抽象类的指针时,该指针不能调用抽象类中的纯虚函数,但可以调用
     抽象类中的非纯虚函数


第十三章  运算符重载

1.少数运算符不能重载:  .   ::   ?   :   *(指针运算符)   sizeof()

2.重载运算符时,不能改变它们的优先级和结合性,也不能改变这些运算符所需操作数的个数

3.在利用友元函数重载时,对于要改变操作数的运算符(比如++、--等),参数必须是引用类型或指针
  类型;对于不改变操作数的运算符(比如正号、负号等),参数不必为引用类型或指针类型

4.t3=t1+t2;
  理解为t3=t1+(t2)即这里的运算符“+”为对象t1中的重载运算符,即t1为当前操作数
  而t2为该重载运算符的参数
  双目运算符重载形式 <参数>只有一个,通常为运算符的右操作数。重载二目运算符的左操作数为
  当前对象

5.赋值运算符重载:
  ● 只能利用成员函数重载,不能用友元函数重载
  ● 重载的赋值运算符不能被继承
  ● 不能将赋值运算符重载函数声明为虚函数