C/C++ 回调函数 callback 异步编程

一、C语言的回调函数

1.小试牛刀 

#include <iostream>
using namespace std;
#include <memory>
#include <stdlib.h>int add(int a, int b) {return a + b;
}void test01() {// 函数指针可以指向任何类型的函数,只要函数的参数列表和返回值类型匹配即可int (*pFunc)(int,int) = add;// 函数指针可以像普通函数一样被调用,通过函数指针变量名加上括号的方式int result = (*pFunc)(1,2);cout << result << endl; // 输出 3
}// typedef 返回类型(*新的函数名)(参数列表)
typedef int (*INT_func)(int,int);
void test02() {INT_func pFunc = add;int result = pFunc(2,3);cout << result << endl; // 输出 5
}// 回调函数,它允许一个函数作为参数传递给另一个函数
// 这种特性使得我们可以将一些特定的任务委托给其他函数来完成// 定义一个函数指针类型
typedef void(*Callback)(int);
// 定义一个函数,该函数接受一个回调函数作为参数
void doSomething(Callback callback) {cout<<"Doing something..."<<endl;// 调用回调函数int data = 1024;callback(data);
}// 定义一个回调函数
void printMyData(int data) {cout<<"My data is: "<<data<<endl;
}int main() {test01();test02();// 将回调函数传递给doSomething函数/*doSomething函数接受一个Callback类型的参数,这是一个指向函数的指针.doSomethings函数调用这个回调函数,并且将一个整型变量作为参数传递给它printMyData在此是一个简单的回调函数,它接受一个整型变量作为参数并且把它打印出来*/doSomething(printMyData);return 0;
}
  • 打印结果:
PS D:\Work\c++> ./bin/app     
3
5
Doing something...
My data is: 1024
PS D:\Work\c++>

2.动态函数指针 

在学习这个知识点的时候,我遇到的坑,非常感谢这位大佬给我指点迷津:

动态函数指针free报错_编程语言-CSDN问答icon-default.png?t=N7T8https://ask.csdn.net/questions/8061857?spm=1001.2014.3001.5505

  • micthis大佬写的代码
#include <iostream>
using namespace std;
#include <memory>
#include <stdlib.h>
int add(int a, int b) {return a + b;
}
/*动态函数指针是指在运行时根据需要动态分配和修改的函数指针它可以在程序运行时根据需要指向不同的函数,从而实现更加灵活和动态的函数调用在c++中,可以使用动态内存分配函数(如malloc或new)来创建动态函数指针
*/
int test01() {// 创建一个指向函数的指针int(**pFunc)(int, int);// 使用malloc动态分配内存int size = sizeof(int(*)(int, int));pFunc = (int(**)(int, int))malloc(size);// 将函数指针指向 add函数*pFunc = add;// 调用函数int result = (*pFunc)(2, 3);cout << result << endl; // 输出 5// 释放内存free(pFunc);return 0;
}
int main() {test01();return 0;
}

打印结果: 

PS D:\Work\c++> ./bin/app
5
PS D:\Work\c++>

3.异步编程

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>// A的实现,一般会隐藏
typedef void (*CallbackPtr)(int);// 函数指针定义typedef struct dataCB{int data;CallbackPtr callback;
}dataCB;// 创建实例
dataCB dataCBInstance = {0, NULL};void* callback_thread(void* arg) { // 此处用的是一个线程// 循环改变p->a的值为 0 1 2 3 4 5 6 7 8 9,每个3s改变一次dataCB* p = (dataCB*)arg;while (1) {sleep(3);// 延时3s执行callback函数p->callback(p->data);// 函数指针执行函数,这个函数来自于应用层Bp->data = (p->data + 1) % 10;}
}void startup_app_A() {// 创建线程pthread_t tid;pthread_create(&tid, NULL, callback_thread, (void*)&dataCBInstance);   
}// 给B的接口,接收注册函数
extern void SetCallBackFun(CallbackPtr cb) {printf("SetCallBackFun print! \n");dataCBInstance.callback = cb;
}// //-----------------------应用者B-------------------------------
void recieve(int data)       // 应用者增加的函数,此函数会在A中被执行
{//do somethingprintf("B得到A的数据 = %d\n",data);
}int main(void) {// 启动Astartup_app_A();SetCallBackFun(recieve);// 主函数while (1) {// std::cout << "main function" << std::endl;printf("main function\n");sleep(2);}return 0;
}
PS D:\Work\c++> ./bin/app
SetCallBackFun print!
main function
main function
B得到A的数据 = 0
main function
B得到A的数据 = 1
main function
main function
B得到A的数据 = 2
main function
B得到A的数据 = 3
main function
main function
B得到A的数据 = 4
main function
B得到A的数据 = 5
main function
main function
B得到A的数据 = 6
main function
B得到A的数据 = 7
main function
main function
B得到A的数据 = 8
main function
B得到A的数据 = 9
main function
main function
B得到A的数据 = 0
main function
B得到A的数据 = 1
main function
main function
B得到A的数据 = 2
main function
B得到A的数据 = 3
main function
main function
B得到A的数据 = 4
main function
B得到A的数据 = 5
main function
main function
B得到A的数据 = 6
main function
B得到A的数据 = 7
main function
main function
B得到A的数据 = 8
main function
B得到A的数据 = 9
main function
main function
B得到A的数据 = 0
main function

