刚听还觉得这有啥区别,实际上是表示这一行代码往栈里面放的顺序,不是栈开口朝左朝右,那当然没区别了
比如:
int p = 0;
printf("%d %d %d \n",p++,++p,p++);
结果是2 2 0,因为先放最右边的p++,放了个0,然后放++p,放了个2,然后放p++,放了个2,最后从栈弹出来,2 2 0
C语言从右向左保存临时数据的原因是:
为了支持可变长参数,以printf函数为例,,定义是这样的:
printf(const char* format,…)
右边的参数数量不定,如果讲fomat置于栈底,我们不知道偏移多少个单位才能到首个参数
最左边的参数存放的是参数个数,我们必须将其置于栈顶,才方便我们知道有几个
可以通过constructor/destructor来指定函数执行顺序在main之前/之后,例如:
void before() __attribute__ ((constructor))
void after() __attribute__ ((destructor))
void before(){
printf("before");
}
void after(){
printf("after");
}
int main(){
printf("main");
return 0;
}
输出的结果就会是 before main after
new运算分两个阶段: (1 )调用:operator new
配置内存;(2)调用对象构造函数构造对象内容
delete运算分两个阶段: (1)调用对象析构函数; (2)调用::operator delete
释放内存
为了精密分工,STL allocator将两个阶段操作区分开来:内存配置有alloc:allocate()
负责, 内存释放由alloc:deallocate()
负责;对象构造由::construct()
负责, 对象析构由::destroy()
负责。
同时为了提升内存管理的效率,减少申请小内存造成的内存碎片问题,SGI STL采用了两级配置器,当分配的空间大小超过128B时,会使用第一级空间配置器; 当分配的空间大小小于128B时,将使用第二级空间配置器。第一级空间配置器直接使用malloc()、realloc()、 free()函数进行内存空间的分配和释放,而第二级空间配置器采用了内存池技术,通过空闲链表来管理内存。
使用示例:构建一个通用的栈stack
template <typename T>
class Stack {
public:
Stack() : top(-1) {}
void push(T val) {
data[++top] = val;
}
T pop() {
return data[top--];
}
private:
T data[100];
int top;
};
由于使用了模板template
,使得stack在应用的时候,可以随意指定内部元素类型,如stack
、stack
等等
因为虚函数表是在构造过程中创建的,你还没构造呢,哪来的虚函数表,也就没有所谓的虚构造函数,无法确定对象具体的对象。
多态就是定义个父类指针,然后让他指向子类实现,比如:
class * Animal = class dog;
如果子类里面在堆区开内存了,delete只能调用到父类的析构函数,子类这块内存就没释放掉,内存泄漏了
多态还可以是子类覆盖父类同名函数,比如
class Animal{
virtual shit(){};
}
class Dog : public Animal{
virtual shit(){Dog shit};
}
这里面,当子类调用该函数时,就会调用到子类的该函数,子类这个函数也得写成虚函数,这和虚函数的实现方式有关:子类的虚函数指针指向子类的虚函数表中该虚函数所在位置,父类的虚函数指针指向父类的虚函数表中该虚函数所在位置,所以二者会调用到不同的实现,形成多态。
队列是FreeRTOS中的概念,其严格遵循队列的性质,只能从队首读,只能从队尾写,也可以按消息上传者的id来读
而消息队列是Linux中的概念,相对不那么严格,允许随机读取,也可以按类型读。
本来以为二者完全相同,实际上还是略有不同的。
互斥锁可以
(1)Nand Flash:单位容量价格低、CPU不能直接访问、容易坏块;
(2)Nor Flash:单位容量价格高、CPU能直接访问、不易坏块、但是不能像内存一样写;
总结:代码必须保存在Flash、硬盘等掉电不丢失的存储介质中,但是代码又不能再这些ROM存储介质中直接运行,必须在RAM中运行,所以设备启动时必须要先将代码重定位到RAM中。