C++ 学习笔记

作者: rogertan30 | 来源:发表于2016-07-20 23:30 被阅读924次

    第一章 计算机与C++编程简介

    • C++程序6个阶段
      编程 ->预处理->编译->连接->装入->执行
      1.程序在编译器中生成源程序并存盘
      2.预处理程序处理代码
      3.编译器建立目标程序并存盘
      4.连接器将目标码与库连接,生成a.out文件并将其存盘
      5.装入器把程序放进内存中
      6.cpu取出每条指令并执行

    • Cin:标准输入流

    • Cout:标准输出流

    • << :流插入运算符

    cout << "welcome to c++ ! \n";
    
    • >> :流读取运算法

    • endl
      end line的缩写,endl输出一个换行符,然后刷新输出缓冲区,即在一些系统中,输出暂时在机器中缓存,等缓冲区满时再打印到屏幕上,endl强制立即输出到屏幕上。

    cout << "sum is" << sum << endl;
    

    使用多个流插入运算符称为连接,链接或连续使用流插入操作。

    • use namespace std;
      指定用std名称空间(namespace),我们可以将我们的所有类和函数放在名字空间detail中。
      如果通过use namespace std声明,我们在使用输出流时就可以这样写:
    cout << "sum is" << sum << endl;
    

    否则我们需要在cout前加上std::

    std::cout << "sum is" << sum << endl;
    

    意思是使用std空间内命名为cout的函数

    C++标准中引入命名空间的概念,是为了解决不同模块或者函数库中相同标识符冲突的问题。有了命名空间的概念,标识符就被限制在特定的范围(函数)内,不会引起命名冲突。最典型的例子就是std命名空间,C++标准库中所有标识符都包含在该命名空间中。
    如果确信在程序中引用某个或者某些程序库不会引起命名冲突(即库中的标识符不会在程序中代表其他函数名称),那么可以通过using操作符来简化对程序库中标识符(通常时函数)的使用,例如:using namespace std;那么就可以不用在标识符在前缀std::来使用C++标准库库中的函数了

    • 未初始化变量会包含未定义值,为该变量保有内存地址中最后存放的值

    第二章 控制结构

    • static_cast <float> ( ) 强制类型转换运算附
    average = static_cast <float> (total) / gradeCounter;
    
    • setprecision( ) 设置精度,即打印小数点后几位。需要导入iomanip.h
    #incloud <iomanip.h>
    cout << "class average is" << setprecison(2) << setiosflags ( ios :: flxed | ios :: showpoint ) << average << endl;
    

    setiosflags ( ios :: flxed | ios :: showpoint )表示设置两个输出格式选项,ios :: flxed表示使浮点数值以浮点格式(而不是科学技术法)输出。即使是整数,ios::showpoint选项也会强制打印小数点和尾部0。

    表示float变量average打印小数点后两位,需导入iomanip.h。如果不指定精度,则浮点数值通常输出六位精度(默认精度)

    • a+=1, a++,++a 有些编译器在用缩写赋值运算符时能产生运行速度更快的代码。

    • 如果for结构体中有一条语句,可以不用花括号包裹代码。如果有多条语句,则应把语句体放在花括号中。

    • 最新ANSI/ISO C++草案标准实际上指定iostream.h和其他标准头文件不需要后缀.h,如iostream。

    • setw()用来控制输出间隔。

    • setiosflags(ios::left)指定输出的值为左对齐。

    • cin.get()函数表示从键盘读取一个字符。

    • while((grade = cin.get()) != EOF) 我们用EOF(通常取值为-1)作为标记值。EOF是<iostream.h>头文件中定义的符号化整数常量。如果grade的取值为EOF,则程序终止。

    测试符号化常量EOF而不是测试-1能使程序更容易移植。ANSI标准要求EOF取负整数值,但不一定是-1。这样,EOF在不同程序中可能取不同的值。

    第三章 函数

    • sqrt ()计算括号中所包含数字的平方根

    • int maximum (int,int, int); 函数声明规则

    • rand ( ) ;

    多次打印的数值顺序与第一次相同,怎么能算是随机数呢?其实这种可重复性是rand函数的一个重要特性。调试程序时,这种可重复性提供了证明修改后程序能正确工作的关键。一旦程序进行彻底调试之后,就可以调整为在每次执行程序时产生不同的随机数系列。这个过程称为随机化,是用标准库函数srand完成的。srand函数取一个unsigned类型的整数参数并内嵌rand函数,就可以在每次执行程序时产生不同的随机数系列。(此处如果需要,请百度多了解一下)

    • srand(time ( 0 ));
      srand函数只要在程序中调用一次即可得到所需的随机化结果,多次调用是多余的,会降低程序性能。

    • enum Status {CONTINUS, WON, LOST};
      作为用户自定义类型名的标示符,其第一个字母应大写。

    • 存储类说明符

    auto :局部变量默认为自动存储类,在进入声明块时生成并在退出这个块时删除。

    register : 让编译器在计算器的高速硬件寄存器中而不是在内存中保存这个变量,这样可以消除从内存向寄存器装入变量和将结果返回内存中的重复开销。

    extern : 对于一个全局变量,它既可以在本源文件中被访问到,也可以在同一个工程的其它源文件中被访问(只需用extern进行声明即可)。

    static : 一般情况下,对于局部变量是存放在栈区的,并且局部变量的生命周期在该语句块执行结束时便结束了。但是如果用static进行修饰的话,该变量便存放在静态数据区,其生命周期一直持续到整个程序执行结束。但是在这里要注意的是,虽然用static对局部变量进行修饰过后,其生命周期以及存储空间发生了变化,但是其作用域并没有改变,其仍然是一个局部变量,作用域仅限于该语句块。
    在用static修饰局部变量后,该变量只在初次运行时进行初始化工作,且只进行一次。

    了解更多 : http://developer.51cto.com/art/201104/256820.htm

    • inline
      说明这个函数是内联的,在编译过程中内联函数会直接被源代码替换,提高执行效率 如果类中的某个函数会被调用很多次或者放在循环中,那么建议将这个函数声明为内联,可以提高程序的运行效率

    • 关键字const

    1. void f (const int i) { i=10;//error! } 如果在函数体内修改了i,编译器就会报错
    2. 要指定引用常量,在参数声明的类型说明符前加上const限定符。
    • 按值调用传递的一个缺点是,如果传递较大的数据项目,则复制这个数据可能要占用相当长的执行时间。按引用调用对性能有利,因为它消除了复制大量数据的开销,但是其安全性较差,因为被调用函数能够直接访问和修改调用者的数据。

    • & : 在函数原型中概参数类型后面加上&,即可按引用调用参数。

    • 为了获得程序的清晰性和高性能,许多c++程序猿喜欢通过指针将可修改参数传递给函数(&),不可修改的小参数按值调用传递,而不可修改的大参数用常量引用传递给函数(const) 。

    • int boxVolume( int length = 1, int width = 1, int height = 1);
      为函数的参数添加默认值。使用默认值能简化函数调用,但有些程序猿认为显示指定所有参数更清楚。

    • 一元作用域运算符 ::
      如果有两个同名变量,一个是全局的,一个是局部的,那么局部的变量在其作用域拥有较高的优先权,全局变量则被屏蔽。那如果我希望在局部变量的作用域里使用全局变量怎么办,这时就要用到::作用域运算符了。

    • 函数重载
      c++允许定义多个同名函数,只要这些函数有不同的参数集(至少有不同类型的参数)。

    int square ( int x);
    double square (double y);
    

    重载是通过签名进行区别,签名是函数名和参数类型的组合。编译器用参数格式 和类型编码每个函数表示符,以确保类型安全连接。重载函数可以有不同返回类型,但必须有不同参数表。

    public @nothing2$qzcipfpd
    public @nothing1$qifzcpi
    
    • 函数模版
      重载函数通车用于不同数据类型用不同程序逻辑进行类似的操作。如果每种数据类型的程序逻辑有操作相同,那么用函数模版完成这项工作更加简洁和方便。所有的模版定义都是以关键字template开头,之后是用尖括号括起来的形式参数表。
    template <class T>
    T maximum (T value1, T value2, T value 3){
    ...
    }
    

    第四章 数组

    • 如果初始化的元素比数组中的元素少,则奇遇元素自动初始化为0。

    • "hello"之类的字符串其实就是一个字符数组。

    char string[] = {'f','i','r','s','t','\0'};
    
    • 声明为static对局部数组声明,使该数组不必在每次调用函数时生成和初始化,该数组在程序中每次退出函数时不会删除,这样可以调高性能。

    • c++使用模拟的按引用调用,自动将数组传递给函数,被调用函数可以修改调用者原数组中的元素值。但各个数组元素和简单变量一样还是按值传递。

    • 有程序中的函数不能修改数组元素。这时候需要在数组前添加const,数组元素成为函数体中的常量。

    第五章 指针与字符串

    • 指针变量的值为内存地址。

    • 尽管不是必须的,但在指针变量名中加上ptr字样能更清楚地表示这些变量是指针,需要相应的处理。

    • 作为一种风格, 很多人不愿意在程序中到处出现未加修饰的0。因此定义了预处理宏NULL (在 和其它几个头文件中) 为空指针常数, 通常是0 或者((void *)0) 。希望区别整数0 和空指针0 的人可以在需要空指针的地方使用NULL。使用NULL 只是一种风格习惯; 预处理器把所有的NULL 都还原回0, 而编译还是依照上文的描述处理指针上下文的0。特别是, 在函数调用的参数里, NULL之前(正如在0 之前) 的类型转换还是需要。NULL 只能用作指针常数;

    • &运算符是一个一元运算符,返回操作数的地址。

    • const限定符可以使程序猿告诉编译器特定变量的值不能修改。

    • sizeof运算符返回数组中的总字节数为size_t类型的值,通常是unsigned int 类型。

    • 数组取值的方法: *(bPtr + 3)即指针加偏移量。

    • 数组名相当于是数组中第一个元素的内存地址。

    • c++中可以说字符串是个常量指针,是指向字符串中第一个字符的指针。从这个意义上说,字符串像数组一样,因为数组名也是第一个元素的指针。

    • char color[] = "blue"; char *colorPrt = "blue";
      第一个声明生成五个元素的数组color,包含字符'b','l','u','e'和'\0'。第二个声明生成指针变量colorPtr,指向内存中的字符串"blue"。

    • 有时,可以将整行文本输入数组中。为此,c++提供了cin.getline函数。cin.getline函数取三个参数:存放该行文本的字符数组,长度和分隔符。
      例如:

    char semtence[80];
    cin.getline(semtence,80,'\n');
    

    声明80个字符的数组,然后从键盘读取一行文本到该数组中。函数遇到分隔符'\n',输入文件结束符或读取的字符数比第二个参数的长度少1时停止读取字符。如果遇到分隔符,则读取该分隔符并不再读入下一个字符。cin.getline默认第三个函数值为\n,因此函数可以写成cin.getline(semtence,80);

    第六章 类与数据抽象(一)

    • 声明一个结构体
    struct Time{
      int hour;
      int min;
      int second;
    }
    Time timeObject,timeArray[10],*timePtr,&timeRef = timeObject;
    

    声明timeObject为Time类型变量,timeArray为10个Time类型元素的数组,timePtr为Time对象的指针,timeRef为Time对象的引用。
    如果要打印hour成员:

    cout << timeobject.hour;
    cout << timeRef.hour;
    timePtr = &timeObject;
    cout << timePtr -> hour;
    
    • 声明一个类
    class Time{
    public:
           Time();
           void setTime (int, int, int)
           void printMilitary();
           void printStandard();
    private:
           int hour;
           int minut;
           int second;
    };
    
    • 声明一个类方法
    void Time::printMilitary()
    {
      cout << ( hour < 10 ? "0" : " ") << hour << ":"
               << ( minute < 10 ? "0" : " ") << minute;
    }
    
    • 实际对象只包含数据,因此要比包含函数的对象小的多。对类名或该类的对象采用sizeof运算符时,只得到该类的数据长度。编译器生成独立于所有类对象的类成员函数副本(只有一份)。当然,因为每个对象的数据是不同的,所以每个对象需要自己的类数据副本。该函数代码是不变的,因此可以在一个类的所有对象之间共享。

    • 头文件的#ifndef和 # define 预处理指令中用头文件名,并将圆点换成下划线。

    #ifndef TIME1_H
    #define TIME1_H
      ...
    #defint
    
    • static局部对象的构造函数只在程序执行首次到达对象时调用一次,对应的析构函数在main终止或调用exit函数时调用。

    • 析构函数在函数名称签名加~

    ~Employee();
    

    第七章 类与数据抽象(二)

    • const对象不能用赋值语句修改,因此应初始化。类的数据成员声明为const时,要用成员初始化值向构造函数提供类对象数据成员的初始值。

    • 如果成员函数不修改对象,则将其声明为const,这样可以减少许多错误。

    void print() const;
    
    • 符合increment(i) 将increment初始化为数值i。如果需要多个成员初始化值,则可以将其放在冒号后面以逗号分隔的列表中。所有数据成员都可以用成员初始化的语法进行初始化,但const和引用必须用这种方式进行初始化。
    Increment::Increment(int c,int i)
                  : increment(i)                       //成员初始化语法
    { count = c ; }                                     //赋值语句
    

    increment被声明为一个const值,如果不是用成员初始化语法,而使用赋值语句对其赋值,则会报错:

    {count = c;
    increment = i;}
    
    • 类可以将其他类对象作为自己的成员,这称之为复合。
    Employee::Employee(char *fname, char *lname, int bmonth, int bday, int byear, int hmonth, int hday, int hyear)
              :birthDate (bmonth, bday, byear),
              hireDate (hmonth, hday, hyear)
    
    • 友元函数
      友元关系是“给予”的,而不是“索取”的。
      比较像oc中a函数需要b函数的熟悉,则在a函数中引用b函数。
      点我-扩展阅读

      class Count{
        friend void setX (Count &, int);
      public:
        ...
      private:
        ...
      
      void setX (count &c, int val){
        c.x = val;
      }
      
    • 每个对象都可以通过this指针访问自己的地址。每个非static成员函数都能访问所调用成员所在对象的this指针。

    • 为了节约存储空间,每个类的每个成员函数只有一个副本,该类的每个对象都可调用这个成员函数。另一方面每个对象又有自己的类数据成员副本。

    • this -> x 或者(*this).x

    • this指针的一个有趣用法是防止对象赋值给自己。

    • Time &setTime (int, int, int); 返回地址?

    • 在ANSI C语言中,要为TypeName类型对象动态分配内存,可以用下列语句:

    TypeName *typeNamePtr;
    typeNamePtr = malloc(sizeof(typeName));
    

    这就要求调用malloc函数和显式使用sizeof运算符,在ANSIC之前的c语言版本中,还要将malloc返回的指针进行类型转换(TypeName *)。malloc函数中没有提供初始化所分配内存块的方法。
    而在c++中,只要用下列语句:

    typeNamePtr = new TypeName;
    

    c++中允许对新生成的对象提供初始化值

    float *thingPtr = new float (3.14159);
    
    • static类变量表示的是类范围中所有对象共享的信息。static数据成员的作用域是类范围。
    • static的引入
      static 是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性。函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题:如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。而static变量可以保持该变量的值,使得函数在下次调用时还保持上次函数退出时的值。

    • static内部机制
      static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间,静态数据成员按定义出现的先后顺序依次初始化,注意静态成员嵌套时,要保证所嵌套的成员已经初始化了。

    • static的优势:
      可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。

    • static类成员
      类的对象构建过程不会动到static变量和函数,因为它存在静态内存,程序加载进内存的时候它就存在;而对象生命周期不同。

    • static数据成员
      static数据成员要在程序一开始运行时就必须存在。因为函数在程序运行中被调用,所以静态数据成员不能在任何函数内分配空间和初始化。static数据成员要实际地分配空间,故不能在类的声明中定义(只能声明数据成员),也不能在头文件中类声明的外部定义,因为那会造成在多个使用该类的源文件中,对其重复定义。static数据成员必须在类定义体的外部定义(正好一次)。不像普通数据成员,static成员不是通过类构造函数进行初始化,而是应该在定义时进行初始化。

    在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。

    静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。

    初始化格式为 <数据类型><类名>::<静态数据成员名>=<值> 。初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆。

    • static成员函数
      在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员。如果静态成员函数中要引用非静态成员时,可通过对象来引用。
      静态成员函数,不属于任何一个具体的对象,那么在类的具体对象声明之前就已经有了内存区,而非静态数据成员还没有分配内存空间,那么在静态成员函数中使用非静态成员函数,就好像没有声明一个变量却提前使用它一样。
      static成员函数没有this指针,不能被声明为const,不能被声明为虚函数。

      静态相关来自于此

    • 类方法的调用

    Employee::getCount();
    
    • 即使在类没有实例化任何对象时,类的static数据成员和成员函数就已经存在并可使用。将static成员函数声明为const是个语法错误。

    • 删除动态分配内存后,设置指向该内存的指针指向0,这样就切断了指针与签名所分配内存的连接。

    • 断言: assert(first != 0 );
      如果表达式值为false,则assert发出错误消息,并调用abort函数终止程序执行。这是个有用的调试工具,可测试变量是否有正确值。

    第八章 运算符重载

    • operator+ 重载运算符+

    • 运算不重载不能改变运算符用于内部类型对象时的含义。运算符重载只能喝用户自定义类型的对象一起使用,或者用于用户自定义类型的对象和内部类型的对象混合使用。

    未完待续

    第九章 继承

    • 为了说明类CommissionWorker是从类Employee派生而来的,类CommissionWorker通常要做如下形式的定义:
    class CommissionWorker : public Employee{
      ...
    };
    
    • protected对于子、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。

    • 基类的public成员能够被程序中所有函数访问,private成员只能被基类的成员函数和友元访问。

    • 基类的protected成员只能被基类的成员和友元以及派生类的成员和友元访问。

    • 一般来说,声明private类的数据成员和使用protected方式只能是系统要满足特定性能要求时的“最后一招”。

    • 把指向基类对象的指针显式地强制转换为派生类指针,然后引用该对象中并不存在的派生类的成员会导致运行时的逻辑错误。

    • 在派生类中重定义基类成员

    Employee::print();
    
    • 派生类永远也不能直接访问基类的private成员,但可通过基类pubic或protected成员间接访问。

    • 调用析构函数的顺序和调用构造函数的顺序相反。

    • 用派生类指针引用基类的对象。这种引用方式会导致语法错误。派生类指针必须先强制转换为基类的指针。

    ??点语法和->的区别??

    变量是对象的时候用“.”访问
    变量是对象指针的时候用“->”访问

    #inlclude <iostream>
    
    using namespace std;
    class A
    {
      public:
            int x;
            int y; 
    };
    int main()
    {    
            A a;
            a.x=100;       //对象用点访问
            // a->y=100;     //error
            A* pa = new A;
            pa->y=200;     //对象指针用箭头
            // pa.x=100;     //error<br>    delete pa;
            return 0;
    }
    

    第十章 虚函数和多态性

    • 虚函数的声明
    virtual void draw() const;
    
    • 如果在基类中将函数draw声明为virtual,然后用基类指针或引用指明派生类对象并使用该指针调用draw函数(shapePtr->draw()),则程序会动态的(即在运行时)选择该派生类的draw函数,这称为动态关联。

      如果用点语法(squareObject.draw()),则被调用函数是在编译时确定的(称为静态关联)。

    • 派生类调用基类函数

    HourlyWorker *hPtr = &h;
    hPtr -> Employee::print();
    

    C++封装、继承、多态扩展阅读
    C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别

    • 将基类的析构函数声明为虚析构函数。基类析构函数在派生类析构函数之后自动执行。

    • 如果一个类拥有虚函数,即使该类不需要虚析构函数也给它提供一个虚析构函数,这样能够使该类的派生类包含正确调用的析构函数。

    • 将构造函数声明为虚函数是语法错误。构造函数不能是虚函数。

    • 虚函数(impure virtual)
        C++的虚函数主要作用是“运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现
        子类可以重写父类的虚函数实现子类的特殊化。
        如下就是一个父类中的虚函数:

    class A{
        public: 
        virtual void out2(string s) {
         cout<<"A(out2):"<<s<<endl;
        }
    };
    
    • 纯虚函数(pure virtual)
        C++中包含纯虚函数的类,被称为是“抽象类”。抽象类不能使用new出对象,只有实现了这个纯虚函数的子类才能new出对象。
        C++中的纯虚函数更像是“只提供申明,没有实现”,是对子类的约束,是“接口继承”。
        C++中的纯虚函数也是一种“运行时多态”。
        如下面的类包含纯虚函数,就是“抽象类”:
    class A{
        public: 
         virtual void out1(string s)=0; 
         virtual void out2(string s) {
           cout<<"A(out2):"<<s<<endl;
         }
    };
    
    
    • “函数printShapeName和print是虚函数(在基类被定义为纯虚函数)的实现,如果不在类Point中重新定义这些函数,那么Point仍然为抽象类则不能实例化Point对象”。

    • c++编译有一个或几个虚函数的类时,对该类建立虚函数列表。列表让执行程序选择每次执行类的虚函数时正确的实现列表。

    第十一章 C++输入/输出流

    • c++式的I/O是类型安全的。

    • c++的I/O是以字节流的形式实现的,流实际上就是一个字节序列。

    • cin:把整数变量grade的值从cin输入到内存中

    cin >> grade;
    
    • cout

    • cerr: 到对象cerr的输出是非缓冲输出,也就是说会立即显示出来。

    • clog:到对象clog的输出是缓存输出。即每次插入clog可能使其输出保持在缓冲区,要等待缓冲区刷新时才输出。

    • cout << "C++\n"; 也可以用流操纵算子endl(行结束)实现转义序列\n(换行符)的功能,也可以用flush刷新输出缓冲区:

    cout << flush;
    
    • 需要输出指针变量的地址时可以使用void *类型。
    char *string = "test";
    cout << static_cast<void *>( string) << endl;
    输出结果:0x00416D50
    
    • put:用于输出一个字符。
    cout.put(' A ');
    cout.put(' A ').put(' \n ');
    
    • 流读取运算符通常会跳过输入流中的空格,tab键,换行符等等的空白字符,当遇到输入流中的文件结束符时,流读取运算符返回0(false),否则,流读取运算符返回对调用该运算符的对象的引用。当输入类型有错时,流读取运算符就会设置输入流的failbit状态位,如果操作失败则设置badbit状态位。

    • cin.get() 其返回结果是所输入的字符。当遇到文件结尾符,返回0(该版本)。

    • cin.eof() 是否在cin中遇到文件结尾符。

    • cin:不读入空格符,cin.get()要流入空格符。

    C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法

    • ignore 用于在需要时跳过流中指定数量的字符(默认为1),或在遇到指定的分隔符(默认分隔符是EOF)时结束。

    • putback 将最后一次用get从输入流中提取的字符放回到输入流中。

    • peek 返回输入流中的下一个字符,但并不将其从输入流中删除。

    • 调用成员函数read,write可实现无格式输入/输出。这两个函数分别把一定量的字节写入字符数组和从字符数组中输出。这些字节都是未经任何格式化的。
      成员函数read把指定个数的字符输入到字符数组中。
      成员函数gcount统计最后输入的字符个数。

    int main() {
      const int SIZE = 80;
      char buffer [SIZE];
    
      count << Enter a Senterce:\n";
      cin.read( buffer, 20);
      cout.writer( buffer, cin.gcount() );
      cout << endl;
       return 0 ;
    }
    
    • dec 整数被解释为十进制。

    • oct 整数被解释为八进制。

    • hex 整数被解释为十六进制。

    • setbase();

    • setprecision或percision控制小数点后面的位数。该精度对之后所有的输出操作都有效,直到下一次设置精度为止。

    • c++中,cout.width( )与setw( )有什么区别?

      这两个函数的作用是一样的。都是控制输出字符域宽度的,且不足用空格填充。
      在C++中,setw(int n)用来控制输出间隔。
      例如:
      cout<<'s'<<setw(8)<<'a'<<endl;
      则在屏幕显示
      s a
      //s与a之间有7个空格,setw()只对其后面紧跟的输出产生作用,如上例中,表示'a'共占8个位置,不足的用空格填充。若输入的内容超过setw()设置的长度,则按实际长度输出。
      setw()默认填充的内容为空格,可以setfill()配合使用设置其他字符填充

      在c++中 以下函数可互用:
      setw 或 width()
      setfill 或 fill()
      setprecision 或 precision()
      其中前面的set* 需要加头文件 #include<iomanip.h>

    • 用户自定义的流操纵蒜子

    ostream& bell ( ostream& output ){
      return output << ' \a';
    }
    
    • flag是作者定义的int…一般是标记的意思…做某种标记…一般只等于0或1…辅助循环退出的…

    • setf( ) setiosflags( ) 设置输出格式状态,括号中应给出格式状态,内容与控制符setiosflags括号中内容相同.

    • ios::showpoint 强制输出浮点数的小数点和尾数零。

    • ios::left,ios::right,ios::internal : left标志可以使输出域数据的右边,right标志可以使输出域右对齐并把填充字符放在输出数据的左边。填充的字符由成员函数fill或参数化的流操纵蒜子setfill指定。

    第十二章 模版

    • template< class T >

    • 模版提供了软件复用的好处。请记住,尽管模版只编写一次,但程序中仍然实例化多个模版函数和模版类的副本。这些副本会占用大量内存。(一个实现多个声明)

    C++类模板详解

    • 模版与友元

    第十三章 异常处理

    • 传统程序控制使用异常处理方法的另一危险是堆栈解退,异常发生之前分配的资源可能无法释放。这个问题可以通过认真编程而避免。

    iOS @try @catch异常机制

    未完待续...

    相关文章

      网友评论

        本文标题:C++ 学习笔记

        本文链接:https://www.haomeiwen.com/subject/fatbjttx.html