参考文章:C/C++面向对象(OOP)编程-回调函数详解(回调函数、C/C++异步回调、函数指针)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_47324800/article/details/135315345

二、C++回调函数

1.动态函数指针

#include <iostream>
using namespace std;
#include <memory>
#include <stdlib.h>
int add(int a, int b) {return a + b;
}
/*动态函数指针是指在运行时根据需要动态分配和修改的函数指针它可以在程序运行时根据需要指向不同的函数,从而实现更加灵活和动态的函数调用在c++中,可以使用动态内存分配函数(如malloc或new)来创建动态函数指针
*/
typedef int(*handleFunc)(int,int);
int test01() {// 创建一个指向函数的指针int(**pFunc)(int, int);pFunc = new handleFunc;// 将函数指针指向 add函数*pFunc = add;// 调用函数int result = (*pFunc)(2, 3);cout << result << endl; // 输出 5// 释放内存delete pFunc;pFunc = nullptr;return 0;
}
int main() {test01();return 0;
}

  2.简单回调

#include <iostream>
#include <functional>// 定义一个回调函数类型
typedef std::function<void(int)> Callback;// 定义一个接受回调函数的函数
void process(int value,Callback callback) {std::cout<<"传入处理值: "<<value<<std::endl;callback(value); // 调用回调函数
}// 定义一个回调函数
int add(int value) {value += 10;std::cout<<"传出结果值: "<<value<<std::endl;return value;
}int main() {int value = 42;process(value,add); // 传递回调函数给process函数return 0;
}

执行结果:

PS D:\Work\c++> ./bin/app
传入处理值: 42
传出结果值: 52
PS D:\Work\c++> 

 3.使用包装器function 

参考文章:C++之可调用对象、bind绑定器和function包装器_完整实现bind和function代码c++-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_65743593/article/details/128963676

 (1) 可调用对象

// 可调用对象
/*在C++中,可以像函数一样的调用的有:普通函数,类的静态成员函数、仿函数、lambda函数,类的非静态成员函数、可被转换为函数的类的对象,统称可调用对象或函数对象可调用对象有类型,可以用指针存储它们的地址,可以被引用(类的成员函数除外)
*/#include <iostream>
using namespace std;
class Object {
public:// 仿函数void operator()(int age, string name) {cout << "年龄:" << age << ",姓名:" << name << endl;}// 类的非静态成员函数void show(int age, string name) {cout << "年龄:" << age << ",姓名:" << name << endl;}
};// 仿函数
void test01() {Object obj;obj(20, "呵呵哒");Object& objRef = obj; // 引用函数objRef(18, "小比尔");
}// lambda函数
void test02() {auto func = [](int age, string name) {cout << "年龄:" << age << ",姓名:" << name << endl;};func(20, "heheda");auto& funcRef = func;// 引用lambda对象funcRef(23, "小比尔");
}// 类的非静态成员函数有地址,但是只能通过类的对象才能调用它,
// C++对它做了特别处理,类的非静态成员函数只有指针类型,
// 没有引用类型,不能引用
void test03() {Object obj;obj.show(30, "智慧老人");void(Object:: *pobj)(int, string) = &Object::show; // 定义类的成员函数的指针(obj.*pobj)(20, "呵呵哒");using PFun = void(Object::*)(int, string);PFun pShow = &Object::show;(obj.*pShow)(78, "圣诞老人");
}int main() {test03();return 0;
}

