C++ Primer Plus 第6版 学习笔记-chapter4

数组

  1. char ch[] ch必须定义时负值、不能做左值

  2. C++11 char ch[] {} ; char ch[] = {};

  3. strcpy(charr1,charr2); strcat(charr1,charr2); (头文件cstring string.h) 拓展:strncat strncpy 可以指出长度

  4. cin.getline(charr1,num);是类方法

  5. 确定长度 strlen(ch1)

string

  1. C++11初始化 string ch[] {} ; string ch[] = {};

  2. str += str; str = str1 + str2;

  3. getline(cin,str);不是类方法 istream类中只有处理double、int等的方法,没有处理string的方法 cin >> str 是利用友元函数处理的

  4. 确定长度 strlen(ch1) str.size()

其他形式的字符串字面值

wchar_t title[] = L"chief Astrogator";
char16_t name[] = u"Felonia Ripova";
char32_t car[] = U"Humber Super Snipe";

C++11 还支持Unicode字符编码方案UTF-8 根据编码的数字值,字符可能存储1-4个八位组,用前缀u8表示。

raw (C++11新增)原始字符串 :表示的字符串就是自己

cout << R"(Jim "King" Tutt uses "\n" instead of endl.)" << '\n';

其中输入原始字符串时,按回车不仅会移到下一行,该将在原始字符串中添加回车字符。

输出Jim "King" Tutt uses "\n" instead of endl.

为了使得能输出)

R"...(...(...)...)..." 输出...(...)... ...自定义定界符不能用空格、左右括号、斜杆和控制字符(如制表符和换行符)

get() getline():读取一整行

cin.getline(char *,int a) 最多读取a-1字符 读取并丢弃换行符

cin.get(char *,int a)最多读取a-1字符 读取换行符并将它留在输入队列 (调用get()来处理,例如cin.get(name,20).get()) get可以用来检错。

混合输入字符串和数字的问题:cin读取年份,将回车键生成的换行符留在队列中导致cin.getline()以为是空行。

int year;
cout << "shuru year:";
cin >> year;
cout << "shuru address";
char address[80];
cin.getline(address,80);

struct

  1. 声明与创建

    struct name
    {
        ...
    };
    ​
    struct name
    {
        ...
    }n1,n2;
    ​
    struct name
    {
        ...
    }n1=
    {
        ,
        ,
    };
    ​
    struct 
    {
        ...
    }n1;
  2. 相对于c,可以省略struct struct xxx a; xxx a;

  3. 初始化 xxx a = {,,};xxx a {,,};xxx a {}(成员都为0,不允许缩窄转换)

  4. name n1 ,n2. 允许n2=n1;

  5. 结构数组

    inflatable gifts[2] = 
        {
            {,,},
            {,,}
        };
  6. 结构中的位字段 :num 指定了位数 例如:unsigned int SN :4; 还可以使用没有名称的字段提供间距,例如:unsigned int :4;

union

  1. 共用体能够存储不同的数据类型,但只能同时存储其中的一种类型

  2. 共用体的长度为其最大成员的长度。

  3. 共用体一般用来解决某个数据项有两种或多种格式。例如一些商品的ID为整数,一些为字符串。

  4. 共用体可以用来节省内存,一般会用于嵌入式编程。

    struct widget
    {
        char brand[20];
        int type;
        union id
        {
            long id_num;
            char id_char[20];
        }id_val;
    };
    int main()
    {
        widget prize;
        prize.type = 1;
        if (prize.type == 1)
            cin >> prize.id_val.id_num;
        else
            cin >> prize.id_val.id_char;
        return 0;
    }
    ​
    struct widget
    {
        char brand[20];
        int type;
        union 
        {
            long id_num;
            char id_char[20];
        };
    };
    int main()
    {
        widget prize;
        prize.type = 1;
        if (prize.type == 1)
            cin >> prize.id_num;
        else
            cin >> prize.id_char;
        return 0;
    }

enum

  1. 提供创建符号常量的方式,定义新类型。

    enum spectrum {red,orange,yellow,green,blue,violet,indigo,ultraviolet } //范围是0~7,如果只使用常量,而不创建枚举类型可省略                                                                                 spectrum
    spectrum band;   

  2. 只有赋值运算,没有算术运算。band = blue //valid band ++ ; band = red + orange; //invalid

  3. 枚举量是整型,可以提升到int,但int不能自动转换到枚举类型。 可以通过强制转换,例如:

    int a = 3+red  //invaid
    band = spectrum(3);  //invaid
  4. 可以使用赋值运算符来显示地设置枚举量的值,第一位默认为0,后面未初始化的值比前面的大1

    enum bits{first,second = 100, third}

    也可以创建多个相同的枚举值

    enum {zero, null = 0,one,numero_uno = 1};
  5. 枚举的取值范围

    最小值不小于0时 0~大于最大值的最小的2的幂-1

    最小值小于0是 -(大于最小值的最小的2的幂-1)~大于最大值的最小的2的幂-1

    因此即便不是枚举值,位于枚举范围内也合法,例如:

    bits myflag= bits(6);

