Linux/C++系统编程 day3

C++应用方向

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-We35Q0DJ-1610347051024)(\image-20210104100841690.png)]

  • C++头文件都是模板编写,没有.h,而模板有一个特点必须知道所有实现之后才能进行正常编译

    (cd /usr/include/c++)

  • 函数声明和定义

    (形式上区别,花括号和末尾分号

    声明可以有多次,定义只能有一次)

  • <<输出流运算符,左移乘2 endl换行

  • >>输入流运算符,右移除2

  • 同窗口无法编译运行

  • vimplus中可使用gcc注释一行,u还原或者再按一次

  • 运算符重载,视作函数

命名空间

为什么要使用命名空间?

  • 解决函数命名冲突
    (命名冲突是指同一个作用域内有多个同名实体)

命名空间是什么?

  • namespace 名字{ }
    (末尾不用加分号,其中可以定义变量、常量、函数、结构体、类、模板、命名空间,统称为实体)

如何使用命名空间?

用法1 :using编译指令

  • using namespace std;

    (可以一次将std命名空间中实体全部引出,可能导致自己定义的实体和std中实体冲突)

用法2 :作用域限定符

  • wd::

    (每次使用实体时加上,即使自定义的实体与std命名空间中的实体冲突也没问题,但使用起来麻烦)

  • ::

    (匿名命名空间,如只有一个printf不需要加作用域限定符也可以正确使用)

用法3 :using声明机制

  • using std::cout

    (一次只将命名空间中的一个实体引出,自然写代码时就不会定义同名函数)

两个命名空间内互相调用

  • type wd::func()

    (带命名空间的函数声明,结构体不能这样使用)

  • 命名空间可以扩展,先写一部分,中间被隔开,后写一部分

    (包括标准命名空间,一般std里是小写,但不建议)

命名空间的嵌套

  • wd::wh::

    (在一个命名空间中再定义另一个命名空间,调用内部实体时要写全作用域)

const常量

  • 可以创建常量,定义时必须初始化,不能进行二次赋值

用法1:修饰变量

  • #define MAX 10

    (宏定义,发生的时机在预处理阶段,做字符串替换,不做任何类型检查,若产生bug直到运行时才出现)

  • const

    (发生的时机在编译阶段,会执行类型检查,若产生bug会立即报告)

    • const int number=10;

    • int const number=10;

      (以上两种都可)

用法2:修饰指针

  • 关于指针,我们只关注其本身和所指的内容

  • 修饰谁谁就不能变,双重const则都不能变

  • 优先级:()>[]>*

常量指针

  • const int * number=10;

  • int const * number=10;

    (当const位于*左边的时候,不能改变指针所指的值,但是可以改变指针本身指向)

指针常量

  • int * const number=10;

    (当const位于*右边的时候,不能改变指针本身指向,但是可以改变指针所指的值)

函数指针与指针函数

  • int (*pf)(int x)

    (指向返回类型是int,参数是int的函数)

  • int* pf (int x)

    (函数的返回类型是指针,参数是int)

数组指针与指针数组

  • int (*parray)[]

    (指向含有[]多个元素的一维数组,二维数组时也叫行指针)

  • int* parray[]

    (数组里面都是指针,可以用来存放变量地址,需要分别赋值)

用法3:对成员函数的修饰

  • 见类

用法4:对对象的修饰

  • 见类

开辟和回收堆空间

C中空间的使用malloc/free表达式

步骤1:申请堆空间

  • int *pInt = (int *)malloc(sizeof(int));

    (严格来说应该判断是否申请成功,即是否空指针)

步骤2:清零(初始化)

  • memset(pInt,0,sizeof(int));

    (sizeof是运算符)

步骤3:赋值使用

  • *pInt=10;

步骤4:回收(释放)堆空间

  • free(pInt);

    (打印地址时printf中用%p)

C++中空间的使用new/delete表达式

步骤1:申请堆空间并初始化,赋值

  • int *pInt = new int(10);

  • int *parray = new int[10]();

    (对于数组此处不可以赋值)