(2)C++之可调用对象,bind绑定器和function包装器

// 包装器function
// 包含头文件:#include <functional>
// std::function<返回值类型(参数类型列表)> diy_name = 可调用对象;#include <iostream>
#include <functional>
#include <string>
using namespace std;
enum OP {ADD,MUL,SUB
};int add(int a, int b) {return a + b;
}using handleFunc = function<int(int, int)>;
class Object {
public:int add(int a, int b) {return a + b;}static int sub(int a, int b) {return a - b;}static int mul(int a, int b) {return a * b;}// 仿函数int operator()(int a, int b, handleFunc cb, OP op) {switch (op) {case ADD:cout << "("<< a << "+" << b << ") = ";break;case MUL:cout << "(" << a << "*" << b << ") = ";break;case SUB:cout << "(" << a << "-" << b << ") = ";break;}cout << cb(a, b) << endl;return cb(a, b);}
};void test01() {Object obj;function<int(int, int)> func = add;cout << func(1, 2) << endl;
}void test02() {Object obj;handleFunc addCB = std::bind(&Object::add, &obj, std::placeholders::_1, std::placeholders::_2);cout << "addCB(1, 2): " << addCB(1, 2) << endl;handleFunc subCB = Object::sub;cout << "subCB(9, 3): " << subCB(9, 3) << endl;subCB = obj.mul;cout << "subCB(10, 6): " << subCB(10, 6) << endl;handleFunc mulCB = Object::mul;cout << "mulCB(3, 3): " << subCB(3, 3) << endl;subCB = obj.mul;cout << "mulCB(2, 6): " << subCB(2, 6) << endl;function<int(int, int, handleFunc, OP)> operCB = obj;operCB(2, 3, add, ADD);operCB(4, 1, obj.sub, SUB);operCB(2, 9, obj.mul, MUL);
}int main() {//test01();test02();return 0;
}

#include <iostream>
#include <functional>
using namespace std;
using handleFunc = function<void()>;
class Object {
public:// 构造函数参数是一个包装器对象Object(const handleFunc& f) :m_callback(f) {}void notify() {m_callback();// 调用通过构造函数得到的函数指针}
private:handleFunc m_callback;
};class Subject{
public:void operator()() { cout << "heheda" << endl; }
};int main() {Subject s;Object obj(s);obj.notify();return 0;
}

#include <iostream>
#include <functional>
using namespace std;
class Person {
public:// 仿函数void operator()(int age, string name) {cout << "age: " << age << ",name: " << name << endl;}void show(int age, string name) {cout << "age: " << age << ",name: " << name << endl;}
};void test01() {Person person;// 仿函数function<void(int, string)> opFunc = bind(Person(), placeholders::_1, placeholders::_2);opFunc(20,"heheda");// 类成员函数需要绑定该类的this指针 Person p1;function<void(Person&, int, string)> showFunc = bind(&Person::show,placeholders::_1, placeholders::_2, placeholders::_3);showFunc(p1, 17, "Tom");// 为了统一,将对象提前绑定function<void(int, string)> showFunc2 =bind(&Person::show, p1, placeholders::_1, placeholders::_2);showFunc2(8, "Jerry");
}int main() {test01();
}

#include <iostream>
#include <functional>
#include <thread>
#include <unistd.h>
using namespace std;// A的实现,一般会隐藏
using CallbackPtr = std::function<void(int)>;typedef struct dataCB{int data;CallbackPtr callback;
}dataCB;// 创建实例
dataCB dataCBInstance = {0, NULL};void* callback_thread(void* arg) { // 此处用的是一个线程// 循环改变p->a的值为 0 1 2 3 4 5 6 7 8 9,每个3s改变一次dataCB* p = (dataCB*)arg;while (1) {sleep(3);// 延时3s执行callback函数p->callback(p->data);// 函数指针执行函数,这个函数来自于应用层Bp->data = (p->data + 1) % 10;}
}void startup_app_A() {// 创建线程std::thread(callback_thread, (void*)&dataCBInstance).detach(); // .detach()分离线程
}// 给B的接口,接收注册函数
extern void SetCallBackFun(CallbackPtr cb) {printf("SetCallBackFun print! \n");dataCBInstance.callback = cb;
}// //-----------------------应用者B-------------------------------
void recieve(int data)       // 应用者增加的函数,此函数会在A中被执行
{//do somethingprintf("B得到A的数据 = %d\n",data);
}int main(void) {// 启动Astartup_app_A();SetCallBackFun(recieve);// 主函数while (1) {printf("main function\n");sleep(2);}return 0;
}