指针

  1. C++创建指针时,会分配用来存储地址的内存,而不会分配用来存储指针指向的数据的内存。因此一定要在对指针应用解除应用运算符(*)之前,将指针初始化为一个确定的、适当的地址。

    int* p;
    *p = 23333; //invalid
    int a;
    *p = &a;
    *p = 23333;
  2. 指针和整型是不同的类型

    int *pt
    pt = 0xB8000000 //invalid type mismatch
    pt = (int*)0xB8000000 //valid
     

自由存储空间 new delete

  1. new将找到一个长度正确的内存块,返回内存块的地址。typeName* pointer_name = new typeName;

  2. new分配的内存块通常与常规变量声明分配的内存块不同。变量和指针变量都是存储在称为栈(stack)的内存区域,而new从称为堆(heap)或自由存储区(free store)的内存区域。

  3. 内存耗尽 new返回空指针

  4. delete会释放指针指向的内存,而不会删除指针本身。可以使用重新指向一个新分配的内存块。

  5. new和delete一定要配对使用,否则会发生内存泄漏。

    int* ps = new int;
    delete ps; //valid
    delete ps; //not OK now 
    int jugs = 5;
    ps = &jugs;
    delete ps; //invalid ,memory not allocated by new
    ​
    int* ps = new int;
    int *pq =ps;
    delete pq; //valid
  6. 动态联编:在运行阶段创建

    静态联编:在编译阶段分配内存

  7. 动态数组

    int * psome = new int [10];
    delete [] psome;
  1. 规则:

    不要使用delete来释放不是new分配的内存

    不要使用delete释放同一个内存两次

    对空指针应用delete是安全的

    使用new [] 应使用delete []

    使用new ,应使用 delete;

  1. new返回的指针指向数组的第一个元素,不能使用sizeof运算符来确定动态分配的数组的字节数。当系统是知道分配的内存量的,以便delete[]

  2. 指针可当做数组名来使用,运行指针加1,但不允许数组名加1(因为数组名是常量)。例如 :

    int * psome = new int [10];
    psome[0] = 1;
    psome += 1;
    psome -= 1;
    delete [] psome; //要使指针指向原处
    ​
    int arr[10];
    arr +=1;//invalid

指针、数组和指针算术

  1. 数组名是第一个元素地址,是常量

    int arr[10];
    int* p,q;
    p = arr;
    q = &arr[0];
  2. arrayname[i] -> *(arrayname + 1) pointername[i] -> *(pointername + 1)

  3. 指针可加1,每加1,移动类型字节数,但不允许数组名加1

  4. sizeof pointername 得到指针类型长度 sizeof arrayname 得到数组长度(这是c++不会把数组名解释为地址)

  5. &arrayname 是数组大小内存块的地址 P109

    &arrayname + 1 代表移动数组大小的字节

    short (*pointername)[20] = &arrayname; pointername 类型为 short (星号)[20]

    因此 *pointername 与 arrayname等价

指针与字符串

  1. char数组名、char指针和“ ”内的字符串常量都被解释为字符串第一个字符的地址

  2. 一般来说,如果给cout提供一个指针,它将打印地址,但如果是char * 指针,将显示指向的字符串,可能通过(int *)来显示字符串的地址

  3. strncpy

    char food[20];
    strncpy(food,"as sdalkw sdkla; sdakl2na",19);
    food[19] = '\0';

指针与结构体

  1. 如果标识符为结构体名,使用句号运算符(.);如果标识符是指针,使用->;

    struct inflatable
    {
      char name[20];
      float volume;
      double price;
    };
    ​
    int main
    {
        inflatable *ps = new inflatable;
        cin.get(ps->name, 20).get();
        cout << "next";
        inflatable inf1;
        cin.get(inf1.name, 20);
        return 0; 
    }
  1. 指针指向结构体要用取地址符&。

内存存储--自动存储、静态存储、动态存储、线程存储(C++11)

  1. 自动存储,一般存储在栈中,后进先出。一般为局部变量,函数调用使自动产生,函数结束时消灭。

  2. 静态存储(两种) 全局变量和变量前使用关键字static。存活于整个生命周期,也可能只在特定函数被执行存在。

  3. new delete;它们管理一个内存池(被称为自由存储空间和堆)。不完全没受程序或函数的生存空间控制。

类型组合

#include 
#include 
using namespace std;
struct years_end
{
    int year;
};
int main()
{
    years_end s1, s2, s3;
    s1.year = 2018;
    years_end *p = &s2;
    p->year = 2019;
    years_end arr[3];
    arr[0].year = 2020;
    (arr + 1)->year = 2021;
    const years_end *ps[3]{&s1,&s2,&s3};
    //ps[2]->year = 2022;
    cout << ps[0]->year << (*(ps+1))->year;
    auto ass = ps;
    cout << (*ass)->year <<(*(ass+1))->year;
    const years_end **pa = ps;
    cout << (*pa)->year << (*(pa + 1))->year;
    return 0;
}

vector array

  1. (C++98)vector vt(n_elem); n_elem可以是整型常量,也可以是整型变量。 长度不固定,动态的。

  2. (C++11)array arr; n_elem不能是变量。长度固定,静态的。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值