c++ primer plus 知识点总结(更新中)

c++笔记

第三章 变量

  1. 变量名

    • 只能使用数字、字母和下划线
    • 数字不能开头
    • 尽量不以下划线开头
    • 不要使用关键字比如double
  2. 整型

    • 术语宽度表示存储整数时使用的内存量
    • 1byte=8bit
    • 1kb=1024byte
    • 1mb=1024kb
    • sizeof()返回类型或变量的长度,单位为字节。注意对类型名使用时,要将类型名加上括号 例如sizeof(int),对变量使用时可以不加括号 sizeof n-int
    • 整型溢出规则:
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yWpZVP1u-1681736558247)(./sec.pic/屏幕截图_20230220_200704.png)]
    • cin 和cout的行为都是由变量类型引导的.
    char ch=78;
    //char ch=N;
    //char ch='N';
    cout<<"hello "<

    输出结果

    hello N you are perfect!
    

    变量类型比较

    char ch;
    cin>>ch;
    
    int ch;
    cin>>ch;
    

    对于上述两段代码,都键入数字 5 ,第一段代码中ch的值为数字5对应的ASCII值53,而第二段则是整型数字5.

  3. 浮点数

    #include 
    int main(){
    using namespace std;
    float a=2.34e22f;
    float b=a+1.0f;
    cout << "a= "<< a < 
           
  4. 成员用逗号隔开;
  5. 分号结尾;
  6. 大括号为空时,各成员为0;
  7. 不允许缩窄转换;
  8. 可以赋值给另一个同一类型的结构,即便成员中含有数组;
  9. 结构可以作为参数传递给函数,也可以让函数返回一个结构。
  10. 结构数组:以结构为元素的数组即为结构数组

    1. 初始化结构数组:数组初始化和结构初始化结合。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RmwVOf8Z-1681736558249)(sec.pic/屏幕截图%202023-03-08%20204054.png)]
    2. guests是一个inflatable数组,guests[0]和guests[1]为数组成员,是一个结构,所以下面的成员运算符是有效的:guests[0].name
  11. 枚举

    1. enum提供了另一种创建符号常量的方式,可以代替const
      enum spectrum {red,orange,yellow,green,blue,violet,indigo,ultraviolet};该语句创建了名称为spectrum的枚举类型;
      类比于结构声明:enum—struct、 spectrum—inflatable
    2. 将red、orange等作为符号常量,这些常量称为枚举量。它们对应的整数值为0~7,在默认情况下,将整数值赋给枚举量时,从0开始依次加1
    3. 枚举可以使用赋值运算符:specturm band; band=blue;
    4. 枚举量是整型,可被提升为int整型,但int整型不可以转变为枚举类型。
      int color=blue;(valid) blue=3;(not valid); color=3+red;(valid)
    5. 如果int值是有效的,则可以进行强制类型转换赋给枚举变量。
      blue=spectrum(3);(valid),但是blue=spectrum(12052);(not valid)
    6. 如果只使用常量,而不创建枚举类型的变量,可以省略枚举类型的名称
      enum {red,orange,yellow,green,blue,violet,indigo,ultraviolet};
      枚举关键字enum、枚举类型名称如spectrum、枚举变量如spectrum band,band即为枚举变量、枚举量如red等
  12. 设置枚举量的值

    1. "="显式设置枚举量的值,指定的值必须是整数。
      enmu bits{one=1,two=2};
    2. 允许部分初始化,未被初始化的枚举量的值默认为0,后面没有被初始化的枚举量的值比前一个大1
      enum bigstep{first,second=100,thrid};
      first为1,thrid为101.
    3. 允许创建多个值相同的枚举量
      enum{zero,null=0,one,numebr_one=1};
  13. 枚举的取值范围
    每个枚举都有取值范围,通过强制类型转换,可以将枚举范围内的任何整数值赋给枚举变量
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RcHDspnd-1681736558249)(sec.pic/屏幕截图%202023-03-08%20215643.png)]

  14. 指针
    a. 指针是一个变量,存储的是值的地址。
    b. 指针名表示的是地址,将*(解除引用运算符)用于指针,可以得到该地址存储的值。

  15. 声明和初始化指针
    a.指针声明必须指定指针指向数据的类型:intp,指针p指向的值为int类型。int 为复合类型,是指向int的指针。
    b.对每个指针变量名,都需要一个运算符。intp1,p2;创建一个指针和一个int变量p2。int p1;intp2才可以创建两个指针。
    c.指针指向的值的长度可能不同(char,int等),但是地址的长度一般相同,2个或4个字节,取决于计算机。
    d.示例:int a=5;int
    p=&a;

  16. 指针的危险
    计算机将分配用来存储地址的内存,但不会分配用于存储指针指向的数据的内存。例如:longfellow; fellow =23330; 第一句代码为fellow创建了一个内存地址,但没有定义fellow的值;第二句代码将fellow指向了数据23330。也就是说我们知道fellow是23330的指针,其值应该是23330的地址,但由于fellow的值并未定义,且计算机不会为23330分配内存,所以23330的地址就是未知的,是随机的。
    要避免指针的危险,就要在使用 * 运算符前,将指针初始化为一个确定的、合适的地址。

  17. 指针和数字
    a.指针不是整型,虽然计算机通常把指针当作整数处理。
    b.不能将整数简单地赋给指针。例如:
    intpt;
    pt=0xB8000000; (type mismatch)
    pt=(int
    )0xB8000000; (强制类型转换后type match)

  18. 使用new分配内存
    a.为一个数据对象(可以是结构,可以是基本类型)获得并指定分配内存的通用格式如下:
    typeNamepointer_name = new typeName;
    int
    pn = new int; new运算符根据数据类型(此处为int)确定需要多少字节的内存,然后找到这样的内存并将地址返回给pn。
    b.常规声明变量分配的内存块存储在栈(stack)的内存区域,而new从堆(heap)或自由存储区(free store)的内存区域分配内存。

  19. 使用delete释放内存
    a.使用delete时,后面加上指针即可。
    int* ps = new int;
    delete ps;
    这将释放ps指向的内存,但不会删除ps指针本身。
    b.只能用delete释放new分配的内存,不可以释放常规声明变量的内存。

  20. 使用new创建动态数组

    • 静态联编(static binding):在编译时给数组分配内存。

    • 动态联编(dynamic binding):在运行且需要时给数组分配内存,而且可以在运行时选择数组的长度。

    • 通用格式:typeName*pointer_name = new typeName [num_elements];

      示例:int* ps = new int [10]; new返回第一个元素的地址并将其赋给ps。
      对于new创建的数组,应该使用delete[]释放内存。

      int* ps = new int [10]; delete [] ps;

      []表明delete释放了整个数组,而不仅仅是指针指向的第一个元素。

    • 使用new和delete的一些规则

      • 不能使用delete释放不是new分配的内存。
      • 不能使用delete释放同一个内存块两次或以上。
      • 如果使用new[ ]分配内存,则应使用delete[ ]来释放内存。
      • 如果使用new[ ]为一个实体分配内存,则应使用delete来(不带方括号)释放内存。
      • 对空指针使用delete是安全的。
  21. 使用动态数组

    • 指针和数组具有基本等价性。引用上述例子,ps[0]是动态数组的第一个元素,* ps也是第一个元素的值。ps[1]是第二个元素,
    • 指针是变量,因此可以修改它的值。在动态数组中,指针数加1代表指向下一个元素,与元素本身占几个字节无关即指针变量加1后,其增加的值等于指向类型占用的字节数。
  22. 指针、数组、指针算术

    • 多数情况下,数组名解释为第一个元素的地址。
      int wages[3]={1,2,3};
      如下等式是成立的:wage = &wage[0];
      但在计算数组长度时数组名不代表第一个元素的地址。
      sizeof(wage),返回整个数组的长度,12个字节长度。
  23. 指针与字符串

    • 如果给cout提供字符的地址,则它将从该字符开始打印,直到空字符结束。
    • 在cout和大多数情况中,char数组名、char指针以及加引号的字符串常量都被解释为字符串的第一个字符的地址。
    • 示例:
    #include
    #include//字符处理应当包含的头文件
    int main(){
        using namespace std;
        char animal[20]="bear";
        const char* bird = "wren";//字符串字面值是常量,const表面可以用bird来访问该字符串,但不可以修改
        char* ps;
        cout << animal << " and "<< bird << endl;
        cout << "Enter a kind of animal: " ;
        cin >> animal;
        ps =animal;//此处为指针赋值,只进行地址复制,而不会复制整个字符串到ps
        cout << ps<<"!\n";
        cout << "Before using strcpy():"<<endl;
        cout << animal << " is at "<< (int*)animal<<endl;//一般来说,给cout提供一个指针,它将会打印该地址;但是如果指针的类型是char,则cout将会打印字符串而不是地址。如果想要打印地址,需要强制类型转换。
        cout << ps << " is at "<< (int*)ps << endl;
        ps = new char[strlen(animal)+1];//分配准确的长度来保存animal的所有内容,注意这里最后加上一个字节存储空字符,使cout完成打印停止。
        strcpy(ps,animal);
        cout << "After using strcpy():" << endl;
        cout << animal << " is at "<< (int*)animal<<endl;
        cout << ps << " is at "<< (int*)ps << endl;
        delete [] ps;
        return 0;
    }
    
    • strcpy(a,b);a代表目标地址,b代表要复制字符串的地址
    • strncpy(a,b,c);c代表要复制的最大字节数,其余两个参数与上述一致。
  24. 使用new创建动态结构

    • 创建结构:inflatable* ps = new inflatable,inflatable为结构类型名称
    • 访问成员:
      • a.箭头运算符 -> 用于指向结构的指针,ps->price;代表ps指向的inflatable结构中的price成员;
      • b.ps->price;等价于(*ps).price;注意小括号的位置。
  25. 自动存储、静态存储和动态存储

    • 在函数内部定义的变量使用自动存储空间,称为自动变量
      • 特点:在所属的函数调用时自动产生,函数结束时自动消亡;
      • 存储在栈中,变量释放内存时遵循后进先出的原则。
    • 静态存储是变量在整个程序运行期间都存在的存储方式。
      • 声明方式:在函数外定义变量或者使用关键字static.
    • new和delete运算符被认为管理一个内存池,称为自由存储空间或者堆(heap)
      • 区别:在栈中,自动添加和删除机制使得占用的内存总是连续的,但动态存储可能导致占用的内存不连续,这使得跟踪新分配内存的地址更加困难。
  26. 内存泄漏

    • 如果使用new运算符在堆上创建变量后没有使用delete,即使包含指针的内存由于作用域规则和对象生命周期的原因被释放,但之前分配的变量还是存在,但我们却无法访问它,因为指向这些内存的指针已经无效,这就导致内存泄漏。被泄露的内存在程序的整个生命周期都不可使用,内存被分配出去却无法收回。极端情况是内存被耗尽,程序崩溃。
  27. 模板类vector

    • vector属于动态数组,本质上也是通过new,delete来完成操作的,但这个过程是自动完成的。因此其存储在堆中。
    • 使用一段代码来举例
    #include//包含头文件
    ...
    using namespace std;//vector包含在名称空间std中
    vectorvi;//创建一个int型空"数组"
    int n;
    cin>>n;
    vectorvd(n);//创建一个长度为n的double"数组"
    

    一般而言,声明vector的格式为:
    vectorvt(n_element);//n_element可以是整型常量或者整型变量。

  28. 模板类array

    • 与数组一样,array的长度是固定的,且存储在栈。
    #include
    ...
    using namespace std;
    arrayai;//创建包含5个int变量的array
    arrayad={1.2,2.0,2.3,2.4};//声明和初始化
    

    一般格式: arrayai;num为整型常量,不可以是变量。

  29. 三者的区别

    • 都可以使用索引法访问成员。
    • array和数组存储在栈中;而vector存储在堆中。
    • array可以直接复制给另一个array,而数组的复制需要逐个元素复制。
    • 数组的索引不检查边界错误。a1[-2]=20.2;这行代码代表将20.2存储到(a1-2)的地址对应的内存。

你可能感兴趣的:(c++,算法,vscode)