(3)异步编程

#include <iostream>
#include <functional>
#include <thread>
#include <unistd.h>
using namespace std;// A的实现,一般会隐藏
using CallbackPtr = std::function<void(int)>;typedef struct dataCB{int data;CallbackPtr callback;
}dataCB;// 创建实例
dataCB dataCBInstance = {0, NULL};void* callback_thread(void* arg) { // 此处用的是一个线程// 循环改变p->a的值为 0 1 2 3 4 5 6 7 8 9,每个3s改变一次dataCB* p = (dataCB*)arg;while (1) {sleep(3);// 延时3s执行callback函数p->callback(p->data);// 函数指针执行函数,这个函数来自于应用层Bp->data = (p->data + 1) % 10;}
}void startup_app_A() {// 创建线程std::thread(callback_thread, (void*)&dataCBInstance).detach(); // .detach()分离线程
}// 给B的接口,接收注册函数
extern void SetCallBackFun(CallbackPtr cb) {printf("SetCallBackFun print! \n");dataCBInstance.callback = cb;
}// //-----------------------应用者B-------------------------------
void recieve(int data)       // 应用者增加的函数,此函数会在A中被执行
{//do somethingprintf("B得到A的数据 = %d\n",data);
}int main(void) {// 启动Astartup_app_A();SetCallBackFun(recieve);// 主函数while (1) {printf("main function\n");sleep(2);}return 0;
}
PS D:\Work\c++> ./bin/app
SetCallBackFun print! 
main function
main function
B得到A的数据 = 0
main function
main function
B得到A的数据 = 1
main function
B得到A的数据 = 2
main function
main function
B得到A的数据 = 3
main function
B得到A的数据 = 4
main function
main function
B得到A的数据 = 5
main function
B得到A的数据 = 6
main function
B得到A的数据 = 7
main function
main function
B得到A的数据 = 8
main function
B得到A的数据 = 9
main function
PS D:\Work\c++> cmake --build build
[100%] Built target app
PS D:\Work\c++> ./bin/app
SetCallBackFun print! 
main function
main function
B得到A的数据 = 0
main function
B得到A的数据 = 1
main function
main function
B得到A的数据 = 2
main function
B得到A的数据 = 3
main function
main function
B得到A的数据 = 4
main function
main function
B得到A的数据 = 5
main function
B得到A的数据 = 6
main function
main function
B得到A的数据 = 7
main function
B得到A的数据 = 8
main function
main function
B得到A的数据 = 9
main function
B得到A的数据 = 0
main function
main function
B得到A的数据 = 1
main function
B得到A的数据 = 2
main function
B得到A的数据 = 3
main function
main function
B得到A的数据 = 4
main function
B得到A的数据 = 5
main function
main function
B得到A的数据 = 6
main function
B得到A的数据 = 7
main function
main function
B得到A的数据 = 8
main function
B得到A的数据 = 9
main function
main function
B得到A的数据 = 0
main function
B得到A的数据 = 1
main function
main function
B得到A的数据 = 2
main function
B得到A的数据 = 3
main function
main function
B得到A的数据 = 4
main function
B得到A的数据 = 5
main function
main function
B得到A的数据 = 6
main function
B得到A的数据 = 7
main function
main function
B得到A的数据 = 8
main function
B得到A的数据 = 9
main function
main function
B得到A的数据 = 0
main function
B得到A的数据 = 1
main function
main function
B得到A的数据 = 2
main function
B得到A的数据 = 3
main function
main function
B得到A的数据 = 4
main function
B得到A的数据 = 5
main function
main function
B得到A的数据 = 6
main function
B得到A的数据 = 7
main function
main function
B得到A的数据 = 8
main function
B得到A的数据 = 9
main function
main function
B得到A的数据 = 0
main function
B得到A的数据 = 1
main function
main function
B得到A的数据 = 2
main function
B得到A的数据 = 3
main function
main function
B得到A的数据 = 4
main function
B得到A的数据 = 5
main function
main function
B得到A的数据 = 6
main function
B得到A的数据 = 7
main function
main function
B得到A的数据 = 8
main function
B得到A的数据 = 9
main function
main function
B得到A的数据 = 0
main function
B得到A的数据 = 1
main function
main function
B得到A的数据 = 2
main function
B得到A的数据 = 3
main function
main function
B得到A的数据 = 4
main function
B得到A的数据 = 5
main function
main function
B得到A的数据 = 6
main function
B得到A的数据 = 7
main function
main function
B得到A的数据 = 8

