C++进阶总结

C++进阶

1.内存的表达

1.1 计算机怎么存放整数

int整数
运用二进制存存储
例子:7的存储方式:0111,1111(原码),1000(反码),1001(补码)。第一个0和1表示符号

1.2 计算机怎么存放小数

  • 定点数:小数点位置固定——>精度高
  • float浮点数:小数点位置不固定,是浮动的——>更灵活、精度低、运算速度慢
    运用IEEE 754标准存放:符号位(最高一位表示符号,0表示正数,1表示负数)+指数(8位)+尾数(23位)

1.3 什么是位运算

int 4B 32bit
short 2B 16bit
char 1B 8bit

  • &与运算
  • |或运算
  • ^异或
  • ~取反
  • <<左移
  • ‘>>右移’

1.4 大端字节序和小端字节序

字节序:大于一个字节类型的数据在内存中的存放顺序
例子:我们现在有一个整数是258。用16进制表示是0x0102,然后我们把这个整数拆分成两个字节,第一个字节为 0000 0001,第二个字节为 0000 0010。
如果在一个使用大端字节序的电脑上,这个整数会被这样存放:0000 0001 0000 0010
如果一个使用小端字节序的电脑上,这个整数的高字节就会存放在高地址上:0000 0010 0000 0001

大多数机器:小端字节序
I/O方面:大端字节序(网络字节序)
例子:要使用网络发送一个 int 类型的变量,要先把 int 转换成大端字节序,然后通过网络发送。

2. 指针探秘

2.1 指针的本质

本质:指向一个地址
地址——>内存:*
内存——>地址:&(取出变量的地址)
例子1:

//当p是一个指针时
#include<memory>
shared_ptr<int> p = make_shared<int>(42);//定义p为shared_ptr的智能指针
//p:表示这个指针变量指向的内存地址
//*p:表示这个指针指向的内存地址中存放的内容,就是42
//&p:表示p这个指针的地址

例子2:

//eg1:指针指向变量
int a = 2;
int * p = &a;//将a的地址取出来赋给指针变量p,指针p就指向了变量a
p = 1;
//eg2:指针指向数组
int arr[10];
int *p = arr;//指向数组第一个元素的位置
p = 12//对arr的第一个元素赋值为12
p+1 = 13//对arr的第二个元素赋值为13
        //*p+1的含义:p的地址+类型大小,
        //如p为int,则相当于原地址+4;如p为short,则相当于原地址+2
//*p++ 等价于 *p = *p + 1
//*p-- 同理
//p[1] 等价于 *(p+1)
//指针和结构体
struct S{
   
    int a = 10;
    float b = 20;
}
struct S s;
s.a = 12;  //操作的句柄是普通的就用"."
s.b = 22;
struct S *p = &s;
p->a = 12; //操作的句柄是指针就用"->"
p->b = 22;

2.2 指针指向函数

向函数中传入另外一个函数——>函数指针

//eg1:
int main(int argc, char** argv)
{
   
//声明函数指针
int (* funcP)(int a, int b) = func1;
//调用函数
int ret = (* funcP)(5, 4);
}
//eg2:给函数加入一个指针参数
//作用:可以让不同使用该函数的人,将其所要插入的函数代码插入到dowork这个函数中。
int dowork(int a, int b, int(*callback)())
{
   
    int c = a + b;
    int ret = (*callback)();
    ...
}

2.3 空指针和野指针

  • 野指针:无法确认指向的指针,或者指向一个无效地址的指针。——>十分危险
//容易引发野指针的情况:
int * p = (int *)malloc(2 * sizeof(int));
free(p);
free(p);
  • 空指针:指针表示不指向任何一个地方
int * p = (int *)malloc(2 * sizeof(int));
free(p);
p = nullptr;//将指针置为空,意味着其不指向任何一个地方,这样就不会有问题了
free(p);
//练习1:编写一个函数,用来交换两个 int 变量的值
void swap(int * a, int * b)
{
   
   int temp = *a;
   *a = *b;
   *b = temp;
}

2.4 函数返回指针

char * func()
{
   
    char * p = nullptr;
    return p;
}

什么情况下需要返回一个指针?返回指针时需要注意什么?

