Cqueue
手写C版本的queue记录一个小demo,留着以后批判。实现了除了运算符重载以外的所有功能(大概),测试时没发现问题。queue使用的是const static queuefuntion queue **类似于C++的namespace**中的通用接口。
用到的宏1#define TYPE int//勉强范型吧
data定义12345678typedef struct queuedata{ TYPE data; unsigned int size; struct queuedata* next; struct queuedata* prev; struct queuedata* head; struct queuedata* tail;}queuedata;
funtion定义12345678910typedef struct queuefuntion{ queuedata* (*initqueue)(TYPE); TYPE (*front)(queuedata*); TYPE (*back)(qu ...
Cstack
手写C版本的stack记录一个小demo,留着以后批判。实现了除了运算符重载以外的所有功能(大概),deque扩容有问题,push和pop设计导致的,可以通过修改宏SIZE的大小来避免扩容,其他的都没什么问题。stack使用的是extern const struct stackFuntion stack; **类似于C++的namespace**中的通用接口。
用到的宏123#define TYPE int#define SIZE 51200//修改大小避免扩容#define INT_MIN -2147483648
data定义123456789typedef struct deque{ struct deque *prev; struct deque *next; unsigned int nowdeque;//当前所处的deque位置 unsigned int top; unsigned int size; unsigned int empty; TYPE data[0];}deque;
funtion定义12345 ...
Cvector
手写C版本的vector记录一个小demo,留着以后批判。实现了除了运算符重载以外的所有功能(大概),quicksort有问题,前期设计导致的,不能从0,1开始…贼麻烦,不建议用。其他的都没什么问题。vector使用的是const static VectorFuntion vector **类似于C++的namespace**中的通用接口。
用到的宏12#define INT_MIN -2147483648#define TYPE int//勉强范型吧
data定义12345typedef struct VectorData{ unsigned int size; unsigned int space; TYPE data[];}VectorData;
funtion定义123456789101112131415161718192021typedef struct VectorFuntion{ VectorData* (*initVectorData)(unsigned int); TYPE (*front)(Vector ...
smartpointer
智能指针C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用。
简介智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。C++ 11中最常用的智能指针类型为shared_ptr,它采用引用计数的方法,记录当前内存资源被多少个智能指针引用。该引用计数的内存在堆上分配。当新增一个时引用计数加1,当过期时引用计数减一。只有引用计数为0时,智能指针才会自动释放引用的内存资源。对shared_ptr进行初始化时不能将一个普通指针直接赋值给智能指针,因为一个是指针,一个是类。可以通过make_shared函数或者通过构造函数传入普通指针。并可以通过get函数获得普通指针。
为什么要使用智能指针智能指针的作用是管理一个指针,因为存在以下这种情况:申请的空间在函数结束时忘记释放,造成内存泄漏。使用智能指针可以很大程度上的避免这个问题,因为智能指针是一个类,当超出了类的实例对象的作用域时,会自动 ...
C实现C++继承和多态
C实现C++的继承和多态第一个版本的比较完全,第二个版本的比较好理解,注意,第二个版本细节上是有问题的,细节上没有体现出派生类重载父类,但是大意上还是体现出虚表是发生多态的关键。
关于细节:继承:继承是指子类拥有父类的特性,只要把父类原原本本的放入子类中即可,即:子结构体包含父结构体即可,案例2并未体现出来,懒得改了。
多态:多态是指子类拥有父类的特性或者父类拥有子类的特性,这里是通过虚表来实现的,案例2的虚表写的也有问题,这里由于是继承,应该使用父类的虚表,但是由于并未包含父类,因此这里案例2只包含了一张子类特有的虚表。实际C++的实现应该是包含父类,然后再父类的虚表基础上进行虚函数替换,得到一张新的虚表,进而实现多态。
为什么案例二问题这么多,还是要给出案例2呢?因为案例二是我自己写的,第一次写,难免有许多不足道的地方,留着以后学习批判用。
案例一:1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636 ...
语言可用性强化
语言可用性的强化常量:constexprconstexprC++ 本身已经具备了常量表达式的概念,比如 1+2, 3*4 这种表达式总是会产生相同的结果并且没有任何副作用。如果编译器能够在编译时就把这些表达式直接优化并植入到程序运行时,将能增加程序的性能。一个非常明显的例子就是在数组的定义阶段:
12345678910111213141516171819202122232425262728#include <iostream>#define LEN 10int len_foo() { int i = 2; return i;}constexpr int len_foo_constexpr() { return 5;}constexpr int fibonacci(const int n) { return n == 1 || n == 2 ? 1 : fibonacci(n-1)+fibonacci(n-2);}int main() { char arr_1[10]; ...
noexcept
1 关键字noexcept从C++11开始,我们能看到很多代码当中都有关键字noexcept。比如下面就是std::initializer_list的默认构造函数,其中使用了noexcept。
12constexpr initializer_list() noexcept: _M_array(0), _M_len(0) { }
该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。如果在运行时,noexecpt函数向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会直接终止,调用std::terminate()函数,该函数内部会调用std::abort()终止程序。
2 C++的异常处理C++中的异常处理是在运行时而不是编译时检测的。为了实现运行时检测,编译器创建额外的代码,然而这会妨碍程序优化。在实践中,一般两种异常抛出方式是常用的:
一个操作或者函数可能会抛出一个异常;
一个操作或者函数不可能抛出任何异常。
后面这一种方式中在以往的C++版本中常用throw()表示,在C++ 11中已经被noexcept代替 ...
UniformInitialization
1 统一初始化(Uniform Initialization)在C++ 11之前,所有对象的初始化方式是不同的,经常让写代码的我们感到困惑。C++ 11努力创造一个统一的初始化方式。其语法是使用{}和std::initializer_list,先看示例。
123456789101112int values[]{ 1, 2, 3 };std::vector<int> v{ 2, 3, 6, 7 };std::vector<std::string> cities{ "Berlin", "New York", "London", "Braunschweig"};std::comples<double> c{4.0, 3.0}; //等价于 c(4.0, 3.0)auto ar = { 1, 2, 3 }; // ar 是一个std::initializer_list&l ...
Gcc编译优化
GCC编译优化选项O0优化:不做任何优化,这是默认的编译选项。O和O1:对程序做部分编译优化,对于大函数,优化编译占用稍微多的时间和相当大的内存。使用本项优化,编译器会尝试减小生成代码的尺寸,以及缩短执行时间,但并不执行需要占用大量编译时间的优化。打开的优化选项:
l -fdefer-pop:延迟栈的弹出时间。当完成一个函数调用,参数并不马上从栈中弹出,而是在多个函数被调用后,一次性弹出。
l -fmerge-constants:尝试横跨编译单元合并同样的常量(string constants and floating point constants)
l -fthread-jumps:如果某个跳转分支的目的地存在另一个条件比较,而且该条件比较包含在前一个比较语句之内,那么执行本项优化.根据条件是true或者false,前面那条分支重定向到第二条分支的目的地或者紧跟在第二条分支后面.
l -floop-optimize:执行循环优化,将常量表达式从循环中移除,简化判断循环的条件,并且optionally do strength-reduction,或者将循环打开等。在大型复杂的 ...
进程基础下
此文为查阅大量博客和自己翻书加上自己理解写的缝合文章,文风有所出入还请各位谅解,由于查阅实在较多,这里就不一一列举个个博客和书名了。
1.基础知识介绍1. 进程和程序
程序,是指编译好的二进制文件,在磁盘上,不占用系统资源。
进程,是活跃的(动态的)的程序,占用系统资源,在内存中执行。进程是分配系统资源的基本单位。
区别:
程序是静态的,进程是动态的。
程序一般保存在磁盘中,不占用系统资源,进程会占用系统资源。
一个程序可以对应多个进程,一个进程可以执行一个或多个程序。
进程具有并发性,而程序没有。
程序没有生命周期,进程有生命周期(创建,执行,撤销等)。
2. 多道程序
多道程序设计是指在内存同时放若干道程序,使它们在系统中并发执行,共享系统中的各种资源。当一道程序暂停执行时,CPU 立即转去执行另一道程序。
宏观并行,微观串行。
3. 进程状态转换
4. PCB(进程控制块)
PCB 中记录了操作系统所需的,用于描述进程的当前情况以及控制进程运行的全部信息。
PCB 主要内容:
进程 ID,系统中每一个程序都有唯一的一个 id,在 C/C++中用 pid_t ...