参考文章:

c++ 用std::function包装类的非静态成员_c++ function 绑定非静态成员函数-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_62953519/article/details/128438241

未完待续 ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/666495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何结合ChatGPT生成个人魔法咒语词库

3.6.1 ChatGPT辅助力AI绘画 3.6.1.1 给定主题让ChatGPT直接描述 上面给了一个简易主题演示一下&#xff0c;这是完全我没有细化的提问&#xff0c;然后把直接把这些关键词组合在一起。 关键词&#xff1a; 黄山的美景&#xff0c;生机勃勃&#xff0c;湛蓝天空&#xff0c;青…

厕所革命与可持续发展的“九牧方案”

人类文明的历史&#xff0c;就是厕所的革命史&#xff0c;小小的厕所里&#xff0c;承载着大故事。 2015 年&#xff0c;印度一个名叫娜尔的女孩&#xff0c;因为丈夫不愿意在家盖厕所&#xff0c;向法庭提出了离婚申请&#xff0c;由此引发了全印度“无厕所&#xff0c;无新娘…

从零开始 TensorRT(2)Python 篇:原生 API 构建网络

前言 学习资料&#xff1a; TensorRT 源码示例 官方文档&#xff1a;Working With TensorRT Using The Python API 官方文档&#xff1a;TensorRT Python API 官方文档&#xff1a;CUDA Python B站视频&#xff1a;TensorRT 教程 | 基于 8.6.1 版本 B站视频配套代码 cookbook …

OSG帧渲染,如何实现自定义动画效果

看到这个标题,老司机可能会想到OSG动画相关的内容,比如osg::AnimationPath类和osg::AnimationPathCallback类,这些动画类,可以实现按照一定的插值方式,生成路径,物体对象按照生成的路径或者预先指定的路径来完成相应的动作的动画。 路径动画有三种动画模式,分别为单摆环…

幻兽帕鲁服务器游戏版本怎么升级更新?

哈喽大家好&#xff0c;我是咕噜美乐蒂&#xff0c;很高兴又见面啦&#xff01; 幻兽帕鲁&#xff08;Monster Hunter: World&#xff09;是一款热门的多人在线游戏&#xff0c;玩家可以在服务器上与其他玩家一起探险、狩猎怪物。为了保持游戏的平衡性和提供更好的游戏体验&am…

【百度Apollo】探索创新之路:深入了解Apollo开放平台

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下…

docker部署RedisCluster集群简单介绍

本文介绍自己建立一个redis-cluster集群的实践&#xff0c;三主三从&#xff0c;使用docker搭建。 其实搭建很简单&#xff0c;就是建立6个容器&#xff0c;每个容器配置不同的端口号&#xff0c;其他的都是一样的。 假设建立6个端口号分别为 5555到5560。 配置文件 port 5…

redis相关问题

面试官&#xff1a;什么是缓存穿透 ? 怎么解决 ? 候选人&#xff1a; 嗯~~&#xff0c;我想一下 缓存穿透是指查询一个一定不存在的数据&#xff0c;如果从存储层查不到数据则不写入缓存&#xff0c;这将导致这个不存在的数据每次请求都要到 DB 去查询&#xff0c;可能导致 D…

树莓派突然不能ssh远程连接的踩坑记录及解决方案

在家研究树莓派&#xff0c;远程连接树莓派吃了不少苦&#xff0c;总是一些意想不到的问题出现&#xff0c;明明昨天还能远程连接&#xff0c;今天又不能了。经过一系列排查&#xff0c;终于锁定&#xff1a; 因为我之前设置的树莓派的静态ip地址&#xff0c;但是可能因为是家…

ai创作软件有哪些?这5个软件了解一下