步骤2:回收堆空间

  • delete pInt;

  • delete [] parray;

    (中括号中间不能填数字,以免被视为偏移,在开辟空间时已经默认多开了4个字节来存数组长度、标志位之类的信息)

  • size_t 类型表示C 中任何对象所能达到的最大长度。它是无符号整数

两者的区别与联系

  • malloc/free是C中的库函数,而new/delete是C++的关键字

  • malloc只能申请原始的堆空间,new申请堆空间并进行( )初始化

  • 都是用来申请堆空间

  • 都要成对使用,否则会造成内存泄漏

    • 内存泄漏:分配了内存而没有释放,逐渐耗尽内存资源,导致系统崩溃

    • 内存越界:向系统申请一块内存,使用的时候超出了申请的范围

    • 内存踩踏:也叫内存重叠,一般是在拷贝过程中目的地址范围和源地址范围有重叠导致的。

    • 内存溢出:想要分配的内存超出了系统能够提供的

    • 野指针:指向被释放的或者访问受限内存的指针

&引用

  • int number=10;

    int &ref=number;

    (已定义变量的别名,引用的提出就是为了减少指针的使用)

实质

  • int *cosnt

    (指针常量)

  • 引用定义时必须初始化,一经绑定就不能改变指向

  • 操作引用与操作变量本身是一样的

  • &跟了类型的是引用,否则是取地址

  • const int &a=10;

    (当既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变时,就应该使用常引用)

用法1:作为函数参数

  • 引用传递和指针传递不同于值传递,它们不需要进行复制,而值传递的形参只是实参的一个副本

  • 引用传递相比于其他两个不会额外占用栈空间,

用法2:作为函数返回类型

  • 可以对函数返回值赋值

  • 函数返回引用的前提是实体的生命周期大于函数的生命周期

  • 不要返回局部变量的引用,其生命周期在函数调用完时已结束

  • 返回堆空间的引用,可能有内存泄漏的隐患(new/delete未成对出现),除非有内存回收的机制

    • 可使用引用绑定函数int &ref=func();

    • 之后再delete &ref;

      (语义无错,但是不推荐这种写法)

指针和引用的区别与联系

相同点:

  • 都是地址的概念;
    (指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名)

区别:

  • 指针是一个实体,而引用仅是个别名;

  • 引用使用时无需解引用(*),指针需要解引用;

  • 引用只能在定义时被初始化一次,之后不可变;指针可变;

  • 引用没有 const,指针有 const;

  • 引用不能为空,指针可以为空;

  • “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;

  • 指针和引用的自增(++)运算意义不一样;

  • 从内存分配上看:程序为指针变量分配内存区域,而引用不需要分配内存区域。

强制转换

  • (tye) a;

    上面是C的写法,C操作简单,但C++更加安全

