union
引用
union (共用声明和共用一变量定义)
前言union跟struct有相似的地方,但是union又叫做联合体或共用体,也就意味着它在内存存储上会和正常的有区别。
正文写法和结构体差不多:
1234union unionName{ type typename; type typename;};
注意:union之间的成员共享内存,也就意味着union的内存占用会根据最大的成员而定义。
No.1首先自定义一个联合体
1234union hh{ short sh; int in;};
先给实例一个hh,然后给小的变量赋值
sizeof能看到是四个字节,也就是印证他会根据联合体里面最大的变量类型扩充。
12345union hh{ short sh; int in; double dou;};
在联合体里再放一个double类型
发现结构体H的占用大小变成了8字节。
可以确定联合体的内存大小由最大成员定义
No.2那么说联合体共享内存空间,那么给short类型变量赋值之后,int和doubl ...
structPointer
前言结构体也不算陌生,特殊的是给结构体赋值的时候。
复现1234typedef struct Box{ int a; int b;}box,*PBox;
typedef是起到一个起别名的作用,例如我们声明typedef int in;,那么后面定义一个int变量的时候就可以in a = 0;。struct是声明结构体类型的关键字,在固有印象里结构体应该是这样的:
1234struct HHH{ int x; int y;};
定义一个HHH结构体时,我们可以用HHH h;或者struct HHH h;当我们在结构体后面放置额外的变量名时:
1234struct HHH{ int x; int y;}h1,h2[10],*h3;
这个时候后面的三个变量名就是表面我们再创建结构体HHH的时候同时声明了三个HHH类型的变量,一个正常的HHH h1,一个长度为10的结构体数组,以及一个指向这种结构体的指针。
然后回到我们刚开始说的:
1234typedef struct Box{ int a; ...
pointer安全
前言对指针已经有了大致了解,那么对于指针的安全性也需要有一定把握
正文12345678910int main(){ int *p; { int *a = new int[10]; p = a; p[0] = 250; } return 0;}
那么当指针p new的内存没有delete的时候,分配到的内存还会存在吗?可以通过输出p[0]的值看看发现仍然有值,这个时候这个指针p就被称为悬挂指针,也就是常说的野指针。
解决这种粗心的办法可以用智能指针
No.112345678910int main(){ int *p; { std::unique_ptr<int[]> a{ std::make_unique<int[]>(50) }; a[2] = 110; p = a.get(); } return 0;}
智能指针之前学 ...
string
引用
[] = “”属于c语言的方式
前言C语言是没有string类型的,那么要表示字符串就是通过char[]来实现。声明方式就是char ch[] = "hello";复古机器人点就是char ch[] = {'H','E','L','L','O','\0'};,当然鬼才用这个。指针也ok,不过需要强转,因为默认不认识字符串char *ch = (char*)"hello";但是要注意字符串末尾其实跟了一个\0作为结束,因为数组的本质是一块连续的内存空间,它需要区分。
有印象的应该知道,strlen和sizeof一个字符串的区别。
正文假设有一个数字char str[255] {"Hello张三"};,编码环境为gbk它的内存分析为:张在gbk中需要两个字节来表示,所以原本应该是0xc5d5,但是由于是char类型,排放顺序从低位到高位,所以说先存d5再存c5。
...
smartPointer1
引用c++ 11:
std::shared_ptr
前言shared顾名思义就是共享的意思,这个共享指针当然也属于智能指针这一块。
语法上:std::shared_ptr<type> tyename例如:std::shared_ptr<int> a{}std::shared_ptr<int> b{ std::make_shared<int>(0) }注意:std::make_shared不支持数组std::shared_ptr<int[]> c{ new int[5]{1,2,3,4,5} }
正文12345std::shared_ptr<int[]> sp{new int[5]{1,2,3,4,5}};std::shared_ptr<int> sp1{ std::make_shared<int>(5) };std::cout <&l ...
smartPointer
引用c++ 11:
std::unique_ptr
c++ 14:
std::make_unique
前言正常的指针如果是通过new或者malloc方式还需要额外的手动释放,delect或free。
智能指针的作用是防止忘记调用delete释放内存和程序异常的进入catch块忘记释放内存。另外指针的释放时机也是非常有考究的,多次释放同一个指针会造成程序崩溃,这些都可以通过智能指针来解决。
智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。智能指针的作用是管理一个指针,因为存在以下这种情况:申请的空间在函数结束时忘记释放,造成内存泄漏。使用智能指针可以很大程度上的避免这个问题,因为智能指针是一个类,当超出了类的实例对象的作用域时,会自动调用对象的析构函数,析构函数会自动释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间。
声明方式:std::unique_ptr<type> typename{},比如std: ...
pointer浅挖
前言指针和数组还有很多知识点需要学习
正文sizeof(数组)大部分情况下,我们使用sizeof(),编译器都是需要一个运行过程的。而我们反汇编sizeof求数组大小的时候会发现不一样的点:
能看到反汇编后
123456int main(){ int ch[5]; int size = sizeof(ch); return 0;}
头两句只有一句反汇编代码,首先也是因为数组没有初始化。其次就是他调用数组大小是20,编译器仿佛知道这个数组的大小了,14h也就是十六进制的写法,换算成十进制也就是20,数组有五个成员*4正好就是20。
也就是之前说的,数组的底层实现是由指针实现的,数组本身是抽象的结构逻辑所以编译器会提前预览出数组的大小,以便后续使用。
引用引用是一种阉割的指针版本。虽然取址引用变量得到的是原值的内存地址,但是引用的变量本身也占用内存。
123456789int a = 5;a = 6;int &b = a;int &c = a;int *d = &a;b = 6;c = 6;*d = 6;a = (int)&a ...
teamviewer设备上限
teamviewer设备上限
远程桌面软件只接触过向日癸和teamviewer两种,但后面实际上tv用的比较多。但商业是收费的,个人用限制设备。以前也是零零散散登录过几次,没太注意,这次换了电脑重新安装提示免费设备到限制了。
正文首先进入官网第一次在新设备上登录还要邮箱重新验证
登陆进去之后看到左上角
点击配置文件进入后,找到免费设备
值得注意的是剩余更次数默认只有两次
如果非特殊情况。在登陆到其他设备时可以选择仅使用一次而不是信任该设备,假设真的真的没次数的话,那就建议新建个账号了。如果没有这么多邮箱电话什么的
可以在编辑配置文件中右边看到删除账户
据说删除了之后还可以使用原来的邮箱重新注册,然后之前的设备限制又变成了两台。。还蛮有意思的。
结语结束
quote
前言引用看起来会很突兀,因为&符号引用的语法是:数据类型 &变量名称 = 引用对象名称
例如
12int a = 100;int &b = a;
12//引用之后,我们对b进行的操作,其实都是变相对a进行了操作b = 200; //那么a的值就会 = 200;
当然引用可以有多个,比如我再新建b1,b2,b3,都可以引用变量a
正文12345678910111213int main(){ int a = 100; int &b = a; int &b2 = a; int &b3 = a; b3++; std::cout << a << std::endl; std::cout << b << std::endl; std::cout << b2 << std::endl; std::cout << b3 << std::endl;}
再看看它们的地址: 发现地址一模一样,这样看上去引用好像有点拉跨。 ...
指针动态内存分配
前言在正常情况下,声明一个数组时type arrayName [arraySize]:
12int ch[10] = {0}; //就是将是个成员全部初始化为0int ch2[] = {1,2,3,4,5}; //没指定大小,但是有初始化,那么数组的大小就会根据初始化成员个数而定
还有一种情况就是arraySize是const类型或者#define,因为在规范里定义了,声明数组大小的时候必须是常量表达式:
12345678910111213#include<iostream>#define N 5int main(){ int ch[N] = { 0 }; //合法,N是常量 const int a = 5; int ch2[a] = { 0 }; //合法,a是常量 int b = 10; int ch3[b] = { 0 }; //不合法,b是一个变量 return 0;}
至于为什么不能是变量,放到最后再说。
正文malloc这就不得不 ...