ai创作软件有哪些&#xff1f;随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;在各个领域都展现出了惊人的实力。特别是在内容创作领域&#xff0c;AI技术已经成为了助力创作者们提高效率、释放创意的得力助手。今天&#xff0c;我们将为大家介绍五款AI创作…

开源模型应用落地-业务优化篇(四)

一、前言 经过线程池优化、请求排队和服务实例水平扩容等措施,整个AI服务链路的性能得到了显著地提升。但是,作为追求卓越的大家,绝不会止步于此。我们的目标是在降低成本和提高效率方面不断努力,追求最佳结果。如果你们在实施AI项目方面有经验,那一定会对GPU服务器的高昂…

软件工程(最简式总结)

目录 第一章:概述 1.软件危机的表现原因 2.常见的软件开发方法包括&#xff1a; 3.软件工程基本原则 4.软件工程三要素 5.设计模式的分类 6.针对变换型数据流设计步骤 7.针对事务型数据流设计步骤 第二章&#xff1a;软件过程 1.软件生命周期 2.软件过程模型 &…

视觉惯性SLAM系列——ORB-SLAM3的重定位线程(Relocalization Thread)(九)

ORB-SLAM3的重定位线程&#xff08;Relocalization Thread&#xff09;&#xff08;九&#xff09; 重定位线程&#xff08;Relocalization Thread&#xff09;在ORB-SLAM3系统中扮演着关键的角色&#xff0c;尤其是在跟踪丢失的情况下。这个线程的主要任务是在相机失去当前轨迹…

flask_django_python五金电商网络营销的可视化分析研究

前面部分完成了系统需求分析&#xff0c;了解到新闻数据业务方面的需求&#xff0c;系统主要分为用户管理、五金信息管理、在线留言、系统管理等功能。销的可视化研究&#xff0c;并对这些数据进行处理&#xff0c; 然后对这些数据进行可视化分析和统计。 Python 爬虫技术目前来…

Element-plus之el-upload上传图片后回显,以及将回显的图片再次上传

在实际的业务中往往需要把提交但尚未上传的图片显示回前端&#xff0c;等待上传&#xff0c;以下方法是将提交后的图片回显的方法 <template><el-uploadaction"/api/imageContainer/saveOrUpdate"accept"image/bmp,image/jpeg,image/jpg,image/png,ima…

优雅的从HuggingFace下载模型

1. 下载全部文件 以下都以下载bloom模型为例 git lfs install git lfs clone https://huggingface.co/bigscience/bloom-7b1这种方式下载会显示下载的进度及网速&#xff0c;因此一般推荐使用这种方式下载。如果直接使用git clone https://huggingface.co/bigscience/bloom-7…

【云计算】opentack的高级服务部署与调优

opentack的高级服务部署与调优 swift 对象存储 安装 Swift 服务。安装完成后&#xff0c;使用命令创建一个名叫 examcontainer 的容器&#xff0c;将 cirros-0.3.4-x86_64-disk.img 镜像上传到 examcontainer 容器中&#xff0c;并 设置分段存放&#xff0c;每一段大小为 10…

js数组和字符串之间的转换方式以及数组的一些方法

一、数组和字符串之间的转换方式 1&#xff09;将字符串切割成字符串数组—stringObject.split(separator, howmany) seperator-----字符串、正则表达式&#xff0c;必需 howmany------指定返回的数组的最大长度&#xff0c;可省略&#xff0c;省略后全量返回 源代码 var str&q…

Linux内核与驱动面试经典“小”问题集锦(1)

笔者混迹职场这么多年来换了不少工作。头些年做的是单片机工程师&#xff0c;后来转入了Linux。转入Linux后&#xff0c;一开始做BSP和驱动工程师&#xff08;当然后来应用工程师的事也没少干&#xff09;&#xff0c;近几年来专做了Linux内核与系统工程师。由打转入Linux后&am…

c++阶梯之类与对象(一)

目录 1.面向过程与面向对象 c语言的视角&#xff1a; c的视角 2. 类的引入 3. 类的定义 3.1 类的两种定义方式 3.2 成员变量如何命名 4. 类的访问限定符与封装 4.1 访问限定符 4.2 封装 5. 类的作用域 6. 类的实例化 7. 类对象模型 7.1 怎么计算一个类对象的…