各类新鲜小问题


本文章专门用于记录学习过程中遇到的感觉很新鲜的问题,以及一些冷知识

压栈顺序从右到左

刚听还觉得这有啥区别,实际上是表示这一行代码往栈里面放的顺序,不是栈开口朝左朝右,那当然没区别了
比如:

	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置于栈底,我们不知道偏移多少个单位才能到首个参数
最左边的参数存放的是参数个数,我们必须将其置于栈顶,才方便我们知道有几个

在main之前执行函数

可以通过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()函数进行内存空间的分配和释放,而第二级空间配置器采用了内存池技术,通过空闲链表来管理内存。

模板类template

使用示例:构建一个通用的栈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 <typename T>,使得stack在应用的时候,可以随意指定内部元素类型,如stack<int>stack<double>等等

构造函数不能声明为虚函数

因为虚函数表是在构造过程中创建的,你还没构造呢,哪来的虚函数表,也就没有所谓的虚构造函数,无法确定对象具体的对象。

多态时要虚析构

多态就是定义个父类指针,然后让他指向子类实现,比如:

class * Animal = class dog;

如果子类里面在堆区开内存了,delete只能调用到父类的析构函数,子类这块内存就没释放掉,内存泄漏了

多态还可以是子类覆盖父类同名函数,比如

class Animal{
	virtual shit(){};
}
class Dog : public Animal{
	virtual shit(){Dog shit};
}

这里面,当子类调用该函数时,就会调用到子类的该函数,子类这个函数也得写成虚函数,这和虚函数的实现方式有关:子类的虚函数指针指向子类的虚函数表中该虚函数所在位置,父类的虚函数指针指向父类的虚函数表中该虚函数所在位置,所以二者会调用到不同的实现,形成多态。

队列(Queue)与消息队列(Message Queue)

队列是FreeRTOS中的概念,其严格遵循队列的性质,只能从队首读,只能从队尾写,也可以按消息上传者的id来读
而消息队列是Linux中的概念,相对不那么严格,允许随机读取,也可以按类型读。

互斥锁和二进制信号量

本来以为二者完全相同,实际上还是略有不同的。
互斥锁可以

重定位

(1)Nand Flash:单位容量价格低、CPU不能直接访问、容易坏块;
(2)Nor Flash:单位容量价格高、CPU能直接访问、不易坏块、但是不能像内存一样写;
总结:代码必须保存在Flash、硬盘等掉电不丢失的存储介质中,但是代码又不能再这些ROM存储介质中直接运行,必须在RAM中运行,所以设备启动时必须要先将代码重定位到RAM中。

32/64位系统不同数据类型所占字节数和取值范围

在这里插入图片描述

字符串存在隐式类型转换

对于一个字符串“abc”而言,如果将它赋值给指针,例如:

char* my_char=“abc”;
my_char[1]='+';

由于等号左边是一个指针,这时“abc”会被隐式类型转换为char const*,这时第二行的赋值操作就不被允许了,因为是const变量,会报错:Segmentation fault (core dumped)

class 和 struct

class 和 struct 最本质的区别 : class 是引用类型,它在中分配空间,栈中保存的只是引用;而 struct 是值类型,它在中分配空间。

C中的struct
1、成员访问权限: 在C中,struct 中的所有成员都是公共的,没有默认的成员访问权限。这意味着你可以在任何地方访问和修改 struct 中的成员。
2、方法和函数: 在C中,struct 不能包含成员函数或方法。struct 通常只包含数据成员,而不包含与这些数据相关的行为。
3、继承: 在C中,struct 不支持继承的概念。你不能从一个 struct 派生出另一个 struct。

C++中的struct
1、成员访问权限: 在C++中,struct 中的成员默认是公共的。这与C中的 struct 相似,但与C++中的 class 不同。
2、方法和函数: 在C++中,struct 可以包含成员函数,这使得它可以具有与数据成员相关的行为,就像 class 一样。
3、继承: 在C++中,struct 支持继承,就像 class 一样。你可以从一个 struct 派生出另一个 struct,并且可以使用访问修饰符来控制派生类对基类成员的访问权限。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值