美文网首页
c++学习笔记-第一部分 基础部分

c++学习笔记-第一部分 基础部分

作者: 大旺旺的弟弟小旺旺 | 来源:发表于2023-07-09 14:43 被阅读0次

    c++学习笔记,不一定每一个都写案例,主要是补充和留下印象吧。

    第一个c++程序

    //引入头文件
    #include <iostream>
    //入口
    int main()
    {
        //输出一句话
        /**
        1.std::cout 向控制台输出内容
        2.<<        输出运算符
        3.""        输出内容
        4.hello world 
        5.\n        回车
        6.;         结束
        */
        std::cout << "Hello World!\n";
    }
    

    C++输出数据

    std::cout << "Hello World!\n";
    

    使用变量

    int a;
    a = 10;
    

    注释

    1.//
    2./**/

    常量

    const int a = 10;
    

    数据分类

    (1)数字:0-9
    (2)字符:单引号括起来的 ''
    (3)字符串:双引号括起来的 ""

    输出数据步骤

    (1)Std::cout可以输出各种类型的数据
    (2)操作符拼接多个数据项
    (3)Std::endl换行使用
    (4)Using namespace std;缺省命名空间

    程序的注释

    (1) 程序添加说明文字,
    ①单行注释
    ②多行注释

    使用变量

    (1) 变量是存储内存变量的简称,用于存放临时数据的。
    (2) 属于之前需要先声明
    语法:数据类型 变量名
    (3)常用的数据类型有:int、float、double、char、string、bool
    (4)代码

    #include <iostream>
    
    int main()
    {
        char c = 'A';
        int num = 10;
        std::string name = "垃圾";
        bool sex = false; //ture为1  false为0
        std::cout << c << "  " << num << "   " << name << "  " << sex;
        std::cout << "Hello World!\n";
    }
    

    标识符命名

    C++输入数据

    (1)C++输出类型
    ①控制台节目输入
    ②文件中读取
    ③数据库中读取
    ④网络中读取
    ⑤输入方式
    (2) 输出案例

    Std::cin >>变量名
    

    (3)注意

    1. bool只能填入0和非0
    2. 输入数据和变量数据类型不匹配,导致结果不确定
    3. 代码
    string name;
    cin >> name;
    std::cout << "Hello World!\n"<<name;
    

    算术运算

    基本运算

    (1) 算术运算包含了:+ - * / %
    (2) 只适用于整数和浮点数
    (3) 取模只能使用于整数

    自增和自减运算

    (1) ++变量名、变量名++、--变量名、变量名--

    赋值运算

    1.+=
    2.-=

    c++11初始化赋值

    old

    int a = 100;
    int b(100);
    int c = (100);
    

    new

    
    ```c++
    int a = 100;
    int b{100};
    int c = {100};
    

    函数

    函数的位置

    (1) 在main上面定义,下来写内容
    (2) 在main的上面写内容
    (3) 函数可以多次声明,但是实现只有一个
    (4) 函数的声明也可以写main函数中,必须放在使用之前,否则会报错。

    函数参数的传递

    (1) 函数调用,调用这将参数传递给函数的参数
    ① 实参:可以是常量变量表达式
    ② 形参:函数调用的参数
    (2) 函数中修改形参的值不会影响实参。
    (3) 代码

    #include <iostream>
    int max(int a, int b);
    int min(int a, int b);
    int main()
    {
        int a = 10;
        int b = 11;
        std::cout << "max:" << max(a,b) << std::endl;
        std::cout << "Hello World!\n";
    }
    
    int max(int a, int b) {
        return a > b ? a : b;
    }
    
    int min(int a, int b) {
        return a < b ? a : b;
    }
    

    函数分文件编写

    (1) 使用头文件和源文件在编写代码
    (2) 在使用的时候通过#将头文件加进去
    (3) 可以写到头文件中的东西:头文件、命名空间、全局变量、函数声明,数据结构和类的声明等
    (4) 源文件:函数的定义、类的定义。

    Sizeof运算符

    (1) Sizeof(数据类型) 得到数据类型或者变量占用的内存空间
    (2) 32位和64为可能结果不一样
    (3) String不是基本数据类型,sizeof(string)没意义
    (4) 代码

    cout << sizeof(int) << endl;
    cout << sizeof(a) << endl;
    

    C++的基本数据类型

    (1) int float double char bool string(不是基本数据类型,但是比较重要)

    int类型

    整型的基本概念

    (1) C++使用int关键字声明变量,实际是integer的简写
    (2) 声明的时候可以在int关键字之前加signed、unsigned、short、long四种修饰符

    ① Signed:有符号的,可以表示正数和负数

    ② Unsigned:无符号的

    ③ Short:短的

    ④ Long:长的

    (3) C++中没有整数的取值范围,取值返回根据组合来计算得到

    整数的书写

    (1) 二进制:书写必须以0b(B)开头

    (2) 八进制:
    ① 必须以0开头
    ② 0-7
    (3) 十进制
    (4) 十六进制:
    ① 0x开头

    整数的坑

    (1) 书写十进制不要在前面加上0,会被认为是八进制

    longlong类型

    1. vs中long是4个字节
    2. liunx中long是8个字节
    3. long long 类型的整数,至少是8个字节,并且与long的长度一样长

    浮点型

    1. 浮点型包括float 、double、long double
    2. 字符数据类型;
      a) 内存占用一个字节,使用单引号
      b) 不存放字符本身,只存放编码
      c) 内存中存储都是二进制
    3. ASCII:33个控制字符 95个可显示字符
    4. 字符的本质
      a) 字符本质是整数,取值范围是0-127
      b) 书写的时候使用单引号,也可以使用整数
      c) 显示的时候可以是整数,也可以是整数
      d) 可以和整数进行运算

    原始字面量

    是不需要转义,直接使用他的直接含义

    #include <iostream>
    using namespace std;
    
    int main()
    {
        string path = "c:\\user";
    string path = R"(c:\user)";
    //前后必须一致  否则会报错
    string path1 = R"aaa(c:\user;)aaa";
        cout << "Hello World!\n";
    }
    

    字符串

    (1) C++风格:string var = “字符串”; 类
    (2) C风格:char[] ch = “字符串”; 字符数组

    数据类型的转换

    (1)计算机进行运算的时候,要求操作数类型相同的大小和存储方式
    (2)转换方式:
    i. 自动转换
    ii. 强制转换

    数据类型的别名

    1.别名的目的
    i.创建别名,方便书写和记忆
    ii. 创建与平台无关的数据类型,提高程序的兼容性
    2.兼容性的写法

    typedef long int lint;判断使用的机器
    

    3.别名可以原原本本的代替原名
    4.语法

    typedef 数据类型名  别名
    

    指针

    (1) C++通过&得到变量的其实地址
    (2) 语法

    i.  &变量名  取得数据的地址
    

    (3)指针用于存放变量的地址 (起始地址)
    (4)函数中使用

    void printInfo(int* a) {
        cout << *a << endl;
        *a = -1;
    }
    int main()
    {
        int a = 0;
        printInfo(&a);
        cout << a << endl;
    }
    

    (5)优点:可以提升性能,较少数据的copy

    (6)没有指定值的指针,值是乱七八糟的

    (7)指针存储的是地址,所有指针的变量名存储的是地址

    (8)*对指针进行解引用

    指针用于函数的参数

    (1)指针是指向的地址的,如果函数使用指针作为参数,那么使用地址传参

    (2)既然是指针,那么在使用的使用的时候,通过解引用得到值。

    (3)如果在函数中是通过解引用改变值,那么也会改变原来的值

    (4)好处

    • 函数中修改实参的值
    • 减少拷贝,提升性能

    值传递和地址传递

    使用常量

    常量是程序中固定不变的数据

    (1)const修饰
    (2)在程序的任何地方都可以的
    (3)使用它修饰指针

    常量指针

    (1)语法:const 数据类型 变量名
    i. 不可以使用解指针的方法设置值
    ii. 注意
    (2)指向的变量可以改变,值不可以改变(
    p =xx值不可以改变)
    (3)一般用于修饰函数的形参,表示不希望改变值
    (4)如果用于型参,虽然指向对象可以改变,但是没意义

    指针常量

    (1)语法:数据类型 *const 变量名
    (2)指向的变量对象不可以改变
    (3)注意
    i. 定义的时候必须初始化,否则没意义
    ii. 可以通过解引用方法修改地址中的值
    iii. 代码

    Int* const p = &a;
    *p = 13;初始化必须设置值   并且值可以修改
    

    常指针常量

    (1)语法:const int *const int

    (2)宏常量

    i. 一般在main函数之上声明的,使用大写字母

    ii. 语法:

    #define NAME C++;
    

    void关键字

    (1)C++中,void表示无类型

    (2)作用:
    i.函数返回值void
    ii.参数设置为void,表示不需要参数
    iii.void*作为函数参数,表示可以使用任意类型的参数

    (3)注意:

    i. 不能使用void声明变量,不可以代表一个真实的变量

    ii. 不能对void*指针直接解引用

    iii. 把其它类型的指针赋值给void*指针不需要转换

    iv. 把void*指针赋值给其他类型的需要转换

    内存空间

    内核空间 栈空间 堆空间 常量 代码

    堆和栈的区别

    (1)管理方式不同:栈是自己回收的,出作用域就会自己回收,堆需要自己释放

    (2)空间大小不同:堆是物理空间决定的,栈一般只有8M

    (3)分配方式不同

    (4)是否存在碎片

    动态分配内存new和delete

    (1)使用堆内存的步骤

    i. 声明指针

    ii. 使用new向系统申请一个内存,让指针指向这块内存

    iii. 通过解引用的方法,使用这一块内存

    (2)语法:new 数据类型(初始值)

    (3)申请成功分配一块地址,如果申请失败,就是一块空地址

    (4)释放delete 地址

    (5)注意

    i. 动态分配内存没有变量名,只能通过指针来操作内存中的数据

    ii. 如果动态分配内存不使用了,必须要释放

    iii. 动态分配的内存生命周期与程序相同

    iv. 指针作用域失效,指向的内存也不会释放

    v. 指针跟踪分配内存的时候,不可以跟丢。

    二级指针

    空指针

    (2)在c或者是c++中,都可以使用0或者NULL表示空指针,在没有赋值之前给它设置空,代表没有指向任何地址

    (3)使用空指针的后果

    i. 程序崩溃

    ii. 对空指针执行delete,系统会忽略该操作,不会出现异常,内存释放后,也应该设置为null。

    (4)为什么指向空指针会崩溃

    i. Null指针分配的分区,范围是0x0000-0x0000ffff这个区域是空闲的,没有任何物理存储与之对应,任何读写都会发生异常

    (5) C++11的nullptr

    i. 使用0或者NULL会产生歧义,所以建议使用(void*)0

    野指针

    (1)野指针就是一个没有指向一个有效合法的地址

    (2)如果访问野指针就会发生崩溃

    (3) 出现野指针的情况

    i. 指针定义的时候没有初始化,值是不确定的

    ii. 使用了动态分配的内存,内存释放了,指针不会置空,但是指向已经失效

    iii. 指针指向变量已经超过了作用域

    (4)规避方法

    i. 指针在定义的时候,如果无指向,就指向nullptr

    函数指针

    (1)函数的二进制代码存放在内存四区中代码段,函数的地址是它在内存中的起始地址,如果将函数地址作为参数传给函数,就可以灵活的调用其他函数

    (2)使用函数指针的步骤

    i. 声明函数指针

    ii. 让函数指针指向函数的地址

    iii. 通过函数指针调用函数

    (3)代码演示

    i.声明函数指针

    int max(int a,int b);
    int (*maxa)(int,int);  可以和上面一样,也可以直接这么写就完事了
    int max(int a,int b){
        return a > b ? a : b;
    }
    
    int a = 10;
    int b = 20;
    
    //使用函数指针名
    void (*pmax)(int,int);
    pmax = max; //函数名字就是函数的地址
    pmax(a,b)  //c++写法
    (*pmax(a,b));//c的写法
    max(a,b);
    

    (4)函数指针有什么作用

    我也解释不清楚,直接一个案例把

    void log(){
    }
    
    void printLog(void (*plog)()){
        logpre();
        log
        logend();
    }
    

    2.必须提供指针类型(返回值和函数列表)

    数组

    数组:一维数组 二维数组 多维数组

    创建数组

    (1)声明数组:数据类型 数组名[数字长度]

    • 数组的长度必须是整数 常熟 表达式
    int bh[3];
    string name[3];
    

    数组的赋值

    bh[0] = 1;
    

    占用空间

    sizeof(bh); 类型 * 长度

    sizeof只适用于基本数据类型,其他的没有意义

    初始化

    声明的时候初始化

    类型 nameArr[length] = {v1,v2,……};  指定值
    类型 nameArr[] = {v1,v2,……};  
    类型 nameArr[] = {0}
    

    数组清零

    memset函数将数组清零

    void *memset(void *s,int v,int size)
    
    memset(bh,0,sizeof(bh));
    

    数组复制

    memcpy()将数组中的全部元素复制到另一个相同的数组

    
    ## 引用
    
    ### 引用概念以及作用
    
    1.引用是c++新增的复合类型
    
    2.它是已定义变量的别名
    
    3.主要用途是函数的形参和返回值。
    
    4.语法
    ```c++
    数据类型 &引用名 = 原变量名
    

    5.引用取值

    int a = 3;
    int &ra = a;
    
    cout<<"a地址:" <<&a << "a的值:" << a <<endl;
    cout<<"ra地址:" <<&ra << "a的值:" << ra <<endl;
    

    数组和指针

    地址+1,一般加的是地址+数据类型大小,所以数组+1是下一个数据的值。

    输出地址的方法
    cout<< (long long)&a[0] <<endl;
    cout<< (long long)&a[1] <<endl;
    cout<< (long long)&a[2] <<endl;
    cout<< (long long)&a[3] <<endl;
    int *p = a;
    cout<< (long long)p <<endl;
    cout<< (long long)p+1 <<endl;
    cout<< (long long)p+2 <<endl;
    cout<< (long long)p+3 <<endl;
    

    数组的越界

    合法的数组下标

    一维数组用于函数参数

    数组下标取值解释为首地址+下标解引用取值

    地址加下标 p[1] 当前地址开始向后一个 p[2]当前地址向后两个

    数组操作:

    char a[20];
    int *p = int(*)a;  //char类型变为了int类型  操作不超过20,就不会存在问题
    
    

    数组用于函数

    传递的数组,在函数中是指针,使用sizeof得不到数组的长度

    new创建数组

    普通数组在栈上分配,更多的在堆上

    数组类型 *指针= new 数据类型[size];
    
    释放:
    delete[] 指针;
    

    遍历指针

    *(arr+i)遍历数组   指针解引用
    

    注意

    • 动态创建的,不可以使用sizeof运算符
    • 可以使用数组和指针的方法操作数组
    • 必须使用delete释放
    • 栈上分配空间,如果内存超出会异常
    • 大量数据需要在堆上分配

    new分配可以堆超出的,给出一个空地址

    int *a = new(nothrow)int[maxsize];
    
    if(a == nullptr){
    
    }else{
    
    }
    

    c风格字符串

    • c++字符串是string,可以自动扩展,不需要担心内存
    • string封装了c的字符串
    • c风格的更加方便/高效

    c风格的字符串

    如果char数组末尾包含了\0,那么就是一个字符串。所以使用c字符的时候,需要多留一个存放\0

    char name[20];
    cout<<name<<endl;  会显示遇到0结束(c/c++都是)
    

    清空字符串就是将所有的数据都设置为0

    方法一:
    char name[10] =  {0}; //清空
    方法二:
    memset(name,0,sizeof(name));
    方法三:
    将第一个设置为0
    

    字符串赋值或复制

    strcpy(name,"hello");
    strncpy(name,"hello",3);//指定个数小于字符长度没有问题 ,但是小于就会存在问题

    毕竟字符出结尾是\0,所以建议每次最好清零

    字符串拼接

    strcat(dst,src);

    结构体

    定义结构体就是告诉编译器,定义了一个新的数据类型,每个成员是什么类型

    结构体声明变量

    struct People{
        string name;
        int age;
    }
    
    //声明变量  c中必须struct c++中可以不写
    struct People p;
    
    访问成员
    p.name = "wk";
    p.name = 10;
    
    cout << "name :" << p.name;
    

    注意:

    • 结构体名是标识符
    • 结构体成员可以是任意类型的数据
    • 定义结构体可以放在代码的任何地方,一般放在main的上面或者头文件中
    • 结构体一般放在使用之前
    • 结构体成员可以使用c++的类,但是不提倡
    • 结构体中可以有函数,但是不提倡(c++)
    • 结构体可以给初始值(c++11)

    结构体的细节

    • 创建的时候可以设置值
    People p = {v1,v2,……};
    Poeple p1 = {0};
    
    • 创建结构体的时候,创建结构体变量
    struct People {
        char name[20] = "kw";
        int age = 100;
    } p;
    
    • 还可以初始化
    struct People {
        char name[20] = "kw";
        int age = 100;
    } p = {"cs",100};
    

    1.占用内存的情况

    使用ziseof可以计算结构体的大小。但是结构体占用内存不一定等于全部成员占用的内存大小,因为需要内存对齐

    内存对齐,

    2.清空结构体

    创建结构体没有初始化,成员变量中存在垃圾值,使用memset清楚数据中的值,只使用于c++中的数据类型

    memset(&strp,0,sizeof(strp))
    

    3.结构体的复制

    • memcpy()将结构体中的成员复制到另一个相同类型的结构体中
    • 也可以使用==

    结构体指针

    结构体是一种自定义的数据类型,使用结构体可以创建变量

    (1)基本语法

    struct People p; //声明结构体变量
    struct People *pst = &p; // 结构体指针
    

    (2)访问成员

    指针名里面是地址,解引用是结构体,结构体.
    (*指针名).成员名
    
    指针名-> 成员变量
    
    

    (3)用处:
    作为函数参数, 用于动态分配内存

    枚举

    enum 枚举名{v1,v2}
    
    enum colors {
        red,vv,ss
    };
    //值为012
    colors f = red; //对
    colors xx = 0; //x
    
    值虽然是0123,但是不可以直接设置
    

    (2)注意事项和细节

    • 枚举创建变量只能在枚举范围内
    • 枚举和变量作用域一样
    • 可以显示枚举的值
    • 给枚举指定值
    • 整数强制转换为枚举 枚举类型(整数)

    引用

    引用是c++新增的符合类型,是已经定义变量的别名,主要用途是函数形参以及返回值

    1.声明语法:

    数据类型 &引用名 = 原变量名 
    int a = 0;
    int &ra = a;
    

    2.注意事项

    • 引用的数据类型与变量名一致 int int
    • 引用名和原变量名可以互换
    cout<< "a的地址"<< &a << "a的值:"<< a << endl;
    cout<< "ra的地址"<< &ra << "ra的值:"<< ra << endl;
    
    两个输出都是相同的
    
    ra = 9;
    他们的值都发生了改变
    
    • 必须在声明的时候初始化
    引用初始化后值是不变的
    int a = 10;
    int ra = &10;
    
    int b = 3;
    ra = b; // a = 3
    
    
    • c/c++使用&符号来指示/取变量的地址

    引用的本质

    指针常量的伪装

    int a = 3;
    int &b = a;
    int * const rb  = &a;
    

    引用用于函数参数

    将函数形参声明为引用,调用的时候,形参为实参的别名,这个叫引用传递,引用的本质是指针,传递的是地址,形参会影响到实参

    优点:

    • 传引用代码简洁
    • 不需要传递二级指针
    • 引用的属性和特别之处

    指针:用于函数参数和动态分配内存

    传值案例

    //值传递 f(1,2)
    int f (int a ,int b){
        a = 10;
        b = 0;
        return a;
    }
    //指针传递 f(&a,&b)
    int f (int* a ,int* b){
        *a = 10;
        *b = 0;
        return a;
    }
    //引用传递 f(a,b)
    int f(int &no,int &ss){
        a ,b
    }
    

    引用用于返回值

    函数返回值引用语法

    int *fun(){
    
    }
    
    调用
    int &d = fun();
    

    注意:

    • 如果返回值是局部的,那就是野指针
    • 可以返回
      • 引用参数
      • 类的成员
      • 全局变量
      • 静态变量

    注意事项

    1.引用数据类型与原来的数据类型相同

    2.引用与原变量名可以互换,值与内存单元相同

    3.必须在声明之前初始化,初始化后不可变

    引用的本质

    他是指针常量的伪装

    相关文章

      网友评论

          本文标题:c++学习笔记-第一部分 基础部分

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