用法1:static_cast<type>(a)

  • 适用范围:

    • 基本数据类型之间

    • void指针转换为目标类型指针,但不安全

    • 任何类型转换为void

    • 用于基类和子类之间指针或引用的转换

      (进行上行转换(把子类的指针或引用转换成
      基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类
      型检查,所以是不安全的。)

  • grep -rEn “*_cast” ./

    (可以查看是否使用强制转换)

int inumber=10;
float fnumber=12.34;
inumber=(int)fnumber;//C
inumber=int(fnumber);//C++
inumber=static_cast<int> (fnumber);//C++

void *pre1=malloc(sizeof(int));
int *pre2=static_cast<int*>(pre1);//C++
delete pre2;
pre2=NULL;//指针置空

用法2:const_cast<type>()

  • 去掉常量属性,将常量指针转化为非常量指针
const int num=100;
int *p2=const_cast<int*>(&num);
*p2=200;//C++未定义的行为

用法3:dynamic_cast<type>()

  • 用于基类和派生类之间的转换,尤其是下行

用法4:reinterpret_cast<type>()

  • 用于处理无关类型之间的转换,容易导致程序不安全
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一门linuxc++通讯架构实战课程,针对c/c++语言已经掌握的很熟并希望进一步深造以将来用c++linux下从事网络通讯领域/网络服务器的开发和架构工作。这门课程学习难度颇高但也有着极其优渥的薪水(最少30K月薪,最高可达60-80K月薪),这门课程,会先从nginx源码的分析和讲解开始,逐步开始书写属于自己的高性能服务器框架代码,完善个人代码库,这些,将会是您日后能取得高薪的重要筹码。本课程原计划带着大家逐行写代码,但因为代码实在过于复杂和精细,带着写代码可能会造成每节课至少要4~5小时的超长时间,所以老师会在课前先写好代码,主要的时间花费在逐行讲解这些代码上,这一点望同学们周知。如果你觉得非要老师领着写代码才行的话,老师会觉得你当前可能学习本门课程会比较吃力,请不要购买本课程,以免听不懂课程并给老师差评,差评也会非常影响老师课程的销售并造成其他同学的误解。 这门课程要求您具备下面的技能:(1)对c/c++语言掌握的非常熟练,语言本身已经不是继续学习的障碍,并不要求您一定熟悉网络或者linux;(2)对网络通讯架构领域有兴趣、勇于挑战这个高难度的开发领域并期望用大量的付出换取高薪;在这门课程中,实现了一个完整的项目,其中包括通讯框架和业务逻辑框架,浓缩总结起来包括如下几点:(1)项目本身是一个极完整的多线程高并发的服务器程序;(2)按照包头包体格式正确的接收客户端发送过来的数据包, 完美解决收包时的数据粘包问题;(3)根据收到的包的不同来执行不同的业务处理逻辑;(4)把业务处理产生的结果数据包正确返回给客户端;本项目用到的主要开发技术和特色包括:(1)epoll高并发通讯技术,用到的触发模式是epoll中的水平触发模式【LT】;(2)自己写了一套线程池来处理业务逻辑,调用适当的业务逻辑处理函数处理业务并返回给客户端处理结果;(3)线程之间的同步技术包括互斥量,信号量等等;(4)连接池中连接的延迟回收技术,这是整个项目中的精华技术,极大程度上消除诸多导致服务器程序工作不稳定的因素;(5)专门处理数据发送的一整套数据发送逻辑以及对应的发送线程;(6)其他次要技术,包括信号、日志打印、fork()子进程、守护进程等等;
《精通MATLAB与C/C++混合编程第3版》是一本专门介绍如何在MATLAB和C/C++之间进行混合编程的书籍。混合编程是指在MATLAB中调用C/C++代码,以提高程序的效率和性能。 这本书主要包含了以下内容:首先介绍了MATLAB和C/C++的基本知识,如MATLAB脚本语言和C/C++的语法、函数和变量的使用等。然后详细介绍了如何在MATLAB中调用C/C++代码,包括如何编写MEX文件(MATLAB可执行文件),以及如何在MATLAB环境中编译和运行这些文件。此外,还介绍了如何在MATLAB中使用C/C++的库函数和数据结构。 书中还讲解了一些高级的主题,如如何优化MATLAB和C/C++代码的性能、如何处理复杂的数据类型和多线程编程等。此外,还提供了一些实际案例和例子,帮助读者更好地理解和掌握混合编程的技巧和方法。 这本书的优点在于结合了MATLAB和C/C++的实际应用,介绍了大量的实际案例和技巧,对于想要学习如何在MATLAB和C/C++之间进行混合编程的人来说非常有用。无论是初学者还是有一定编程经验的人,都可以通过这本书提高自己的编程水平,提升自己的工作效率。 综上所述,《精通MATLAB与C/C++混合编程第3版》是一本非常实用的书籍,对于想要深入学习和应用MATLAB和C/C++混合编程的人来说是必备的参考资料。它不仅能够帮助读者了解MATLAB和C/C++之间的关系,还可以提升他们的编程水平和解决实际问题的能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值