//错误代码,错误原因:arr是一个局部变量,func结束后就被销毁了,自然会出问题。
int * func()
{
   
    int arr[] = {
   1, 2, 3, 4};
    return arr;
}
//解决办法:把内存分配到堆内存上
int * func()
{
   
    int * arr = (int *)malloc(4 * sizeof(int));
    return arr;
}
int main(int argc,char **argv)
{
   
    int * p = func();
    free(p); //调用完后要记得手动销毁!!
    return 0;
}

2.5 解引用

返回内存地址中对应的对象

int a = 10;
int * p = &a;
cout<<*p<<endl;//输出a的值就是解引用操作

3. 类和对象

更加注重数据和动作的联系

  • 声明一个类必须加";",而函数不用

3.1 分文件编程

可以把一个类写到两个文件中:

  • .h或.hpp:头文件
  • .c或.cpp:实现文件
    如何Staff.h文件是定义,Staff.cpp是实现,想要在main函数中引用这个类就需要使用 #include “Staff.h” 将头文件引入进来。
#include "Staff.h"

int main(int argc,char **argv)
{
   
    // 我们就这样实例化了三个员工
    Staff st1;
    Staff st2;
    Staff st3;
    return 0;
    //将这三个'员工'分配到了栈上,可以把他们分配到堆内存上去。
}

3.2 new和delete

要将对象分配到堆上,需要使用两个关键字:new和delete。

  • new:分配对象,返回一个指针
  • delete:把这个指针指向的地址释放掉
#include "Staff.h"
int main(int argc,char **argv)
{
   
    // 我们就这样实例化了三个员工
    Staff * st1 = new Staff();
    Staff * st2 = new Staff();
    Staff * st3 = new Staff();
    // 记得释放
    delete st1;
    delete st2;
    delete st3;
    return 0;
}

3.3 权限修饰符

private
class A
{
   
private:
    int a;
    int b;
}
int main(int argc,char **argv)
{
   
    A a;
    a.a = 15; // 会报错!!,因为成员变量是 private 的
    return 0;
}
public
class A
{
   
public:
    int a;
    int b;
}
int main(int argc,char **argv)
{
   
    A a;
    a.a = 15; // 不会报错,因为成员变量是 public 的
    return 0;
}
protected

用来指定保护成员。一般是允许在子类中访问。(后续学习类的继承后你就明白了)

3.4 成员函数

//头文件Staff.hpp中:
#include <string>

class Staff
{
   
public:
    std::string name;
    int age;

    int PrintStaff();
};
//对应的.cpp文件中:
#include "Staff.hpp"

int Staff::PrintStaff()
{
   
    printf("Name: %s\n", name.c_str());
    printf("Age: %d\n", age);
    return 0;
}
//在main函数中调用:
#include <stdio.h>
#include "Staff.hpp"

int main(int argc,char **argv)
{
   
    Staff staff1;
    staff1.PrintStaff();

    return 0;
}

同样,因为上述函数写到了public下面,可以在外部对其进行调用,如果把他放到private下面,就不能被外部调用,只能被类中其他函数调用。

成员函数的重载
#include <string>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++中的容器有很多种,其中包括map和set。map是一种关联容器,它存储了一组键值对,每个键对应一个值。map中的键是唯一的,且按照某种顺序进行排序。set也是一种关联容器,它存储了一组唯一的值,并按照一定的顺序进行排序。map和set都可以通过迭代器进行遍历和访问。引用、和中的代码示例展示了如何使用map和set进行操作和排序。 在示例代码中,map的键是字符串类型,值是整数类型。可以使用insert函数向map中插入键值对,使用[]运算符访问和修改特定键对应的值。set中只存储了值,可以使用insert函数插入值,使用find函数查找特定的值。 需要注意的是,map和set中的元素是按照键的顺序进行排序的,因此在示例代码中使用了不同的排序方式。map默认是按照键的升序进行排序的,可以使用greater<int>作为模板参数,将其改为按值的降序进行排序。 总结起来,C++中的map和set是用来存储一组唯一的键值或值的容器,可以通过迭代器进行遍历和访问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++进阶之map与set](https://blog.csdn.net/qq_52433890/article/details/124850598)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

故事已经翻了几页

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值