关于c++:C面试八股文在C中有哪些可执行体

某日二师兄加入XXX科技公司的C++工程师开发岗位第14面: 面试官:在C++中,有哪些可执行体? 二师兄:可执行体? 面试官:也就是可调用对象。 二师兄:让我想一想。函数、函数指针、类的静态方法、类的成员办法、仿函数、lambda表达式。 面试官:能说一说他们之间有什么区别吗? 二师兄:好的。函数是一段代码,执行特定工作,承受参数并返回值。 int add(int a, int b){ return a + b;}二师兄:函数指针是指向函数的指针。int add(int a, int b){ return a + b;}using addptr = int(*)(int,int);addptr ptr = &add; //函数指针int sum = addptr(1,2);二师兄:类的静态方法和函数基本一致,只不过此静态方法属于整个类所有。而成员办法则只能通过类的实例来调用。class Foo{public: static int add(int a, int b) { return a + b;} //静态方法 int add2(int a, int b) { return a + b; } //成员办法};int sum1 = Foo::add(1,2);Foo f;int sum2 = f.add2(2,1);二师兄:仿函数是一个类或构造体,重载了()运算符。struct Add{ int operator()(int a, int b) { return a+ b;} };int sum = Add()(1,2);二师兄:lambda表达式在C++11时被引入,实质上是是一个匿名函数。auto add = [](int a, int b) {return a + b;};int sum = add(1,2);//orint a =1 , b = 2;auto ladd = [a,b](){return a + b;};int sum = ladd();面试官:你晓得std::function? ...

June 14, 2023 · 1 min · jiezi

关于c++:C面试八股文什么是RAII

某日二师兄加入XXX科技公司的C++工程师开发岗位第13面: 面试官:什么是RAII? 二师兄:RAII是Resource Acquisition Is Initialization的缩写。翻译成中文是资源获取即初始化。 面试官:RAII有什么特点和劣势? 二师兄:次要的特点是,在对象初始化时获取资源,在对象析构时开释资源。这种技术能够防止资源正路或内存透露,进步程序的健壮性和可维护性。 面试官:应用RAII能够做哪些事件? 二师兄:次要能够治理动态分配的内存而不须要手动申请和开释,治理锁不须要手动加锁和解锁,治理句柄不须要手动关上和敞开。 面试官:你晓得有哪些C++规范库中曾经存在的类型应用了RAII技术? 二师兄:有std::shared_ptr、std::unqiue_ptr和std::lock_guard及std::unqiue_lock。 面试官:晓得std::lock_guard如何实现的吗? 二师兄:应该是在结构的时候锁定,在析构的时候解锁。 class lock_gurad{public: lock_gurad(std::mutex& mtx):mtx_(mtx){mtx_.lock(); } ~lock_gurad(){mtx_.unlock();}private: std::mutex mtx_;};面试官:好的。明天的面试到此结束,回去等告诉吧。让咱们认真看一下二师兄的这段代码,不难发现存在以下问题: std::mutex mtx_不能间接保留值,因为mutex没有拷贝构造函数,所以这里须要应用援用。须要在构造函数前加上explicit关键字,避免编译器隐式转换lock_gurad不能拷贝(因为会有多个实例治理一个互斥锁,导致不可预测的行为),所以要删除拷贝构造函数和拷贝赋值运算符。修复后的代码如下: class lock_guard{public: explicit lock_guard(std::mutex& mtx) : mtx_(mtx){ mtx_.lock(); } ~lock_guard(){ mtx_.unlock(); } lock_guard(const lock_guard&) = delete; lock_guard& operator=(const lock_guard&) = delete;private: std::mutex& mtx_;};好了,今日份面试到这里就完结了。 关注我,带你走进二师兄的C++面试生涯。 关注我,带你21天“精通”C++!(狗头)

June 13, 2023 · 1 min · jiezi

关于c++:C面试八股文了解位运算吗

某日二师兄加入XXX科技公司的C++工程师开发岗位第12面: 面试官:理解位运算吗? 二师兄:理解一些。(我很相熟) 面试官:请列举以下有哪些位运算? 二师兄:按位与(&)、按位或(|)、按位异或(^),按位取反(~)、左移(<<)和右移(>>)。 面试官:好的。那你晓得位运算有什么劣势吗? 二师兄:劣势次要有两点:1.速度快。2.节俭寄存器/内存空间。 面试官:在C++中,如何解决int型正数最高位(是1)的左移或者右移? 二师兄:不同编译器解决的办法不同。此操作在C++中属于未定义的行为。所以不要应用带符号的整数加入位运算。 面试官:如何判断一个数是不是2的整数次方? 二师兄:应用这个数与这个数-1按位与,如果后果是0,则这个数是2的整数次方,否则不是。 bool is_power_of_two(unsigned int n){ return n & (n-1) == 0;}面试官:如何应用位运算替换两个数,而不能申请额定的空间? 二师兄:能够应用异或操作,原理是一个数异或两次同一个数,后果等于原值。 void swap(unsigned int& a, unsigned int& b){ a = a ^ b; // a = a ^ b; b = a ^ b; // b = a ^ b ^ b = a; a = a ^ b; // a = a ^ b ^ a = b;}面试官:如何获取一个数字中的某一位是0 还是1 ? ...

June 12, 2023 · 1 min · jiezi

关于c++:C面试八股文在C中你知道哪些运算符

某日二师兄加入XXX科技公司的C++工程师开发岗位第11面: 面试官:在C++中,你都晓得都哪些运算符? 二师兄:啥?运算符?+-*/=这些算吗? 面试官:嗯,还有其余的吗? 二师兄:当然还有,+=,-=,*=,/=,==,还有逻辑运算,位运算等。 面试官:好的。那你晓得这些运算的优先级吗? 二师兄:(面试官傻逼吧,这谁记得住)记不住了,个别我都会加括号来表白我的意思。 面试官:好的。那你晓得上面这段程序会输入什么吗? #include <iostream>int main(int argc, char const *argv[]){ int i = 0; std::cout << i++ + ++i << std::endl;}二师兄:应该是2吧。 面试官:那你晓得运算符的求值程序吗? 二师兄:应该是从左向右? 面试官:%这个符号是求余的你应该晓得吧。如果应用一个int型正数对另一个int型正数求余数,后果是负数还是正数? 二师兄:应该是负数吧。 面试官:对一个整数判断是否位true或者false,能够用if(val == true)或if(val == false)吗? 二师兄:不能,因为在应用int型与bool型比拟时,会把true和false转换成int型,下面两个表达式等同于if(val == 1)和if(val == 0),与咱们的本意不符。 面试官:你晓得a=a+1和a+=1这两者的区别吗? 二师兄:两者应该没啥区别吧? 面试官:你晓得++i和i++的区别吗? 二师兄:前者返回i+1,后者返回i。之后i会被+1。 面试官:C++11中的左值右值你相熟吗? 二师兄:理解过一些(我很相熟)。 面试官:那你晓得算数运算符、逻辑运算符、位运算符返回的后果是左值还是右值吗? 二师兄:额,让我想想。。。应该都是右值。 面试官:好的。那你晓得点(.)和箭头(->)运算符返回的后果是左值还是右值吗? 二师兄:额。。。应该都是左值。(应该是的吧。。。) 面试官:咱们都晓得,一个int型的正数,在最高(31)位上的值是1。那么如果对这个正数进行右移(>>)操作,最高位上的1会被挪动吗? 二师兄:应该不会。可能跟编译器实现无关。 面试官:你晓得重载运算符要留神哪些事项吗? 二师兄:其实工作中很少重载运算符,我感觉最重要的事项就是尽量不要重载运算符。(我好机智。。) 面试官:好的,明天的面试完结了,回去等告诉吧。 对于今日二师兄的体现,让咱们来回过头看一下: 在C++中,你都晓得哪些运算符?除了算术运、逻辑、位、关系、等于运算符,如sizeof,decltype、new/delete也属于运算符。 晓得上面这段程序会输入什么吗? 应该是2吧。 这里程序的输入的后果是不确定的。起因会在上面讲。 那你晓得运算符的求值程序吗?在C++的规范中,大部分的运算符两侧的表达式的求值程序是不确定的。在上个例子中,可能会先计算i++,而后再计算++i,也可能反过来。所以这里的后果不缺行,属于未定义的行为(undefined behavior)。 那么C++中有没有确定求值程序的二元运算符呢?答案是有的,而且仅有这四个:&&,||,:?,,。C++规范保障这四个运算符的求值程序是从左到右确定的。 你晓得a=a+1和a+=1这两者的区别吗?此两者有一点区别,那就是前者的a会被求值2次,而后者只会被求值1次。如果开启编译器优化,有可能会被优化雷同的成果。 你晓得++i和i++的区别吗?除了二师兄的答复外,前置++的效率要高于后者,因为前者不须要缓存值,以用来返回。 晓得点(.)和箭头(->)运算符返回的后果是左值还是右值吗?这里箭头运算符的调用者必定是左值(想想看为什么),然而号运算符的调用者可不肯定是左值。所以箭头运算符的后果肯定是左值,当点运算符的调用者是左值时,返回值时左值,当点运算符的调用者是右值时,返回值时右值。 正数进行右移(>>)操作,最高位上的1会被挪动吗很遗憾,这里答复会和不会都不对,因为这也属于未定义的行为(undefined behavior)。 所以不要对有符号的类型进行按位操作,最好的状况是正好以后编译器的实现和你的预期吻合,以后平台运行无异样。一旦移植代码,可能会遇到意想不到的问题。 ...

June 11, 2023 · 1 min · jiezi

关于c:Linux网络开发必学教程31文件服务器最终实现

问题: # favicon.ico 简介 是什么?申请如何解决?favicon.ico 简介favicon.ico 是网页上的图标文件 名称:默认名称位 favicon.ico尺寸:16x16、32x32、48x48、64x64、128x128色彩: 8 位、24 位 或 32 位 个别说,在网页中能够通过 HTML 语句设置图标文件 <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">如果不设置,浏览器会在网站根目录中申请图标文件 即:被动发送 HTTP 申请 /favicon.ico浏览器与文件服务器的交互文件浏览 点击列表中的文件夹 进入子文件夹(展现子文件夹列表)文件下载 点击列表中的文件 下载指标文件错误处理 向服务器发送谬误申请 浏览不存在的文件夹 / 下载不存在的文件# 文件下载 char buf[1024] = {0};int max = lseek(fd, 0, SEEK_END);sprintf(head, HTTP_FORMAT, max);len = TcpClient_SendRow(client, head, strlen(head));lseek(fd, 0, SEEK_SET);while ((len > 0) && (len = read(fd, buf, sizeof(buf))) > 0) { ret + TcpClient_SendRow(client, buf, len);}ret = (ret == max);错误处理static const char* ERR_FORMAT = "<!DOCTYPE html>" "<html>" " <head>" " <meta charset=\"utf-8\">" " <title>D.T.Software</title>" " </head>" " <body>" " <h1>DT4SW Http File Server</h1>" " <hr/>" " <h2>OOPS!!!</h2>" " <h3>Path: \'%s\' is NOT available...</h3>" " </body>" "</html>";char *ToErrString(const char *path){ char *ret = NULL; if (path && (ret = malloc(strlen(ERR_FORMAT) + strlen(path) + 1))) { sprintf(ret, ERR_FORMAT, path); } return ret;}响应模块入口函数int RequestHandler(TcpClient* client, const char* req, const char* root){ int ret = 0; if (client && req && root) { char *ap = GetAbsPath(req, root); if (ap && (access(ap, F_OK) == 0)) { if (GetEntryCount(ap) < 0) { ret = FileReqHandler(client, req, root); } else { ret = DirReqHandler(client, req, root); } } else { ret = BadReqHandler(client, req, root); } free(ap); } return ret;}编程试验:最终实现源码下载地址 ...

June 10, 2023 · 1 min · jiezi

关于c++:C面试八股文了解sizeof操作符吗

某日二师兄加入XXX科技公司的C++工程师开发岗位第10面: 面试官:理解sizeof操作符吗? 二师兄:稍微理解(不就是求大小的嘛。。) 面试官:请讲以下如何应用sizeof? 二师兄:sizeof次要是求变量或者类型的大小。间接应用sizeof(type)或sizeof(var)即可。 面试官:嗯。sizeof(int*)、sizeof(int**) 和sizeof(int[4])各返回什么? 二师兄:前两者的返回值相等。在32位操作系统中返回4,64位操作系统中返回8。sizeof(int[4])返回16,是因为sizeof运算时数组不会进化为指针。 面试官:如果一个int* p = nullptr,那么对其进行sizeof(*p)会产生什么? 二师兄:返回4。起因是sizeof在编译时求值,sizeof只须要获取*p的类型,并不对*p求值。所以不会产生段谬误。 面试官:上面三个szieof运算符,各返回什么? #include <iostream>#include <string>int main(int argc, char const *argv[]){ const char* str1 = "hello"; char str2[] = "hello"; std::string str3 = "hello"; std::cout << sizeof(str1) << std::endl; std::cout << sizeof(str2) << std::endl; std::cout << sizeof(str3) << std::endl;}二师兄:第一个返回4或8,因为它是个指针,第二个是个数组,不过开端有个\0结束符,所以它的值是6,第三个不分明,然而等于sizeof(std::string)。 面试官:好的。应用sizeof对以下两个构造体求大小, #include <iostream>struct Foo{ char c; int i; double d;};struct Goo{ char c; double d; int i;};int main(int argc, char const *argv[]){ std::cout << sizeof(Foo) << std::endl; std::cout << sizeof(Goo) << std::endl;}二师兄:sizeof(Foo)应该等于16,而sizeof(Goo)应该等于24。因为须要内存对齐。 ...

June 9, 2023 · 1 min · jiezi

关于c++:C面试八股文C中设计一个类要注意哪些东西

某日二师兄加入XXX科技公司的C++工程师开发岗位第9面: 面试官:C++中,设计一个类要留神哪些货色? 二师兄:设计一个类次要思考以下几个方面:1.面向对象的封装、继承及多态。2.big three或者big five。3.运算符和函数重载、动态成员、友元、异样解决等相干问题。 面试官:请介绍一下面向对象的三个个性。 二师兄:封装是将类的函数和数据封装起来,内部不能间接拜访类的数据,而是须要通过办法拜访数据。继承是指一个类能够继承另一个类的属性和办法。多态是指一个对象能够体现出多种状态。 面试官:请问多态是如何实现的? 二师兄:多态的是通过父类的指针或援用指向子类的对象实现的。在对象中保护一个虚指针(vtptr),这个指针指向一个虚表(vtable),当用户通过父类对象拜访子类的办法时,通过查问虚表中对应的办法的地址,并跳转到此地址执行间接拜访对象的办法。所以多态是有一点点运行时开销的。 面试官:你方才所说的big three和big five是什么? 二师兄:(嘿嘿,被装到了)类的big three别离是拷贝构造函数(copy constructor)、拷贝赋值运算符(copy assignment)和析构函数。而类的big five则多了两个,别离是挪动构造函数(move constructor)和挪动赋值运算符(move assignment)。前面两个是C++11之后引入的。 面试官:好的。那你晓得为什么要引入挪动结构和挪动赋值吗? 二师兄:次要是为了效率。挪动结构和挪动赋值不须要把所有的数据从新拷贝一遍,而是霸占了被挪动对象的数据的所有权。代价是被挪动对象在被挪动后不能应用。 面试官:嗯。那你晓得为什么挪动结构和挪动赋值都要加上noexcept关键字吗? 二师兄:额。。。如同不让抛异样? 面试官:你晓得类的动态成员变量须要留神哪些问题吗? 二师兄:要留神哪些问题?额。。。 面试官:在成员办法后加const是为什么? 二师兄:次要是为了束缚这个成员办法不更改对象的任何数据。 面试官:还有其余的起因吗? 二师兄:如同没有了吧。。。 面试官:类的成员办法能够通过const符号重载吗? 二师兄:这个,,应该能够吧。。 面试官:你晓得什么是类的成员办法的援用限定符吗? 二师兄:没有据说过耶。。。 面试官:好的,回去等告诉吧。 让咱们来看一看今日二师兄的体现吧, 为什么挪动结构和挪动赋值都要加上noexcept关键字?因为在应用挪动语义时,通常会将资源的所有权从一个对象转移到另一个对象,而不是复制资源。如果抛出异样,那么在转移资源的过程中可能会呈现问题,导致资源透露或其余不可预测的行为。 另外,加上 noexcept 关键字还能够进步代码的性能,因为编译器能够在不必要的状况下进行优化。 类的动态成员变量须要留神哪些问题?动态成员变量的初始化程序是不确定的。如果一个动态成员变量依赖于另一个动态成员变量的值,要确保第二个动态化成员先被初始化,否则程序可能会呈现未定义的行为。 动态成员变量的值能够被多个实例同时批改,因而在多线程拜访动态成员时要留神数据竞争问题。动态变量的生命周期与程序的生命周期雷同,因而它们可能会占用大量的内存。 在成员办法后加const是为什么?一是能够束缚此办法不会更改对象的任何数据。二是cosnt对象也能够拜访此成员办法。 #include <iostream>struct Foo{ void f1(){std::cout <<"f1" << std::endl;} void f2() const{std::cout <<"f2" << std::endl;}};int main(int argc, char const *argv[]){ Foo foo; foo.f1(); foo.f2(); const Foo& foo2 = foo; foo2.f1(); //这里无奈通过编译,因为const对象无法访问非const 办法 foo2.f2(); //这里能够通过编译}类的成员办法能够通过const符号重载吗?这是一个很好的问题,预计很多人没有思考过。先说答案,底层const能够,而顶层const不能够。 ...

June 8, 2023 · 2 min · jiezi

关于c:Linux网络开发必学教程30文件浏览交互涉及

问题:浏览器与文件服务器如何交互?浏览器与文件服务器的交互文件浏览 点击列表中的文件夹 → 进入子文件夹(展现子文件夹列表)文件下载 点击列表中的文件 → 下载指标文件错误处理 向服务器发送谬误申请 → 浏览不存在的文件夹 / 下载不存在的文件文件浏览交互实现 实现中的要害概念共享文件夹(root) 服务端启动时指定的共享文件夹门路(服务零碎中的门路)申请门路(req) 文件 / 文件夹 在服务端上绝对共享文件夹的门路绝对路径 AbsPath = root + "/" + req根底函数定义char *GetAbsPath(const char *relative, const char *root) 拼接 root 和 relative, 返回绝对路径,返回值需开释 (free)int isDotPath(const char *path) 判断 path 是否为非凡门路 "." 或 ".."int GetEntryCount(const char *path) 返回 path 门路下的 (文件 + 文件夹)总数编程试验:根底函数实现static char *GetAbsPath(const char *relative, const char *root){ int reLen = strlen(relative); int rootLen = strlen(root); char *ret = malloc(reLen + rootLen + 2); if (ret) { strcpy(ret, root); if ((relative[0] == '/') && (ret[rootLen-1] == '/')) ret[rootLen - 1] = 0; if ((relative[0] != '/') && (ret[rootLen-1] != '/')) strcat(ret, "/"); strcat(ret, relative); } return ret;}static int IsDotPath(const char *path){ int ret = -1; if (path) { ret = (strcmp(path, ".") == 0) || (strcmp(path, "..") == 0); } return ret;}static int GetEntryCount(const char *path){ int ret = -1; DIR *dirp = opendir(path); if (dirp != NULL) { struct dirent *dp = NULL; ret = 0; while ((dp = readdir(dirp)) != NULL) { if (!IsDotPath(dp->d_name)) { ret ++; } } } closedir(dirp); return ret;}要害数据结构定义enum { TypeAll = 0x00, TypeDir = 0x04, TypeFile = 0x08};typdef struct { const int length; RowInfo data[];}FileEntry;typedef struct { char link[2048]; char name[255]; char type[32]; char size[32]; char time[32];}RowInfo;要害函数定义int MakeEntryItem(RowInfo *item, struct dirent *dp, const char *ap, const char *req); ...

June 8, 2023 · 5 min · jiezi

关于c++:C面试八股文C中函数的参数应该传值还是传引用

某日二师兄加入XXX科技公司的C++工程师开发岗位第8面: 面试官:C++中,函数的参数应该传值还是传援用? 二师兄:要看参数的用处。如果是出参,必须传援用。如果是入参,次要思考参数类型的大小,来决定传值还是传援用。 面试官:为什么不应用指针? 二师兄:传指针也称之为传援用(pass by refereence)。然而在C++中不举荐应用指针,因为指针须要判断是否位空,而援用则无需放心。 面试官:入参传值还是传援用有什么规范吗? 二师兄:没有规范吧。个别参数类型大小大于16字节(64位操作系统)时,传援用成果要好于传值。 面试官:为什么? 二师兄:因为传值相当于拷贝结构,当变量的类型尺寸大于16字节时,拷贝结构所耗费的工夫大于解援用。此时传援用收益更高。 面试官:你晓得函数参数传递的过程中,寄存器起什么作用吗? 二师兄:额。。理解过一些。个别简略的数据类型,能够通过寄存器传递。而对于结构图和类则应用是通过堆栈传递参数。当然不同的编译器对此实现不尽相同。 面试官:那么你晓得什么是cdel、stdcall、fastcall、thiscall吗? 二师兄:据说过,不是很理解。。 面试官:好的,回去等告诉吧。 今日二师兄的体现比较稳定,只有最初一问没有答复上来: 你晓得什么是cdel、stdcall、fastcall、thiscall吗?这些都是C++中的函数调用约定。它们决定了函数参数的传递形式和堆栈的清理形式。 cdecl是默认的调用约定,它将参数依照从右到左的程序顺次压入堆栈中,由调用者负责清理堆栈。stdcall将参数依照从右到左的程序顺次压入堆栈中,由被调用函数负责清理堆栈。fastcall将前两个整型或指针参数存储在寄存器中,其余参数依照cdecl约定压入堆栈中。thiscall是用于成员函数的调用约定,它将this指针作为隐式参数传递,并将其存储在寄存器或堆栈中,其余参数依照cdecl约定压入堆栈中。须要留神的是,这些约定可能因编译器和平台的不同而不同。 好了,今日份面试到这里就完结了,小伙伴们,对于明天二师兄的面试,能打几分呢? 关注我,带你21天“精通”C++!(狗头)

June 7, 2023 · 1 min · jiezi

关于c++:C面试八股文static和const的关键字有哪些用法

某日二师兄加入XXX科技公司的C++工程师开发岗位第7面: 面试官:C++中,static和const的关键字有哪些用法? 二师兄:satic关键字次要用在以下三个方面:1.用在全局作用域,润饰的变量或者函数为动态的,限度在本文件内应用。2.办法内润饰润饰动态局部变量,在第一次拜访的时候初始化。3.内类润饰成员函数和成员变量,此函数或变量由类持有,而非类的对象持有。 二师兄:const关键字次要也有三个用处:1.润饰函数参数,则在函数外部不能够批改此参数。2.润饰类的成员办法,外表此办法不会更改类对象的任何数据。3.润饰变量,表明变量不能够被修该。 面试官:当初两个指针,一个是 const int*,另一个是int * const,两者有什么区别? 二师兄:这要要看const和* 的地位,const在前称为常量指针,const在后称为指针常量。常量指针的指针局部可变,指针指向的内容不可变。指针常量则相同,指针指向的内容可变,指针不可变。 面试官:嗯,那么你晓得顶层const和底层const吗? 二师兄:额。。。不晓得。。。 面试官:晓得constexpr关键字的作用吗? 二师兄:理解一些。constexpr关键字润饰的变量具备编译器求值的性能。润饰的函数是否在编译器求值要取决于传入的参数是不是编译器确定的,这属于元编程的领域。 面试官:嗯,那你晓得consteval和constinit这两个关键字的作用吗? 二师兄:额。。。理解过一些,遗记了。 面试官:好的,回去等告诉吧。 让咱们来复盘一下今日二师兄的体现: const在前称为常量指针,const在后称为指针常量。这里的表述仁者见仁智者见智。然而在赫赫有名的《C++ Primer Edition 5》中文版中,const int* 被称为指向常量的指针,而int* const则被称为常量指针。这种表述更容易了解两种指针的差别。 你晓得顶层const和底层const吗?这里的顶层const和底层const概念次要是为了辨别const润饰的是变量自身还是变量指向的内容。 int i = 42;const int ci = 42;//顶层constconst int* pi = &i; //磁层const,因为const润饰的是i所在的地址,不能通过pi去批改i,然而能够批改piint* const pi2 = &i;//顶层const,因为pi2无奈批改const int& ri = i; //底层const,不能通过ri批改i在传递参数时,顶层const能够被疏忽,而底层const不能被疏忽。 你晓得consteval和constinit这两个关键字的作用吗?还记得constexpr是否在编译时求值要取决于传入的参数吗?如果传入的参数是编译时确定的,constexpr函数就会在编译时求值,反之则会在运行时求值。 constexpr int add(int a, int b){ return a+b;}constexpr int sum1 = add(1,2); //编译时求值int a = 1, b = 2;int sum2 = add(a,b); //运行时求值当应用consteval润饰函数和变量时,如果不能在编译时求值,则编译谬误。 ...

June 6, 2023 · 1 min · jiezi

关于c:Linux网络开发必学教程29动态创建交互页面

问题:如何创立浏览器中的文件展现页面?再论前端页面 交互页面剖析动态局部 表格,页面构造动静局部 文件浏览门路 (Path)文件列表(Table)"<!DOCTYPE html>""<html>"" <head>"" <meta charset=\"utf-8\">"" <title>D.T.Software</title>"" <head>"" <body>"" <h1>DT4SW Http File Server</h1>"" <hr/>"" <h3>Path: %s</h3>"" %s"" <body>""<html>"文件列表剖析动态 表格题目行表格列表构造动静局部 表格行数据"<table border=\"1\" width=\"100%\">";" <tr>"" <th>File Name</th><th>File Type</th><th>File Size</th><th>Modify Time</th>"" </tr>"" <td><a href=\"%s\">%s</a></td><td>%s</td><td>%s</td><td>%s</td>"" </tr>""</table>"文件列表接口函数及数据结构Table *CreateTable();Table *InsertRow(Table *table, RowInfo *info);char *ToTableString(Table *table);void FreeTable(Table *table);typedef void Table;typedef struct { char link[2048]; char name[255]; char type[32]; char size[32]; char time[32];}RowInfo;解决方案CreateTable() 从堆空间创建表格题目行,并作为初始表格数据返回InsertRow(table, info) 将 info 中的字符串进行表格行格式化,并增加到 table 开端ToTableString(table) 将 table 表格数据格式化为 HTML 字符串,并返回表格动态创建要害代码if (table && info) { char *t = table; int len = strlen(t); char *buf = malloc(strlen(ROW_FORMAT) + sizeof(*info)); if (buf) { sprintf(buf, ROW_FORMAT, info->link, info->name, info->type, info->size, info->time); ret = realloc(t, len + strlen(buf) + 1); ret = ret ? (strcpy(ret + len, buf), ret) : t; } else { ret = t; } free(buf);}页面动态创建代码char *ToPageString(const char *path, char *ts){ char *ret = NULL; if (path && ts && (ret = malloc(strlen(PAGE_FORMAT) + strlen(path) + strlen(ts) + 1))) { sprintf(ret, PAGE_FORMAT, path, ts); } return ret;}编程试验:动态创建交互页面main.c ...

June 5, 2023 · 3 min · jiezi

关于c++:C面试八股文如何在堆上和栈上分配一块内存

某日二师兄加入XXX科技公司的C++工程师开发岗位6面: 面试官: 如何在堆上申请一块内存? 二师兄:罕用的办法有malloc,new等。 面试官:两者有什么区别? 二师兄:malloc是向操作系统申请一块内存,这块内存没有通过初始化,通常须要应用memset手动初始化。而new个别随同三个动作,向操作系统申请一块内存,并执行类型的默认构造函数,而后返回类的指针。 面试官:嗯,那你晓得calloc和realloc吗? 二师兄:calloc比malloc多做了一步,就是把申请的内存初始化成0。而realloc则能够扭转以后指针所指向的内存块的大小。 面试官:好的。那么你晓得这些api/操作符失败会产生什么吗? 二师兄:malloc/calloc/realloc失败会返回NULL,而new失败则会抛出异样。 面试官:有没有让new失败不抛出异样的办法? 二师兄:如同有,然而我不记得了。。。 面试官:没关系。。。咱们都晓得new和delete成对呈现,new[]和delete[]也是成对呈现,那么我想问,如果应用new[]创立的对象用delete开释了会产生什么?为什么? 二师兄:额。。。内存透露?对,会产生内存透露。因为内存没有被开释。 面试官:好的。咱们都晓得C++中的内存治理是一个比拟麻烦的事件,当初有个需要,须要在程序中记录被动申请的内存和被动开释的内存,以确保没有产生内存透露。有什么好的办法吗? 二师兄:能够重载new和delete运算符。 面试官:如何重载new和delete运算符? 二师兄:我得查一下材料,这个重载用的很少。。。 面试官:(笑)好吧,最初一个问题,咱们下面始终在探讨堆中的内存的调配和开释,请问一下,如果在栈上调配一块固定的内存?栈中的内存如何开释? 二师兄:额。。。(思考)应用 char[size] ? 应该不须要手动开释。 面试官:好的,回去等告诉吧。 对于二师兄的体现,小伙伴们能给打几分呢?咱们先看看二师兄在面试中体现不太好的中央: 面试官:有没有让new失败不抛出异样的办法?在C++中咱们能够应用以下办法使得new运算符不抛出异样, int* p = new (std::nothrow) int(42);if(p == nullptr){ //调配失败}这个个性须要C++11反对。 再看下一个问题: 如果应用new[]创立的对象用delete开释了会产生什么?肯定会产生内存透露吗?答案是,不肯定。这取决于类型T。咱们先看第一种状况: class Foo{public: Foo():num_(42){}private: int num_;};Foo* pf = new Foo[1024];delete pf;当类型T没有治理资源时,delete pf会把整个申请的1024个Foo所占用的内存全副归还给操作系统,此时并没有内存透露。再看下一种状况: class Foo{public: Foo():num_(new int(42)){} ~Foo(){delete num_;}private: int* num_;};Foo* pf = new Foo[1024];delete pf; 此时会造成内存透露,起因很简略。在执行delete[]时,首先逆序执行每个元素的析构函数,而后再把整块内存归还给操作系统。而delete只会把内存还给操作系统,没有执行析构函数。当类没有资源须要治理时,执行与不执行析构函数都无关紧要,然而当类中须要治理资源时,析构函数的执行就至关重要了。 如何重载new和delete运算符?#include <iostream>#include <cstdlib>#include <map>struct MemoryInfo { size_t size; const char* file; int line;};std::map<void*, MemoryInfo> memoryMap;void* operator new(size_t size, const char* file, int line) { void* ptr = std::malloc(size); memoryMap[ptr] = {size, file, line}; return ptr;}void operator delete(void* ptr) noexcept { auto it = memoryMap.find(ptr); if (it != memoryMap.end()) { std::free(ptr); memoryMap.erase(it); }}#define new new(__FILE__, __LINE__)int main() { int* p = new int(42); for (const auto& [ptr, info] : memoryMap) { std::cout << "Memory allocated at " << ptr << " with size " << info.size << " in file " << info.file << " at line " << info.line << std::endl; } delete p; for (const auto& [ptr, info] : memoryMap) { std::cout << "Memory allocated at " << ptr << " with size " << info.size << " in file " << info.file << " at line " << info.line << std::endl; } return 0;}最初一个问题: ...

June 5, 2023 · 2 min · jiezi

关于c:Linux网络开发必学教程28浏览器请求响应实现

文件服务器架构 职责定义主线程 命令行输出,管理员可管制服务端工作状态监听线程 服务端启动后对客户端连贯进行监听的工作环境通信线程 客户端连贯胜利后与服务端的数据交互环境主线程int main(int argc, char *argv){ if (argc >=2) { DIR *dir = opendir(argv[1]); if (dir != NULL) { close(dir); Run(argv[1]); } } printf("Can not launch File Server, need a valid director as root.\n"); return 0;}if (*line) { char *cmd = FormatByChar(line, ' '); // 此处的作用次要为去除前后空格 int done = 0; for (i=0; i<DIM(g_handler); ++i) { if (strcmp(g_handler[i].cmd, cmd) == 0) { g_handler[i].handler(cmd); done = 1; break; } } if (!done) { printf("\'%s\' can NOT be parser!\n", cmd); } free(cmd);}交互流程一 ...

June 4, 2023 · 4 min · jiezi

关于c:Linux网络开发必学教程27文件服务器可行性分析

需要剖析服务端启动时指定某本地文件夹作为网络共享文件夹共享文件夹中的所有文件及子文件夹均可被客户端拜访应用浏览器作为客户端,在浏览器中可“看到”所有共享文件用户可在浏览器中将指标文件下载到本地服务端可暂定服务,但不影响正在下载指标文件的客户端技术可行性剖析服务端网络通讯 基于 Http 协定与客户端浏览器通信可应用 tcp socket 实现对 Http 协定的反对服务端文件操作 获取文件夹中的所有文件及子文件夹返回文件列表 或 返回文件内容零碎概要设计 基础设施Socket - Http 协定以 TCP 协定为底座Thread - 同时对多个客户端服务(申请响应)File - 文件夹信息读取,文件属性读取,文件数据读取基础设施一 (Socket)思考:是否应用课程中的网络通讯框架作为基础设施?答:临时不能 课程中通信框架的服务端基于 select 机制,即: 服务端工作时会导致程序阻塞 (程序无奈持续向下执行)每次只服务一个客户端(当服务工夫过长,会影响其它服务端通信)文件服务器工作模型 网络通讯框架改良计划新增服务端函数 TcpClient *TcpServer_Accept(TcpServer *server); 阻塞函数,调用后始终期待客户端连贯返回与客户端通信的 TcpClient 构造体返回的 TcpClient 构造体互相独立,并且独立于服务端TcpClient *TcpServer_Accept(TcpServer *server){ TcpClient *ret = NULL; if (server) { Server *s = (Server*)server; struct sockaddr_in caddr = {0}; socklen_t asize =sizeof(caddr); int fd = accept(s->fd, (struct sockaddr*)&caddr, &asize); if (fd > -1) { ret = TcpClient_From(fd); if (!ret) close(fd); } } return ret;}基础设施二 (Thread)过程:应用程序的一次加载执行(零碎进行资源分配的根本单位)线程:过程中的程序执行流 ...

June 4, 2023 · 5 min · jiezi

关于c++:C面试八股文structclass和union有哪些区别

某日小二加入XXX科技公司的C++工程师开发岗位5面: 面试官:struct和class有什么区别? 小二:在C++中,struct和class的惟一区别是默认的访问控制。struct默认的成员是public的,而class的默认成员是private的。 面试官:struct、class和union有哪些区别? 小二:union和struct、class在内存布局上不同。union实例的所有成员共享一块内存,这块内存的大小等同于union中成员尺寸最大的一个。 面试官:你能列举一下union适宜应用的场合吗? 小二:额。。(我哪晓得啊,素来没用过。。) 面试官:好的,回去等告诉吧。 对于这三个关键字,置信小伙伴们对前两个关键字并不生疏,然而对于union可能用的会少一些。 union最开始的呈现是为了解决内存占用的问题。例如你须要存储一个IP地址,然而你并不知道IP的类型,你须要: struct IP{ char ipv4[4]; char ipv6[16];}; //sizeof(IP) = 20对于一个IP地址,要么是IPV4要么是IPV6,IPV4和IPV6是互斥的,那么必定有一块空间是被节约了。此时咱们的union就派上用场了: union IP{ char ipv4[4]; char ipv6[16];}; //sizeof(IP) = 16第二种用法是能够通过union判断大小端。(当然也能够通过其余办法) union End{ unsigned char uc; unsigned short us;};bool is_little_end(){ End end{0}; end.us = 1; return end.uc;}小端模式的意思是,低位放在低内存,高位放在高内存。而大端正好相同。当咱们给us赋值1时,如果是大端,内存中的数据应该是这样的:0x00,0x01,这时候如果取uc的值,只能取到0x00。如果是小端,内存中的数据应该是0x01,0x00,此时取到的uc的值是0x01,返回1(true)。 小伙伴们,你还晓得union的其余用法吗? 关注我,带你21天“精通”C++!(狗头)

June 4, 2023 · 1 min · jiezi

关于c:Linux网络开发必学教程26Web-前端开发基础

对于 Http 应用程序基于 Http 的应用程序实质上是一种非凡的 C/S 模型利用Http 应用程序的底座是 TCP 协定(即:socket 可实现利用)常见的 Http 客户端为浏览器,服务端为 Web 服务器简略了解:Http 应用程序 ←→ TCP 应用程序 + 文本处理应用程序值得思考的问题浏览器为什么能成为 “万能客户端” ?什么是 HTML ?HTML 指的是超文本标记语言:Hyter Text Markup LanguageHTML 不是一种编程语言,而是一种标记语言标记语言是一套标记标签(markuo tag) HTML 应用标记标签来形容网页HTML 文档蕴含了 HTML 标签及文本标记能容HTML 文档也叫做 Web 页面HTML 文本示例 HTML 中的标签HTML 标签通常被称为 HTML TagHTML 标签是由尖括号突围的管检测,比方:<html>HTML 标签通常是成对呈现的,比方 <b> 和 </b>标签对中的第一个标签为开始标签,第二个标签是完结标签开始标签和完结标签也被称为凋谢标签和闭合标签HTML 中的“分区” 问题一:如何管制 HTML 页面中的字符大小HTML 题目是通过 <h1> - <h6> 标签来定义的(字符由大到小)HTML 段落是通过标签 <p> 来定义的 (段落主动换行)HTML 应用标签 <b> 与 <i> 对输入的文本进行格局HTML 应用 <hr> 标签在 HTML 页面中创立水平线<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>DT4SW</title></head><body> <h1>字符管制示例</h1> <p><b>hr 标签定义水平线</b></p> <hr/> <h2>这是段落1。</h2> <hr/> <h4>这是段落2。</h4> <hr/> <h6>这是段落3,<br/>换行<br>再换一行</p></h6></body></html> ...

June 4, 2023 · 2 min · jiezi

关于c++:C面试八股文memsetmemcpy和strcpy的区别是什么

某日小二加入XXX科技公司的C++工程师开发岗位4面: 面试官:memset、memcpy和strcpy的区别是什么? 小二:memset用于将一块内存设置为特定的值, memcpy用于将一块内存从一个地位复制到另一个地位, strcpy用于将一个字符串从一个地位复制到另一个地位。 面试官:嗯,不错。那么你晓得这三个函数在应用时要留神哪些问题吗? 小二:呃。。。 面试官:好的,回去等告诉吧。 这三个函数在C/C++开发中用到的频率比拟高。 memset函数罕用于POD类型对象的初始化,个别第二个参数都是0,第三个参数是这段内存的长度。 memcoy函数须要留神的点是,函数传入的源地位和指标地位不能有重叠,否则这种操作引发的后果无奈预知。如果你不可能确定传入的源地位和指标地位是否存在重叠,那么能够应用memmove函数代替memcoy。 strcpy存在另一个问题,那就是源字符串的长度可能大于指标区域的长度,导致指标区域内存被超写,造成不可预知的谬误。当然也能够通过应用strncpy函数传入指标区域的大小-1,如果源字符串的长度小于指标区域的大小-1,则全副拷贝,否则最多只拷贝指标长度-1的内容,保障指标字符串以0结尾。 小伙伴们,如果你是小二,你能比小二答复的更好吗? 关注我,带你21天“精通”C++!(狗头)

June 3, 2023 · 1 min · jiezi

关于c:Linux网络开发必学教程25Http-协议基础

Http 是什么?Http 作为 WWW 的重要组成部分被提出(World Wide web)而过后的 WWW 是为了帮忙研究者更好的进行常识共享根本理念:文档之间的互相关联造成超文本,最终连城互相参阅的 WWWHttp (Hyper Text Transfer Protocol)用于定义文档之间如何跳转,即:文档传输协定 Http 是什么?Http 是位于 TCP/IP 之上的应用层通信协定 Http 世界中的“重要角色”域名解析服务器 (DNS - Domain Name System)DNS 是位于 TCP/IP 之上的应用层协定DNS 提供域名到 IP 地址之间的解析服务主机 IP 地址查找过程 域名 VS 网络地址每一台网络中的主机都有一个地址(惟一标识,即:IP 地址)为了不便记忆,可通过域名拜访网络上的指标主机域名是字母与数字的组合,如:dt4sw.comDNS 可通过域名查找 IP 地址,也可逆向从 IP 地址反查域名初见 URI 和 URLURI : 对立资源标识符(Uniform Resource Identifier) 由某种规定定义的资源标识符通过字符串标识资源(即:URI 的表现形式为字符串)例: dev:app:py4oh:fileshttp://dt4sw.com/index.htmlmailto:support@dt4sw.comtelnet://193.168.3.11tel:+86-159xxx0426URL 不限于标识互联网资源,它能够用于定义所有资源的标识符深刻了解 URI 与 URLURL 是一种非凡的 URI, 它是 URI 的一种利用模式URI 不肯定是 URL,而 URL 肯定是 URIURL 是相对的,提供拜访到确切资源的具体门路(全网惟一)URL 既有相对性又有绝对性 ...

June 3, 2023 · 1 min · jiezi

关于c:Linux网络开发必学教程24物联网服务模块实现非必要

笔者无对应硬件开发板,对波及硬件操作局部的代码不做全副开展。(不影响主线了解) 问题:服务模块如何获取实在环境信息?外设简介 设施驱动开发根底GPIO GPIO 即: General-Purpose Input/Output, 通用型输入输出在硬件设施上,GPIO 通常体现为引脚 (Pin), 输入为高电平或低电平程序设计中,可通过代码管制指定 GPIO 的输入,或接管内部输出GPIO 是硬件与外部设备的接口,罕用于对外部设备进行管制GPIO 信号输入 当 GPIO 作为输入应用时,输入的电信号为高电平(1)或着低电平(0),因而,只有在电路上稍加设计就能够接入外设(如:LED,电动机,等),并通过程序控制外设的状态GPIO 利用形式根底性能 仅应用 GPIO 引脚性能对外输入管制信息(0 或 1)复用性能 通过 GPIO 根底性能实现的通信形式(如:I2C)GPIO 根底性能示例#include "iot_gpio.h"#include "hi_io.h"IoTGpioInit(14);IoTGpioSetFunc(14, HI_IO_FUNC_GPIO_14_GPIO);IoTGpioSetDir(14, HI_GPIO_DIR_OUT);int Service_SetLight(int on){ return (IotGpioSetOutputVal(14, on) == 0);}什么是 I2C?I2C 即:inter - integrated Circuit, 一种两线式串行总线I2C 罕用于链接微信控制器及其外围设备(如:用于连贯传感器)I2C 可通过两个 GPIO 引脚实现物理连贯及数据通讯 如:GPIO0 对应 I2C_SDA : I2C 数据传输线GPIO1 对应 I2C_SCL : I2C 时钟信号线深入浅出 I2C 通信I2C 总线上能够挂载一个设施和多个从设施主设施负责调度总线,决定某个工夫和其中一个从设施通信每个从设施在 I2C 总线上都有惟一的地址主设施寻址时,8 位数据中高 7 位是从设施地址,最低位示意读写每次数据通讯,主从设施之间都会发送起始和完结信号大道至简:对于 I2C 利用的了解I2C 的实质是两根对于数据传输的连线(微控制器 <--> 传感器)I2C 编程是非凡的 GPIO 编程 (GPIO 配置后进行数据读写)开发板上的 I2C 与集成外设固定连贯(如:温湿度传感器)I2C 利用的终极体现只是简略的数据读写I2C 利用示例uint8_t send_data[1] = {0};send_data[0] = 0x01;IoTI2CWrite(1, (BH175_Addr<<1)|0x00, send_data, 1);usleep(100000);send_data[0] = 0x10;IoTI2CWrite(1, (BH175_Addr<<1)|0x00, send_data, 1);uin8_t recv_data[6] = {0};IoTI2CRead(1, (BH175_Addr<<1)|0x01, recv_data, 2);将来可做的扩大提供更多不同类型的服务(如,图像采集与辨认服务)提供设施被动服务模式及服务联动模式开发手机客户端,通过手机终端应用服务。。。

June 3, 2023 · 1 min · jiezi

关于c:Linux网络开发必学教程23客户端服务端交互实现

问题:客户端业务逻辑如何实现?与服务设施交互细节如何设计?客户端业务逻辑实现用户输出解决 字符串空格解决,宰割获取命令与参数服务信息处理 字符串预处理,宰割获取服务命令存储服务命令与设施地址之间的映射(命令字符串 地址字符串)客户端业务逻辑实现 - 用户输出解决typedef struct { const char *cmd; char *(*handler)(const char *);}Handler;static Handler g_handler[] = { {"query", Query_Handler}, {"touch", Touch_Handler}};if (*line) { char **arg = Malloc2d(char, 2, BUF_SIZE); int i = 0; int r = DivideBy(line, ' ', arg, 2, BUF_SIZE); if (i=0; i<DIM(g_handler); ++i) { if (strcmp(g_handler[i].cmd, arg[0]) == 0) { g_handler[i].handler(arg[1]); break; } } Free2d(arg);}服务端逻辑实现查问音讯解决 接管播送,并回复 UDP 音讯服务命令解决 接管 TCP 连贯,通过 申请 - 响应 的模式进行服务UDP 响应模式设计static void Query_Handler(UdpPoint *udp, Message *msg, const char *remote, int port){ Message *resp = Message_New(TYPE_RESPONSE, 0, 0, 0, NULL, DESC_SIZE + ADDR_SIZE + USAGE_SIZE); if (resp) { char ip[16] = {0}; get_localip("ens33", ip); strncpy(resp->payload, Service_GetDesc(), DESC_SIZE); strncpy(resp->payload + DESC_SIZE, ip, ADDR_SIZE); strncpy(resp->payload + DESC_SIZE + ADDR_SIZE, Service_GetUsage(), USAGE_SIZE); UdpPoint_SendMsg(udp, resp, remote, port); } free(resp);}服务模块设计#ifndef LOCAL_SERVICE_H#define LOCAL_SERVICE_Htypedef struct { float illumination; float humidity; float temperature; int light;}SvrData;void Service_Init(void);const char *Service_GetDesc(void);const char *Service_GetUsage(void);SvrData Service_GetData(void);int Service_SetLight(int on);#endif // LOCAL_SERVICE_HTCP 响应模块设计Message *msg = TcpClient_RecvMsg(client);if (msg && (msg->type == TYPE_TOUCH)) { static char buf[128] = {0}; SvrData ed = Service_GetData(); free(msg); // provided by service module msg = Message_New(TYPE_RESPONSE, 0, 0, 0, buf, strlen(buf) + 1); // format data according to message payload string}else { const char *message = "Invalid touch request"; free(msg); msg = Message_New(TYPE_RESONSE, 0, 0, 0, message, strlen(message) + 1);}TcpClient_SendMsg(client, msg);free(msg);客户端响应接管msg = TcpClient_RecvMsg(client);if (msg && (msg->type == TYPE_RESPONSE)) { printf("%s\n", msg->payload);} else { printf("Invalid status from service ...\n");}free(msg);编程试验: 客户端服务端交互实现课后思考服务模块如何获取真是环境信息 ...

June 3, 2023 · 2 min · jiezi

关于c++:emacs-CC-develop-configuration-file

;;; package --- Summary(require 'package);;(setq package-archives '(("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")));;(add-to-list 'package-archives;; '("melpa" . "http://melpa.org/packages/") t)(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/"))(package-initialize) (when (not package-archive-contents) (package-refresh-contents));;(unless (package-installed-p 'use-package) (package-install 'use-package)) ;(require 'use-package);(setq use-package-always-ensure t) ;;(use-package irony;; :defer t;; :diminish irony-mode;; :init;; (add-hook 'c++-mode-hook 'irony-mode-when-supported);; (add-hook 'c-mode-hook 'irony-mode-when-supported);; :config;; (irony-cdb-autosetup-compile-options)) (add-to-list 'load-path "~/_emacs/custom") ;;(require 'setup-ggtags);;(require 'setup-cedet) (setq emacs_list_dir "~/_emacs/")(add-to-list 'load-path emacs_list_dir);;(add-to-list 'load-path "~/_emacs/ecb")(add-to-list 'load-path "~/_emacs/emacs-eclim")(add-to-list 'load-path "~/_emacs/icicles")(add-to-list 'load-path "~/_emacs/CodePilot");;(add-to-list 'load-path "~/_emacs/cedet-1.1");;(add-to-list 'load-path "~/_emacs/cedet-1.1/common");;(add-to-list 'load-path "~/_emacs/cedet-1.1/speedbar");;(add-to-list 'load-path "~/_emacs/cedet-1.1/eieio");;(add-to-list 'load-path "~/_emacs/cedet-1.1/semantic");;(add-to-list 'load-path "~/_emacs/cedet-1.1/semantic/bovine");;(add-to-list 'load-path "~/_emacs/cedet-1.1/ede");;(add-to-list 'load-path "~/_emacs/cedet-1.1/srecode")(add-to-list 'load-path "~/_emacs/yasnippet")(add-to-list 'load-path "~/_emacs/fuzzy-el")(add-to-list 'load-path "~/_emacs/popup-el")(add-to-list 'load-path "~/_emacs/auto-complete")(add-to-list 'load-path "~/_emacs/company-mode")(add-to-list 'load-path "~/_emacs/auto-complete-clang")(add-to-list 'load-path "~/_emacs/pos-tip")(add-to-list 'load-path "~/_emacs/window-numbering")(add-to-list 'load-path "~/_emacs/highlight-parentheses");;(add-to-list 'load-path "~/_emacs/python");;(add-to-list 'load-path "~/_emacs/git-emacs")(add-to-list 'load-path "~/_emacs/emacs-htmlize")(add-to-list 'load-path "~/_emacs/imenu-list") ...

June 3, 2023 · 8 min · jiezi

关于c++:C算法基础2暴力枚举的方法论与优化技巧-大力出奇迹

暴力枚举法(Brute Force)是许多刚接触编程或算法的选手最容易上手,也最显著的算法。尽管暴力枚举往往效率极低,然而能够很快地解决一些问题。 本文将介绍暴力枚举法的办法和优化技巧。留神本文中许多名字并非业余学名,而是我本人定义的,请不要过于纠结。 作者:Eriktse 简介:19岁,211计算机在读,CCPC全国赛金牌,ICPC区域赛银牌服役选手力争以通俗易懂的形式解说编程和算法!❤️欢送关注我,一起交换C++/Python算法。(优质好文继续更新中……)欢送加群一起游玩~QQ群:6002401501.确定解的模式(枚举变量)在进行暴力之前,咱们须要剖析出解的模式,比方要求满足条件的三元组的个数,咱们就枚举所有三元组,查看哪些满足条件。比方咱们要求满足条件的区间的个数,就能够枚举所有的二元组(示意左右端点)。 有些题目解的模式可能不太惟一,须要抉择适合的模式,对于不同的模式抉择不同的枚举办法。比方枚举子集,能够用循环,也能够用dfs,有时候在可能剪枝的状况下,dfs会比循环间接枚举子集快很多。 2.抉择枚举办法常见的枚举办法有间接枚举法和递归枚举法,依据题目不同,有时候也可能有用一些构造方法来进行枚举。 常见的间接枚举(循环)不会超过4层循环,且循环层数固定。 如果你发现循环层数是可变的,往往就要用递归枚举,比方你要枚举所有长度小于等于$n$的一个货色,就须要用到递归。 3.判断函数在枚举出一个解后,咱们须要判断其是否是可行解,于是咱们要写一个判断函数。 这个判断函数能够依据你枚举出的一个解,来判断这个解是否可能。 举个例子咱们要求范畴$[1, n]$的所有质数。 那么咱们解的模式就是一个整数,于是咱们遍历解空间$x \in [1, n], x \in Z^+$的所有解,说人话就是$[1, n]$的所有整数,而后编写判断函数,用于判断一个解$x$是否是可行解,即判断一个数字$x$是否是质数,并执行操作:[YES->将解退出到解集中,NO->舍弃]。 例题ETOJ 1014: straax'aks Array链接:http://oj.eriktse.com/problem.php?id=1014 这道题看数据范畴,显著反对$O(n^3)$,所以能够大胆地暴力,枚举所有$i < j < k$的三元组,并$O(1)$判断是否满足条件即可。 代码: #include <bits/stdc++.h>using namespace std; using ll = long long;const ll N = 1e6 + 9, inf = 8e18;ll a[N]; bool check(ll a, ll b, ll c, ll m){ return (a + b + c) * (a ^ b ^ c) >= m;} void solve(){ int n, m;cin >> n >> m; for(int i = 1;i <= n; ++ i)cin >> a[i]; ll ans = 0; for(int i = 1;i <= n; ++ i) for(int j = i + 1;j <= n; ++ j) for(int k = j + 1;k <= n; ++ k) if(check(a[i], a[j], a[k], m)) { ans ++; //cout << a[i] << ' ' << a[j] << ' ' << a[k] << '\n'; } cout << ans << '\n';} signed main(){ ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int _ = 1; while(_ --)solve(); return 0;}ETOJ 1016: 全排列链接:http://cdn.oj.eriktse.com/problem.php?id=1016 ...

June 2, 2023 · 2 min · jiezi

关于c++:C算法基础1基于比较的排序与桶排序-不要只会写冒泡了

在算法比赛中,有两种排序较为常见,第一种是$O(nlogn)$的排序,个别是基于比拟的排序,第二种是桶排序。两种办法各有优劣,选取适合的排序办法对于解题十分重要。 本文次要解说这两种排序办法,不要只会写冒泡排序了! 作者:Eriktse 简介:19岁,211计算机在读,CCPC全国赛金牌,ICPC区域赛银牌服役选手力争以通俗易懂的形式解说编程和算法!❤️欢送关注我,一起交换C++/Python算法。(优质好文继续更新中……)欢送加群一起游玩~QQ群:600240150基于比拟的排序这里不解说疾速排序的外部原理,咱们只须要晓得在什么场合应用即可。 在C++中,个别不须要本人写疾速排序,用STL中的sort()函数即可(具体的实现办法不肯定是疾速排序),即工夫复杂度为$O(nlogn)$的排序办法。 应用sort()函数前须要引入头文件#include <algorithm>。在vector中,应用sort(v.begin(), v.end())进行排序,在C数组中用sort(a, a + n)进行排序。 个别在数据范畴$1 times 10 ^ 6$以内能够用疾速排序,且元素的大小个别很大。 桶排序当元素的大小比拟小的时候,能够采纳桶排序,其工夫复杂度为$O(n)$,是一个线性复杂度。 它利用的是值域小的个性,开一个数组记录数字呈现的次数,而后下标主动就排序了。 在某些状况下,用桶的思维能够优化复杂度。 例题luogu P1177 【模板】排序链接:https://www.luogu.com.cn/problem/P1177 本题数据范畴反对应用基于比拟的排序,所以间接是应用即可。 <bits/stdc++.h>头文件蕴含了<algorithm>。代码: #include <bits/stdc++.h>using namespace std;signed main(){ ios::sync_with_stdio(0); int n;cin >> n; vector<int> a(n); for(int i = 0;i < n; ++ i)cin >> a[i]; sort(a.begin(), a.end()); //留神上面这句,前面这部分意思是 //当i的迭代器和a.back()迭代器雷同时就换行 for(auto &i : a)cout << i << " n"[&i == &a.back()]; return 0;}luogu P1271 【深基9.例1】选举学生会链接:https://www.luogu.com.cn/problem/P1271 本题须要采纳桶排序,因为基于比拟的排序办法最小复杂度为$O(nlogn)$,可能无奈满足本题需要。 代码: #include <bits/stdc++.h>using namespace std;const int N = 2e6 + 9;int a[N];//a[i]示意数字i呈现的次数signed main(){ ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n, m;cin >> n >> m; for(int i = 1;i <= m; ++ i) { int x;cin >> x; a[x] ++; } for(int i = 0;i <= n; ++ i) { for(int j = 1;j <= a[i]; ++ j) { cout << i << ' '; } } return 0;}

June 1, 2023 · 1 min · jiezi

关于c++:C面试八股文C中指针引用解引用和取地址有什么不同

某日小二加入XXX科技公司的C++工程师开发岗位2面: 面试官:指针、援用、解援用和取地址是C++中的重要概念,请问它们在语法和语义上有所不同? 小二:指针是一个变量,它存储了一个内存地址。 小二:援用是一个别名,它容许应用一个变量的多个名称来拜访同一个内存地位。 小二:解援用是指应用*运算符来拜访指针所指向的内存地位处的值。 小二:取地址是指应用&运算符来获取变量的地址。 指针是一个变量,它存储了一个内存地址。能够应用指针来拜访和批改存储在该地址处的值。指针能够通过&运算符获取变量的地址,也能够通过*运算符解援用指针来拜访该地址处的值。 int x = 10; int* ptr = &x; *// 获取x的地址* *ptr = 20; *// 批改x的值* 援用是一个别名,它容许应用一个变量的多个名称来拜访同一个内存地位。援用能够看作是指针的一种简化模式,它不须要应用*运算符来解援用,也不须要应用&运算符来获取地址。 int x = 10; int& ref = x; *// ref是x的援用* ref = 20; *// 批改x的值* 解援用是指应用*运算符来拜访指针所指向的内存地位处的值。 int x = 10;int* ptr = &x;int y = *ptr; *// 解援用ptr,获取x的值* 取地址是指应用&运算符来获取变量的地址。 int x = 10; int* ptr = &x; *// 获取x的地址* 总的来说,指针和援用都能够用来拜访和批改变量的值,但它们的语法和语义有所不同。指针须要应用*运算符来解援用,而援用不须要。指针能够被从新赋值指向另一个内存地位,而援用一旦绑定到一个变量上就不能再绑定到另一个变量上。解援用和取地址是指针和援用的基本操作,它们能够用来拜访和批改变量的值以及传递变量的地址给函数。 面试官:十分好,那么你晓得援用是怎么实现的吗? 小二:援用的底层实现的具体细节在不同编译器上可能不同,然而有一种办法就是常量指针。同样,常量指针须要在初始化的时候绑定指向的对象,而且在绑定之后不能批改绑定的对象。这和援用的行为合乎。 面试官:能够对援用取地址吗? 小二:能够,取到的地址和对援用绑定的对象取到的地址雷同。 面试官:那么能够对援用解援用吗? (挖坑) ...

June 1, 2023 · 1 min · jiezi

关于c++:C面试八股文C和C有哪些区别

某日小二加入XXX科技公司的C++高级工程师开发岗位1面: 面试官:请问C和C++的区别有哪些? 小二:C++是C的超集。 面试官:还有吗? 小二:... 面试官:面试完结,回去等音讯吧。 小二:淦。 小二的答案对吗? 实际上这句话是有问题的,严格的说,C语言和C++有很多交加,这部分交加占了C语言的大部分,占了C++的小局部。 滞销C++书籍作者侯杰老师曾说过,当咱们议论C++的时候,其实在议论四个方面的货色; 1.面向过程的编程语言2.面向对象的编程语言3.STL(Standard Template Library,规范模板库)4.元编程其中,只有第一条面向过程的编程语言和C语言的定位重合。 那么咱们很容易得出结论,C++独有的性能和个性包含面向对象的编程范式,STL和元编程。那么C中有的,而C++中没有的这部分是什么呢? 次要蕴含一些语法细节的变动,C++在思考到安全性、易用性、性能完整性等一系列问题后的实现与C语言现有的实现不同的中央,以下列出一些,并不是残缺列表: 1.编译器类型大小不同 如C语言的单个字符编译时占用4个字节,而C++只占用一个字节。 如空构造体在C语言中的大小是0,而在C++中的大小是1。 2.类型查看尺度不同 如C语言中的main函数的返回值能够是任何类型,但在C++中main函数的返回值只能是int类型。 如C语言中从void*转换成任意类型的指针,而C++中必须应用强制转换符。 3.关键字雷同但应用不同如const,auto。 那么回到结尾,让咱们从新模仿一编结尾的面试环节: 面试官:请问C和C++的区别有哪些? 小二:C是面向过程的编程语言,而C++不仅是面向过程的编程语言,还是面向对象的编程语言。同时C++蕴含了C中所没有的STL,且C++反对函数是编程/泛型编程/元编程。 面试官:还有吗? 小二:C++号称是C的超集,其实大部分工夫这句话是对的,但还有一些轻微的点C++是不能兼容C语言的,如balabalabala... 面试官:面试完结,请留神放弃手机畅通。 小二:好。 关注我,带你21天“精通”C++!(狗头)

June 1, 2023 · 1 min · jiezi

关于c++:代码级质量技术之基本框架介绍

作者 | CQT&星云团队 一、背景代码级品质技术:顾名思义为了服务质量更好,波及到代码层面的相干技术,特地要指出的是,代码级品质技术不单纯指代码召回技术,如动态代码扫描、单元测试等。 钻研代码级品质技术次要有以下几个方面的起因: 1、随着精准测试等概念的衰亡,对代码覆盖率的依赖逐步减轻,代码插桩的性能、准确性、时效性等都成为业界要解决的难题; 2、随着智能化,尤其是基于危险驱动的测试倒退,对代码的了解须要失去冲破,能力更好的从代码实现中开掘危险、判断危险; 3、在黑盒级别的测试,品质工作者往往是通过对象的返回或外在表象观测对下的异样体现进而发现问题,然而其实可能很多潜在的异样并没有到“肉眼”可观测到的级别而导致问题漏出,这时候就须要有更多的对象更细的运行数据来供品质工作者剖析去发现问题的蛛丝马迹,诸如:内存泄露、性能好转等,所以业界有很多prof、火焰图、asan等偏白盒动静检测问题的技术呈现; 4、代码作为产生理论问题最前沿的阵地,大部分问题都能够归因到某段代码不合理,如果能够在代码级别间接召回问题,无论从仿真复杂度、修复老本、定位老本等均会失去极大改善; 5、代码是工程师交换的舞台,通过对代码级品质技术的钻研和标准,能够促成代码更加的具备鲁棒性和更优质的设计如单测晋升可测性等,也能够促成品质保障人员对代码加深掌控与了解,进而在品质保障各类场合施展关键作用。 从领导品质行为、极大晋升召回问题能力、加强代码鲁棒性、晋升人员对代码的掌控力等多个方面,都能够看出代码级品质技术的要害且不可代替作用,百度品质效力平台于2019年开始关注和投入该方向,在代码了解、代码探针、代码品质技术利用等多个层级多方面进行摸索和落地,接下来的文章中会顺次为大家介绍。 二、代码级品质技术架构要了解代码级品质技术的原理和后续的次要利用场景,首先要了解代码从语言到可执行态的根本过程,上面以C++为例说下根本过程: C++从代码到可执行bin文件,次要分为四个阶段:预处理、编译、汇编和链接。 预处理:解决一些#号定义的命令或语句(如#define、#include、#ifdef等),生成.i文件; 编译:进行词法剖析、语法分析和语义剖析等,生成.s的汇编文件,大家相熟的AST形象语法树就在该过程产生; 汇编:将对应的汇编指令翻译成机器指令,生成二进制.o指标文件; 链接:链接分为两种,动态链接:将动态链接库中的内容间接装填到可执行程序中;动静链接:只在可执行程序中记录与动态链接库中共享对象的映射信息。 代码级品质技术的技术原理,次要是获取到该过程的代码片段数据或植入对应的指标代码,来达到对应的品质指标,如获取片段数据能够用来了解代码判断危险,能够用来指结构化代码构造,供主动生成单元测试和代码检测提供根底数据;如植入对应指标代码,能够用来做插桩(即覆盖率采集)或动态数据采集等。 基于上述介绍与了解,咱们把代码级品质技术划分大范畴为两个档次,两个档次内蕴含多个档次,如下图所示: 大档次一:代码了解,CodeC(Code Comprehend):偏底层技术,基于底层AST等能力、剖析出代码的个性(AST、调用链、依赖等)和危险度,通过API、SDK等形式对外提供根底服务 存储层:次要用来代码编译过程的根底数据和对应的数据存储选型调优等,在这个过程次要难点在于根底工具的选型和过程性能的调优,以达到能够在业务利用的指标;剖析层:剖析层是依靠根底的数据,依据特定的要求,对数据进行结构化的建模,如函数调用链、依赖关系等,做好根底的剖析供下层利用;模型层:用于通过剖析层和根底数据,去训练代码存在的潜在危险或危险偏差(性能问题突出等);API层:通过API、SDK等形式对外提供根底服务。该层会遇到泛滥技术挑战,如要适配不同语言的解析器、编译过程;根底框架进行代码调优;剖析过程数据缺失修复等,是一项十分粗疏且有技术挑战的工作,当然咱们在该过程也会摸索出一些技术教训供大家参考。 大档次二:代码级品质技术利用,Code:次要是依靠代码了解的过程或产出,植入对应的信息,以达到对应的品质指标,这个档次利用场景是要害,因而咱们是以解决问题的指标为导向,对该档次进行细分,所以指标或利用场景的不同会使得该档次的分类会一直减少,目前分为以下四类: CodeQ(Code Quality): 与召回问题相干(智能UT、基于规定的代码缺点检测、基于AI的代码缺点检测、火焰图、ASAN等在个分类);CodeP(Code Probe):与动静插桩相干(ccover、covtool、jacoco、gocov等在这层),次要是往代码外面植入探针获取运行行为数据;CodeH(Code Health):评估代码衰弱度(相似sonarcube等)、代码危险度评估用于决策后续的品质行为;CodeDL(Code defect location):代码缺点定位。上面的章节咱们会散布从第二级的档次,为大家做基本原理和过程介绍,后续还会有系列发文再深刻的介绍对应实现内容。 三、代码了解层介绍代码了解是一个以软件程序为对象,对其外部的运作流程进行剖析,获取相干的常识信息,这些信息能够用于软件开发、软件测试、软件维护等各个阶段,旨在对程序进行性能优化和正确性验证。代码了解罕用的剖析方向有动态剖析、动态分析、非源码剖析3类,然而随着LLM大模型的倒退,咱们也正在钻研模型在代码了解畛域的冲破与利用。 动态剖析:是指在不运行代码的形式下,通过词法剖析、语法分析、控制流、数据流剖析等技术对程序代码进行扫描,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码剖析技术。 动态分析:软件系统在模仿的或实在的环境中执行之前、之中和之后,对软件系统行为的剖析。 非代码剖析:次要是对数据文件、配置文件等非源码文件和源码间进行关联剖析,当代码仓变更时,能感知变更内容对源码、性能的影响。 动态分析多为对程序进行的一些功能测试或性能测试等对程序的运行后果,资源应用状况的相干程序剖析工作。故本大节次要介绍动态程序剖析相干的代码了解技术,不对动静程序剖析做开展。 动态程序剖析在不执行程序程序的状况下对程序进行剖析,剖析的对象能够是针对特定版本的源代码或者二进制文件,通过词法剖析、语法分析、控制流、数据流剖析等技术对程序代码进行扫描,依据不同的剖析指标,失去对应的剖析后果。在学术界和工业界次要利用在软件平安畛域,验证代码是否满足规范性、安全性、可靠性、可维护性;在百度外部,除破绽检测外,动态程序剖析还包含多维度的代码剖析和度量伎俩,在交付零碎和监测零碎中被宽泛应用。 业界动态剖析个别基于以下4种形式开展: 关键字匹配,基于正则表达式剖析基于AST的代码剖析,联合正则表达式和关键字能力长处:联合语法和语义,能够引入作用域等更多概念,更精确。毛病:无奈应答所有场景,另外,基于AST来剖析失去的数据流,疏忽了分支、跳转、循环等影响执行过程程序的条件,短少控制流信息。基于IR/CFG的代码剖析等自制的两头语言数据结构剖析属于以后比拟支流的代码剖析计划,例如被源伞,实现了多种语言生成对立的IR,这样一来对于新语言的扫描反对难度就变得大大减少。IR:是一种相似于汇编语言的线性代码,其中各个指令依照程序执行。其中当初支流的IR是三地址码(四元组),例如llvm的IR。CFG:(Control flow graph)控制流图,在程序中最简略的控制流单位是一个基本块,在CFG中,每一个节点代表一个基本块,每一个边代表一个可控的管制转移,整个CFG代表了整个代码的的管制流程图。基于IR来生成失去CFG。基于QL(Query Language)剖析例如codeQL,把源代码转化成一个可查问的数据库,通过 对源代码工程进行要害信息剖析提取,形成一个关系型数据库。安全漏洞、Bug 和其余谬误被建模为可针对从代码中提取的数据库执行的查问。罕用的动态程序剖析技术: 数据流剖析数据流剖析收集程序运行到不同地位时各个值的信息和它们随工夫变动的信息。污点测验是一个典型的通过数据流剖析进行程序危险检测的例子,它会找到所有的可能被使用者批改的变量(也就是有“污点”、不平安的变量),并阻止这些变量在被修复安全漏洞前被应用。控制流剖析用于剖析程序控制流构造的动态剖析技术,目标在于生成程序的控制流图,在污点剖析、编译器设计、程序剖析、程序了解等畛域都有重要利用。指针剖析指针剖析次要用于剖析指针所有可能指向的对象,它会剖析出一个指针所指向的内存地位和所对应的对象。能够用于调用剖析、代码优化、Bug追究、安全性剖析与验证测试。四、代码级利用之探针代码探针,也是插桩技术,它是在保障被测程序原有逻辑完整性的根底上在程序中插入一些探针(又称为“探测仪”,实质上就是进行信息采集的代码段,能够是赋值语句或采集笼罩信息的函数调用),通过探针的执行并抛出程序运行的特色数据,通过对这些数据的剖析,能够取得程序的控制流和数据流信息,进而失去逻辑笼罩等动静信息,从而实现测试目标的办法。 不同语言的插桩技术有所不同,常见的技术有:ccover、covtool、jacoco、gocov。 CodeP代码探针能够利用在: 代码监控(办法执行耗时等),代码剖析(函数、数据流的跟踪等),业务埋点。 除此之外,代码探针最常见的场景是代码覆盖率采集。 4.1 覆盖率代码覆盖率,是软件测试中的一种度量,形容程序中源代码被测试的比例和水平,所得比例称为代码覆盖率 ,剖析未笼罩局部的代码,从而反推在后期测试设计是否充沛,没有笼罩到的代码是否是测试设计的盲点。覆盖率统计的分类蕴含: 行覆盖率:行覆盖率是最根本的指标,示意是否代码中的每个可执行语句都被执行过; 分支覆盖率:分支笼罩应用一组测试参数来测试是否代码中所有的分支都能被测试到了; 门路覆盖率: 对包含所有分支在内的所有的门路都能测试一遍,这就是门路笼罩; 变更行覆盖率:上一次公布代码后更新的代码的行覆盖率,这个数据能够不便的看出新的代码是否做了测试。 覆盖率的业务应用场景宽泛比方:RD自测、RD准入、QA准出、外包评估、精准测试、集成测试、基线降级评估、灰度测试评估,自动化测试能力评估、众测等。 代码探针实现覆盖率统计的步骤如下: 1、辨认待插桩的函数 2、用codep技术对函数进行插桩,插桩技术分为: 源码插桩: 侵入式的在源代码的根底上替换或者插入另外一些代码编译过程插桩: 在字节码文件中写入桩函数 (如asm、javassit等技术)3、探针采集笼罩信息整合, 统计覆盖率数据 五、代码级利用之召回从召回异样问题的角度介绍两类代码级技术利用:智能UT、SA。与现有异样测试方法进行比照剖析,压力测试、功能测试依赖编译运行且需人工结构异样场景,存在高老本、低召回的问题。而智能UT和SA基于白盒剖析产出的数据能够提前、疾速、低成本、轻量级地召回异样问题。 5.1 智能UT单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证,这里的最小测试单元是指函数或者类。在问题召回层面,UT针对最小单元进行测试,结构数据简略、易于验证正确性,便于后续性能的回归,可能更早地发现问题,定位和解决问题成本低。 ...

May 31, 2023 · 1 min · jiezi

关于c:Linux网络开发必学教程22客户端设计与初步实现

问题:Response Task 和 Server Task 的业务逻辑如何实现?客户端如何实现?再论交互流程 交互具体设计(Message::payload) 客户端被动发动服务查问(局域播送)服务设施将本身能提供的服务信息及用法返回(字符串形容)客户端依据收到的服务用法向设施发动申请(字符串形容)服务设施接管命令并匹配服务,并返回服务后果(字符串形容)交互示例 关键问题"Touch Lig_On" 怎么晓得给哪一个服务设施发送命令?地址管理器模块每个服务设施在回复服务查问信息时,会附带服务地址;因而,记录服务命令与设施地址之间存在映射关系。 #ifndef ADDR_MSG_H#define ADDR_MSG_Hint AddrMgr_Add(const char *cmd, const char *addr);char *AddMgr_Find(const char *cmd);void AddMgr_Remove(const char *cmd);void AddMgr_Clear();#endif // ADDR_MSG_H根底功能模块#define Malloc2d(type, row, col) ({});void Free2d(void *p);char *FormatByChar(const char *src, char c);int DivideByChar(const char *line, char c, char **argv, int row, int col);编程试验:客户端初步实现main.c #include <stdio.h>#include <string.h>#include "utility.h"#include "addr_mgr.h"int main(){ const char *src = " abc de "; char ** argv = Malloc2d(char, 3, 5); int r = DivideByChar(src, ' ', argv, 3, 5); int i = 0; for (i=0; i<r; i++) { printf("argv[%d] = *%s*\n", i, argv[i]); } Freee2d(argv); AddrMgr_Add("delpin", "1.1.1.1"); AddrMgr_Add("tang", "2.2.2.2"); AddrMgr_Add("D.T.Software", "3.3.3.3"); printf("delpin = *%s*\n", AddrMgr_Find("delpin")); printf("tang = *%s*\n", AddrMgr_Find("tang")); printf("D.T.Software = *%s*\n", AddrMgr_Find("D.T.Software")); AddMgr_Clear(); return 0;}输入: ...

May 30, 2023 · 3 min · jiezi

关于c:Linux网络开发必学教程21智能家居服务发现实现

服务设施软件 代码复用将网络通讯框架移植到开发板,之后,可应用框架中的组件实现 Response Task 和 Server Task 框架移植注意事项Lwip 是微型 TCP/IP 协定栈 (并非残缺 TCP/IP协定栈)反对 socket 接口,但一些性能未实现socket 接口所在头文件不同于 Linux 和 Window 平台实现可执行测试,对测试中呈现的问题及时修复可执行性测试通过网络调试助手验证 TCP 数据首发 设施运行服务端,客户端连贯,数据收发性能通过网络调试助手验证 UDP 数据收发 设施端接管播送,并复原数据Server Task 要害实现static void EventListener(TcpClient* client, int evt){ if( evt == EVT_CONN ) { printf("%s : CONN - %p...\n", __FUNCTION__, client); } else if( evt == EVT_DATA ) { Message* msg = NULL; printf("%s : DATA - %p...\n", __FUNCTION__, client); msg = TcpClient_RecvMsg(client); if( msg ) { printf("%s : msg = %p\n", __FUNCTION__, msg); printf("%s : msg->type = %d\n", __FUNCTION__, msg->type); printf("%s : msg->cmd = %d\n", __FUNCTION__, msg->cmd); } free(msg); } else if( evt == EVT_CLOSE ) { printf("%s : CLOSE - %p...\n", __FUNCTION__, client); }}void* Service_Task(const char* arg){ TcpServer* server = TcpServer_New(); printf("%s : enter service task...\n", __FUNCTION__); if( server ) { printf("%s : server = %p\n", __FUNCTION__, server); TcpServer_SetListener(server, EventListener); TcpServer_Start(server, 8888, 10); TcpServer_DoWork(server); } return arg;}Respone Task 要害实现void* Response_Task(const char* arg){ UdpPoint* udp = UdpPoint_New(9999); printf("%s : enter response task...\n", __FUNCTION__); if( udp ) { char remote[16] = {0}; int port = 0; printf("%s : udp = %p\n", __FUNCTION__, udp); while( 1 ) { Message* msg = UdpPoint_RecvMsg(udp, remote, &port); if( msg ) { printf("%s : msg = %p\n", __FUNCTION__, msg); printf("%s : remote = %s\n", __FUNCTION__, remote); printf("%s : port = %d\n", __FUNCTION__, port); printf("%s : msg->type = %d\n", __FUNCTION__, msg->type); printf("%s : msg->cmd = %d\n", __FUNCTION__, msg->cmd); } else { printf("%s : msg is NULL...\n", __FUNCTION__); } free(msg); } } return arg;}编程试验,网络通讯框架移植main.c ...

May 30, 2023 · 3 min · jiezi

关于c#:Unity的AssetPostprocessor之Model深入解析与实用案例-1

Unity AssetPostprocessor模型相干函数详解在Unity中,AssetPostprocessor是一个十分有用的工具,它能够在导入资源时主动执行一些操作。在本文中,咱们将重点介绍AssetPostprocessor中与模型相干的函数,并提供多个应用例子。 OnPostprocessModelOnPostprocessModel是AssetPostprocessor中与模型相干的次要函数。它在导入模型时主动调用,并容许咱们对模型进行一些自定义操作。上面是一个简略的例子: using UnityEngine;using UnityEditor;public class MyModelPostprocessor : AssetPostprocessor{ void OnPostprocessModel(GameObject model) { // 在这里对模型进行自定义操作 }}在这个例子中,咱们创立了名为MyModelPostprocessor的AssetPostprocessor类,并重写了OnPostprocessModel函数。在这个函数中,咱们能够对导入的模型进行自定义操作。 上面是一些常见的用: 1. 批改模型的材质void OnPostprocessModel(GameObject model){ Renderer[] renderers = model.GetComponentsInChildren<Renderer>(); foreach (Renderer renderer in renderers) { Material[] materials = renderer.sharedMaterials; for (int i = 0; i < materials.Length; i++) { // 批改材质 materials[i] = new Material(Shader.Find("Standard")); } renderer.sharedMaterials = materials; }}在这个例子中,咱们获取了模型中所有的Renderer组件,并遍历每个Renderer的材质。而后,咱们将每个材质替换为一个新的Standard材质。 2. 批改模型的网格void OnPostprocessModel(GameObject model){ MeshFilter[] meshFilters = model.GetComponentsInChildren<MeshFilter>(); foreach (MeshFilter meshFilter in meshFilters) { // 批改网格 Mesh mesh = meshFilter.sharedMesh; Vector3[] vertices = mesh.vertices; for (int i = 0; i < vertices.Length; i++) { vertices[i] += Vector3.up; } mesh.vertices = vertices; mesh.RecalculateNormals(); }}在这个例子中,咱们获取了模型中所有的MeshFilter组件,并遍历每个MeshFilter的网格。而后,咱们将每个网格的顶点向上挪动一个单位。 ...

May 29, 2023 · 3 min · jiezi

关于c#:CVBNET如何从-PowerPoint-演示文稿中提取文本

在学习或者日常工作中,有时咱们须要把幻灯片的货色整顿成文字,而从 PowerPoint 演示文稿中一张一张的整顿手动复制粘贴,整个过程会十分费精力且耗时。那么怎么样能力比拟轻松且疾速地提取PowerPoint中的文字呢?明天这篇文章就将为你介绍如何通过编程形式提取PowerPoint中的文字,文章最初附有C#/VB.NET代码以及效果图,心愿对你有所帮忙。 程序环境本次测试时,在程序中引入Free Spire.Presentation for .NET。可通过以下办法援用 Free Spire.Presentation.dll文件:办法1:将 Free Spire.Presentation for .NET下载到本地,解压,装置。装置实现后,找到装置门路下BIN文件夹中的 Spire.Presentation.dll。而后在Visual Studio中关上“解决方案资源管理器”,鼠标右键点击“援用”,“增加援用”,将本地门路BIN文件夹下的dll文件增加援用至程序。办法2:通过NuGet装置。可通过以下2种办法装置:(1)能够在Visual Studio中关上“解决方案资源管理器”,鼠标右键点击“援用”,“治理NuGet包”,而后搜寻“Free Spire.Presentation”,点击“装置”。期待程序安装实现。(2)将以下内容复制到PM控制台装置。Install-Package FreeSpire.Presentation -Version 7.8.0 从 PowerPoint 演示文稿中提取文本为了便于在 PowerPoint 文档中共享或传递文本信息,有时须要进行文本提取操作。以下是从所有演示文稿幻灯片中提取文本并保留在 TXT 文件中的步骤。 初始化 Presentation 类的实例。应用 Presentation.LoadFromFile() 办法加载 PowerPoint 文档示例。创立 StringBuilder 实例。遍历文档中的每张幻灯片,而后遍历每张幻灯片中的所有形态。确定形态是否为 IAutoShape 类型。如果是,则遍历每个形态中的所有段落,并应用 TextParagraph.Text 属性获取段落文本。应用 StringBuilder.AppendLine() 办法将提取的文本附加到StringBuilder实例创立一个新的txt文件,并应用 File.WriteAllText() 办法将提取的文本写入该文件。 残缺代码C# using Spire.Presentation;using Spire.Presentation.Charts;using Spire.Presentation.Converter.Equation.Word;using System;using System.IO;using System.Text;namespace ExtractText{ class Program { static void Main(string[] args) { //初始化Presentation类的实例 Presentation presentation = new Presentation(); //载PowerPoint文档示例 presentation.LoadFromFile("空中楼阁是如何造成的?.pptx"); //创立StringBuilder实例 StringBuilder sb = new StringBuilder(); //遍历文档中的每张幻灯片 foreach (ISlide slide in presentation.Slides) { //遍历每张幻灯片中的每个形态 foreach (IShape shape in slide.Shapes) { //查看形态是否为IAutoShape类型 if (shape is IAutoShape) { //以每种形态遍历所有段落 foreach (TextParagraph tp in (shape as IAutoShape).TextFrame.Paragraphs) { //提取文本并保留到StringBuilder实例 sb.AppendLine(tp.Text); } } } } //创立一个新的txt文件以保留提取的文本 File.WriteAllText("提取文本.txt", sb.ToString()); presentation.Dispose(); } }}VB.NET ...

May 29, 2023 · 1 min · jiezi

关于c#:Unity的Console的控制类LogEntries深入解析与实用案例

应用Unity Console窗口的LogEntries公有类实现自定义日志零碎在Unity开发过程中,咱们常常须要应用Console窗口来查看程序运行时的日志信息。Unity内置的日志零碎提供了根本的日志性能,但有时咱们须要更多的自定义选项。本文将介绍如何应用Unity Console窗口的LogEntries公有类来实现自定义日志零碎,并提供多个应用例子。 1. 获取LogEntries公有类的援用首先,咱们须要获取LogEntries公有类的援用。因为LogEntries是一个公有类,咱们须要应用反射来获取它。以下是获取LogEntries类援用的代码: using System;using System.Reflection;using UnityEditor;public class CustomLogSystem{ private static Type logEntriesType; static CustomLogSystem() { Assembly unityEditorAssembly = Assembly.GetAssembly(typeof(EditorWindow)); logEntriesType = unityEditorAssembly.GetType("UnityEditor.LogEntries"); }}2. 应用LogEntries实现自定义日志性能2.1 清空Console窗口有时咱们心愿在程序运行时主动清空Console窗口,以便查看新的日志信息。咱们能够应用LogEntries.Clear()办法来实现这个性能。以下是清空Console窗口的代码: public static void ClearConsole(){ MethodInfo clearMethod = logEntriesType.GetMethod("Clear", BindingFlags.Static | BindingFlags.Public); clearMethod.Invoke(null, null);}2.2 获取日志数量咱们能够应用LogEntries.GetCount()办法来获取Console窗口中的日志数量。以下是获取日志数量的代码: public static int GetLogCount(){ MethodInfo getCountMethod = logEntriesType.GetMethod("GetCount", BindingFlags.Static | BindingFlags.Public); return (int)getCountMethod.Invoke(null, null);}2.3 获取特定类型的日志数量有时咱们须要获取特定类型(如谬误、正告、一般日志)的日志数量。咱们能够应用LogEntries.GetCountsByType()办法来实现这个性能。以下是获取特定类型日志数量的代码: public enum LogType{ Error = 0, Warning = 1, Log = 2}public static int GetLogCountByType(LogType logType){ MethodInfo getCountsByTypeMethod = logEntriesType.GetMethod("GetCountsByType", BindingFlags.Static | BindingFlags.Public); int[] counts = new int[3]; getCountsByTypeMethod.Invoke(null, new object[] { counts }); return counts[(int)logType];}3. 应用例子3.1 主动清空Console窗口在程序开始运行时,咱们能够主动清空Console窗口,以便查看新的日志信息。以下是实现主动清空Console窗口的代码: ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的Undo详解解析与实用案例

Unity Undo详解在Unity中,Undo是一个十分重要的性能,它能够让开发者在编辑器中进行操作时,随时撤销之前的操作,从而防止不必要的谬误。本文将具体介绍Unity Undo实现原理和应用办法,并提供多个应用例子,帮忙开发者更好地了解和利用该性能。 实现原理Unity Undo的实现原理是通过记录每个操作的状态,并将其存储在一个Undo栈中。当须要撤销操作时,Unity会从Undo栈中取出最近的操作状态,并将其还原到之前的状态。当须要重做操作时,Unity会从Redo栈中取出最近的操作状态,并将其还原到之后的状态。应用办法Unity Undo的应用办法非常简单,只须要在须要进行Undo的前,调用Undo.RecordObject办法即可。该办法承受两个参数,第一个参数是须要进行Undo的对象,第二个参数是一个形容该操作的字符串。例如: using UnityEngine;public class MyScript : MonoBehaviour{ public int myValue void Update() { Undo.RecordObject(this, "Change My Value"); myValue = Mathf.RoundToInt(Time.time); }}在下面的例子中,咱们在Update办法中调用了Undo.RecordObject办法,将以后对象和一个形容字符串传递给该办法。当咱们在编辑器中批改myValue的值时,Unity会自动记录该操作,并将其存储在栈中。当咱们须要撤销该操作时,只须要按下Ctrl+Z即可。 应用例子例子1:批改Transform组件在Unity中,Transform组件是一个十分罕用的组件,它用于管制游戏对象的地位、旋转和缩放。咱们能够应用Undo性能来撤销对Transform组件的批改。例如: public class MyScript : MonoBehaviour{ void Update() { Undo.RecordObject(transform, "Change Transform"); transform.position = new Vector3(1, 2, 3); transform.rotation = Quaternion.Euler(0, 90, 0); transform.localScale = new Vector3(2, 2, 2); }}在下面的例子中,咱们在Update办法中调用了Undo.RecordObject`办法,并将Transform组件和一个形容字符串传递给该办法。当咱们在编辑器中批改Transform组件的值时,Unity会自动记录该操作,并将其存储在Undo栈中。当咱们须要撤销该操作时,只须要按下Ctrl+Z即可。 例子2:批改数组元素在Unity中,数组是一个十分罕用的数据结构,咱们能够应用Undo性能来撤销对数组元素的批改。例如: using UnityEngine;public class MyScript : MonoBehaviour{ public int[] myArray = new int[3]; void Update() { Undo.RecordObject(this, "Change Array"); myArray[0] = 1; myArray[1] = 2; myArray[2] = 3; }}在下面的例子中,咱们在Update办法中调用了Undo.RecordObject办法,并将以后对象和一个形容字符串传递给该办法。当咱们在编辑器中批改myArray的值时,Unity会自动记录该操作,并将其存储在Undo栈中。当咱们撤销该操作时,只须要按下Ctrl+Z即可。 ...

May 28, 2023 · 1 min · jiezi

关于c++:QT-绘制波形图频谱图瀑布图星座图眼图语图

阐明最近在学中频信号处理的一些货色,顺便用 QT 写了一个小工具,能够显示信号的时域波形图、幅度谱、功率谱、二次方谱、四次方谱、八次方谱、刹时包络、刹时频率、刹时相位、非线性刹时相位、刹时幅度直方图、刹时频率直方图、刹时相位直方图、眼图、星座图、语谱图、瀑布图。 1. 实现思路工具为纯 C++ 开发,包含频谱计算以及图像可视化。这里简述下实现思路,应用到了以下第三方库: QCustomPlot 绘图库。FFTW 傅氏变换库。FreeGlut 工具包。频谱计算局部,通过调用 FFTW 的 C++ 接口,同时开启 OpenMP 多核反对,能够取得很快的计算速度,比 MATLAB 还快,工具中的所有频谱都是在点击按钮时现算的。在我的电脑上(8 核 Intel i7-6700HQ CPU @ 2.60GHz),实测对 33554432 长度(2 的 25 次方)的双精度浮点数组进行傅里叶变换,两种形式的耗时如下: MATLAB 的 fft 函数耗时 629 毫秒。C++ 调用 FFTW 接口并开启 OpenMP 多核反对,耗时 390 毫秒。图像可视化局部,应用 QCustomPlot 实现图像绘制,并联合 FreeGlut 工具开启 OpenGL 反对,绘图品质及响应速度也失去了较好的晋升,大数据显示并进行交互时不会呈现卡顿。为了进一步晋升速度,还批改了 QCustomPlot 的局部源码,将数据更新接口裸露进去,应用 memcpy() 间接对原始绘图数据所在的内存块进行操作,晋升数据更新的速度。主界面如下: 2. 时域波形图测试信号:2FSK 调制,调制速率 8888 Baud/s,采样率 284416 Hz,信号频率 62216 Hz 与 79992Hz,文件大小 64 MB。波形显示时做了贝塞尔平滑解决。 3. 幅度谱测试信号:2FSK 调制,调制速率 8888 Baud/s,采样率 284416 Hz,信号频率 62216 Hz 与 79992Hz,文件大小 64 MB。 ...

May 28, 2023 · 2 min · jiezi

关于c#:Unity的UnityStats-属性详解与实用案例

UnityStats 属性详解UnityStats 是 Unity 引擎提供的一个用于监测游戏性能的工具,它提供了一系列的属性值,能够帮忙开发者解游戏的运行状况,从而进行优化。本文将具体介绍 UnityStats 的每个属性值,并提供多个应用例子帮忙开发者更好地应用 UnityStats。 帧率相干属性UnityStats.fpsUnityStats.fps 属性用于获取以后游戏的帧率。它返回一个浮点数,示意以后游戏的帧率。例如: void Update(){ float fps = UnityStats.fps; Debug.Log("以后帧率:" + fps);}UnityStats.batchedDrawCallsUnityStats.batchedDrawCalls 属性用于获取以后游戏中批处理的绘制调用次数。它返回一个整数,示意以后游戏中批处理的绘制调用次数。例如: void Update(){ int batchedDrawCalls = UnityStats.batchedDrawCalls; Debug.Log("批处理的绘制调用次数:" + batchedDrawCalls);}UnityStats.drawCallsUnityStats.drawCalls 属性用于获取以后游戏中绘制调用次数。它返回一个整数,示意以后游戏中的绘制调用次数。例如: void Update(){ int drawCalls = UnityStats.drawCalls; Debug.Log("绘制调用次数:" + draw);}UnityStats.trianglesUnityStats.triangles 属性用于获取以后游戏中的三角形数量。它返回一个整数,示意以后游戏中的三角形数量。例如: Update(){ int triangles = UnityStats.triangles; Debug.Log("三角形数量:" + triangles);}内存相干属性UnityStats.usedTextureMemorySizeUnityStats.usedTextureMemorySize 属性用于获取以后游戏中应用的纹理内存大小。它返回一个整数,示意以后游戏中应用的纹理内存大小。例如: void Update(){ int usedTextureMemorySize = UnityStats.usedTextureMemorySize; Debug.Log("应用的纹理内存大小:" + usedTextureMemorySize);}UnityStats.usedHeapSizeUnityStats.usedHeapSize 属性用于获取以后游戏中应用的堆内存大小。它返回一个整数,示意以后游戏中应用的堆内存大小。例如: void(){ int usedHeapSize = UnityStats.usedHeapSize; Debug.Log("应用的堆内存大小:" + usedHeapSize);}UnityStats.usedGraphicsMemorySizeUnityStats.usedGraphicsMemorySize 属性用于获取以后游戏中应用的显存大小。它返回一个整数,示意以后游戏中应用的显存大小。例如: ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IPostGenerateGradleAndroidProject深入解析与实用案例

Unity IPostGenerateGradleAndroidProjectUnity是一款风行的跨平台游戏引擎,它反对多种平台,包含Android。在Unity中,咱们能够应用IPostGenerateGradleAndroidProject接口来自定义Gradle构建过程。本文将介绍如何应用IPostGenerateGradleAndroidProject接口,并提供三个应用例子。 IPostGenerateGradleAndroidProject接口IPostGenerateGradleAndroidProject接口是Unity提供的一个接口,它容许咱们在Gradle构建过程中执行自定义操作。咱们能够应用它批改Gradle构建文件,增加Gradle插件,或者执行其余自定义操作。 IPostGenerateGradleAndroidProject接口有一个办法:OnPostGenerateGradleAndroidProject。这个办法会在Gradle构建过程中被调用,咱们能够在这个办法中执行自定义操作。 应用例子例子1:批改Gradle构建文件咱们能够应用IPostGenerateGradleAndroidProject接口来批改Gradle构建文件。例如,咱们能够增加一个自定义的Gradle工作来执行一些额定的操作。 using UnityEditor.Android;public class MyPostGenerateGradle : IPostGenerateGradleAndroidProject{ public void OnPostGenerateGradleAndroidProject(string basePath) { string gradlePath = basePath + "/build.gradle"; string gradleContent = File.ReadAllText(gradlePath); gradleContent += "\n" + "task myTask {\n" + " doLast {\n" + " println 'Hello from myTask'\n" + " }\n" + "}\n"; File.WriteAllText(gradlePath, gradleContent); }}在这个例子中,咱们增加了一个名为myTask的Gradle工作,它会在构建过程中执行。这个工作会输入一条音讯,通知咱们它曾经被执行了。 例子2:增加Gradle插件咱们也能够应用IPostGenerateGradleAndroidProject接口来增加Gradle插件。例如,咱们能够增加一个自定义的Gradle插件来执行一些额定的操作。 using UnityEditor.Android;public class MyPostGenerateGradle : IPostGenerateGradleAndroidProject{ public void OnPostGenerateGradleAndroidProject(string basePath) { string gradlePath = basePath + "/build.gradle"; string gradleContent = File.ReadAllText(gradlePath); gradleContent += "\n" + "buildscript {\n" + " repositories {\n" + " mavenCentral()\n" + " }\n" + " dependencies {\n" + " classpath 'com.example:my-plugin:1.0'\n" + " }\n" + "}\n" + "apply plugin: 'com.example.my-plugin'\n"; File.WriteAllText(gradlePath, gradleContent); }}在这个例子中,咱们增加了一个名为com.example.my-plugin的Gradle插件,它会在构建过程中执行这个插件会执行一些额定的操作,例如生成一些额定的文件或者执行一些额定的工作。 ...

May 28, 2023 · 1 min · jiezi

关于c:Linux网络开发必学教程20物联网设备-WIFI-模块实现非必要

问题:如何在设施上进行 WIFI 编程?Lwip (Light weight IP) 简介Lwip 是轻量化的TCP/IP,是一个小型开源的 TCP/IP 协定栈LwIP 的设计指标是用较少的资源实现实现的 TCP/IP 协定栈Lwip 能在操作系统中运行,也能在无操作系统的状况下独立运行Lwip 提供了 Socket API 和 Netconn APILwip 的次要个性反对 ARP, ICMP, IGMP反对 UDP, TCP, IP (可执行网络通讯框架)反对 DNS, PPP, SNMP直至 DHCP, 可动态分配 IP (WIFI 反对)。。。BearPi-Nano 联网能力BearPi-Nano 基于 Hi3861 芯片构建,而 Hi3861 本身具备 Wifi 能力 AP 模式:工作于 WIFI 热点模式,可被其它设施以 WIFI 形式连贯STA 模式:工作于 WIFI 连贯模式,可连贯到指定 WIFI 热点WIFI 模块接口设计init Wifi_Init(void);init Wifi_Connect(const char *id, const char *pwd);int Wifi_Start(void);int Wifi_IsOk(void);void Wifi_Stop(void);char *Wifi_IpAddr(void);波及的 OH 零碎接口WifiErrorCode RegisterWifiEvent(WifiEvent *event);WifiErrorCode EnableWifi(void);WifiErrorCode AddDeviceConfig(const WifiDeviceConfig *config, int result);WifiErrorCode ConnetTo(int networkid); // 通过网络标识连贯到指标热点struct netif *netifapi_netif_find(const char *name); // 获取 netif 构造体用于后续 dhcp 操作err_t dhcp_start(struct netif *netif); // 启动 hdcp, 获取 ipWIFI 热点连贯流程 ...

May 28, 2023 · 3 min · jiezi

关于c#:Unity的IUnityLinkerProcessor深入解析与实用案例

Unity IUnityLinkerProcessorUnity IUnityLinkerProcessor是Unity引擎中的一个接口,它容许开发者在Unity我的项目构建时对代码进行链接解决。这个接口能够用来优化我的项目构建大小,缩小不必要的代码和资源,进步我的项目的性能和加载速度。 接口定义IUnityLinkerProcessor接口定义如下: namespace UnityEditor.Build.IPA{ public interface IUnityLinkerProcessor { void OnBeforeRun(LinkXml linkXml); void OnProcessAssembly(string inputFile, string[] searchDirs, string outputFile); }}其中,OnBeforeRun办法在Unity构建我的项目之前被调用,能够用来解决Link.xml文件。OnProcessAssembly办法在Unity构建我的项目时被调用,能够用来解决每个输出程序集。 Link.xml文件Link.xml文件是Unity我的项目中的一个XML文件,用于指定须要保留的程序集、类型和成员。Link.xml文件的格局如下: <linker> <assembly fullname="AssemblyName"> <type fullname="TypeName" preserve="method" /> </assembly></linker>其中,assembly元素指定须要保留的程序集,fullname属性指定程序集的残缺名称。type元素指定须要保留的类型,fullname属性指定类型的残缺名称,preserve属性指定须要保留的成员类型,能够是method、field、property、event等。 应用例子上面给出三个应用例子,别离演示如何应用IUnityLinkerProcessor接口来优化Unity我的项目的构建大小。 例子1:保留指定程序集在Link.xml文件中指定须要保留的程序集,其余程序集将被删除。 <linker> <assembly fullname="Assembly-CSharp" /></linker>在IUnityLinkerProcessor接口的OnBeforeRun办法中读取Link.xml文件,将须要保留的程序集增加到LinkerOptions中。 public void OnBeforeRun(LinkXml linkXml){ foreach (var assembly in linkXml.Assemblies) { if (assembly.Fullname == "Assembly-CSharp") { LinkerOptions.LinkAssemblies.Add(assembly.Fullname); } }}例子2:保留指定类型和成员在Link.xml文件中指定须要保留的类型和成员,其余类型和成员将被删除。 <linker> <assembly fullname="Assembly-CSharp"> <type fullnameMyClass"> <method signature="System.Void MyMethod()" /> </type> </assembly></linker>在IUnityLinkerProcessor接口的OnBeforeRun办法中读取Link.xml文件,须要保留的类型和成员增加到LinkerOptions中。 public void OnBeforeRun(LinkXml linkXml){ foreach (var assembly in linkXml.Assemblies) { if (assembly.Fullname == "Assembly-CSharp") { foreach (var type in assembly.Types) { if (type.Fullname == "MyClass") { foreach (var method in type.Methods) { if (method.Signature == "System.Void MyMethod()") { LinkerOptions.LinkType(type.Fullname); LinkerOptions.LinkMethod(method.Signature); } } } } } }}例子3:删除指定程序集在Link.xml文件中指定须要删除的程序集,其余程序集将被保留。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IGenerateNativePluginsForAssemblies深入解析与实用案例

Unity IGenerateNativePluginsForAssembliesUnity是一款十分风行的游戏引擎,它反对多种平台,包含Windows、Mac、Linux、Android、iOS等。在Unity中,咱们能够应用C#编写游逻辑,然而有些时候咱们须要应用一些原生的代码来实现一些高性能的性能,比方图像处理、音频等。这时候,咱们就须要应用Unity的IGenerateNativePluginsForAssemblies性能来生成原生插件。 什么是IGenerateNativePluginsForAssembliesIGenerateNativePluginsForAssemblies是Unity的一个性能,它能够将C#代码编译成原生代码,并生成一个动态链接库(DLL)。这个DLL能够被Unity加载,并且能够在C#代码中调用其中的函数。这样,咱们就能够应用原生代码来实现一些高性能的性能。 如何应用IGeneratePluginsForAssemblies应用IGenerateNativePluginsForAssemblies非常简单,只须要依照以下步骤即可: 在Unity中创立一个C#类,并在其中定义须要编译成原生代码的函数。在Unity的菜单栏中抉择Assets -> Generate Code,而后抉择须要编译的C#类。Unity会主动编译C#代码,并生成一个DLL文件。例子1:应用IGenerateNativePluginsForAssemblies实现图像处理上面是一个应用IGenerateNativePluginsForAssemblies实现图像处理的例子。咱们须要应用OpenCV库来实现图像处理,此须要先装置OpenCV库。 using UnityEngine;using System.Runtime.InteropServices;public class ImageProcessor{ [DllImport("ImageProcessor")] private static extern void ProcessImage(byte[] data, int width, int height); public static void Process(Texture2D texture) { byte[] data = texture.GetRawTextureData(); ProcessImage(data, texture.width, texture.height); }}在下面的代码中,咱们定义了一个名为ImageProcessor的类,并在其中定义了一个名为Process的动态函数。这函数承受一个Texture2D对象作为参数,并将其转换为一个字节数组。而后,它调用了一个名为ProcessImage的原生函数,这个函数应用OpenCV库来解决图像。 为了让Unity可能调用这个原生函数咱们须要在函数后面加上DllImport属性,并指定原生函数的名称和DLL文件的名称。在这个例子中,原生函数的名称为Image,DLL文件的名称为ImageProcessor。 例子2:应用IGenerateNativePluginsForAssemblies实现音频解决上面是一个应用IGenerateNativePluginsForAssemblies实现音频解决的例子。咱们须要应用FMOD库来实现音频解决,因而须要先安FMOD库。 using UnityEngine;using System.Runtime.InteropServices;public class AudioProcessor{ [DllImport("AudioProcessor")] private static extern void ProcessAudio(float[] data, int length); public static void Process(AudioClip clip) { float[] data = new float[clip.samples * clip.channels]; clip.GetData(data, 0); ProcessAudio(data, data.Length); }}在下面的代码中,咱们定义了一个名为AudioProcessor的类,并在其中定义了一个名为Process的动态函数。这个函数承受一个AudioClip对象作为参数,并将其转换为一个浮点数数组。而后,它调用了一个名为ProcessAudio的原生函数,这个应用FMOD库来解决音频。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IPreprocessComputeShaders深入解析与实用案例

Unity IPreprocessComputeShadersUnity IPreprocessComputeShaders是Unity引擎中的一个十分有用的性能,它能够让开发者编译Compute Shader时自定义哪些操作须要被执行。这个能够帮忙开发者更好地管制Compute Shader的编译过程,确保在编译Compute Shader时执行必要的操作。在本文中,咱们介绍Unity IPreprocessComputeShaders的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IPreprocessComputeShaders的应用办法Unity IPreprocessComputeShaders是一个接口,它在编译Compute Shader时被调用。在这个接口中,咱们能够编写咱们须要执行的操作,并且能够获取以后的Compute Shader。下是一个简略的例子,演示了如何在编Compute Shader时执行一些操作: using UnityEngine;using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class ComputeShaderPreprocessor : IPreprocessComputeShaders{ public int callbackOrder { get { return 0; } } public void OnProcessComputeShader(ComputeShader shader) { // Do something with the compute shader }}在这个例子中,咱们实现了IPreprocessComputeShaders接口,并重写了它的OnProcessComputeShader办法。在这个办法中,咱们能够获取以后的Compute Shader,并执行咱们须要执行的操作。 应用例子上面是三个应用Unity IPreprocessComputeShaders的例子,每个例子都供了具体的实现。 例子1:批改Compute Shader的属性在这个例子中,咱们将演示如何批改Compute Shader的属性。 using UnityEngine;using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class ComputeShaderPreprocessor : IPreprocessComputeShaders{ public int callbackOrder { get { return 0; } } public void OnProcessComputeShader(ComputeShader shader) { shader.SetInt("MY_DEFINE", 1); shader.SetTexture(0, "MY_TEXTURE", myTexture); }}在这个例子中,咱们实现了IPreprocessComputeShaders接口,并重写了它的OnProcessComputeShader办法。在这个办法中,咱们首先应用Compute Shader的SetInt办法设置了一个整型变量,而后应用SetTexture办法设置了一个纹理变量。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IPreprocessShaders深入解析与实用案例

Unity IPreprocessShadersUnity IPreprocessShaders是Unity引擎中的一个十分有用的性能,它能够让开发者在编译Shader时自定义哪些操作须要被执行。这个能够帮忙开发者更好地管制Shader的编译过程,确保在编译Shader时执行必要的操作。在本文中,咱们介绍Unity IPreprocessShaders的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IPreprocessShaders的应用办法Unity IPreprocessShaders是一个接口,它在编译Shader时被调用。在这个口中,咱们能够编写咱们须要执行的操作,并且能够获取以后的Shader。下是一个简略的例子,演示了如何在编译Shader时执行一些操作: using UnityEngine;using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class ShaderPreprocessor : IPreprocessShaders{ public int callbackOrder { get { return 0; } } public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> shaderCompilerData) { // Do something with the shader }}在这个例子中,咱们实现了IPreprocessShaders接口,并重写了它的OnProcessShader办法。在这个办法中,咱们能够获取以后的Shader,并执行咱们须要执行的操作。 应用例子上面是三个应用Unity IPreprocessShaders的例子,每个例子都供了具体的现。 例子1:批改Shader的属性在这个例子中,咱们将演示如何批改Shader的属性。 using UnityEngine;using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class ShaderPreprocessor : IPreprocessShaders{ public int callbackOrder { get { return 0; } } public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> shaderCompilerData) { if (snippet.passType == PassType.ForwardBase) { foreach (var data in shaderCompilerData) { data.shaderCompilerOptions.Add("d3d11_no_compute_shaders", "true"); } } }}在这个例子中,咱们实现了IPreprocessShaders接口,并重写了它的OnProcessShader办法。在这个办法中,咱们首先判断以后的Shader是否是ForwardBase类型的。而后,咱们遍历所有的ShaderCompilerData,并向它们的shaderCompilerOptions中增加一个选项。 ...

May 28, 2023 · 1 min · jiezi

关于c#:Unity的IActiveBuildTargetChanged深入解析与实用案例

Unity IActiveBuildTargetChangedUnity IActiveBuildTargetChanged是Unity引擎中的一个十分有用的性能,它能够让开发者在切换构建平台时自定义哪些操作须要被执行。这个性能能够帮忙开发者更好地管制我的项目的构建过程,确保在切换构建平台时执行必要的操作。在本文中,咱们将介绍Unity IActiveBuildTargetChanged的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IActiveBuildTargetChanged的应用办法Unity IActiveBuildTargetChanged是一个事件,它在切换构建平台时被触发。在这个事件中,咱们能够编写咱们须要执行的操作,并且能够获取以后的构建平台。下是一个简略的例子,演示了如何在切换构建平台时执行一些操作: using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;public class BuildHandler : IActiveBuildTargetChanged{ public int callbackOrder { get { return 0; } } public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget) { if (newTarget == BuildTarget.Android) { // Do something for Android build target } else if (newTarget == BuildTarget.iOS) { // Do something for iOS build target } else { // Do something for other build targets } }}在这个例子中,咱们实现了IActiveBuildTargetChanged接口,并重写了它的OnActiveBuildTargetChanged办法。在这个办法中,咱们首先获取以后的构建平台。而后,咱们依据以后的构建平台执行相应的操作。 ...

May 28, 2023 · 1 min · jiezi

关于c++:Coke一优秀的C-Workflow支持协程啦

Coke(一):你好,世界C++ Workflow是一款高性能的异步编程范式,自Github开源以来,曾经收货了一万多枚Star,失去了越来越多的认可。 Coke我的项目是一个高性能的协程库,基于C++ 20提供的协程组件开发,提供一组简洁的异步接口,而其后盾则是由C++ Workflow强力驱动。应用Coke能够轻松地创立协程工作,并通过C++ Workflow的调度器高效地调度和执行,Coke心愿为大家带来一种新鲜的体验C++ Workflow的形式。 作为开篇,本文介绍大家进入编程世界常遇到的第一个示例:Hello World。 #include <iostream>#include <chrono>#include "coke/coke.h"coke::Task<> helloworld(size_t n, std::chrono::milliseconds ms) { for (size_t i = 0; i < n; i++) { // 每两次打印之间期待500毫秒,与同步期待不同,异步期待不会阻塞任何线程 if (i != 0) co_await coke::sleep(ms); // 向屏幕打印 Hello World std::cout << "Hello World" << std::endl; }}int main() { // 启动协程工作,并期待其实现 coke::sync_wait(helloworld(3, std::chrono::milliseconds(500))); return 0;}Coke我的项目正在开发中,有想法或倡议的同学欢送提Issue或Pull request! 本系列文章同步公布于集体网站和知乎专栏,转载请注明起源,以便读者及时获取最新内容及勘误。

May 27, 2023 · 1 min · jiezi

关于c#:Unity的IPostBuildPlayerScriptDLLs深入解析与实用案例

Unity IPostBuildPlayerScriptDLLsUnity IPostBuildPlayerScriptDLLs是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目后自定义哪些文件须要被复制到输入目录中。这个性能能够帮忙开发者更好地管制我的项目的构建过程,确保输入目录只蕴含必要的DLL文件。在本文中,咱们将介绍Unity IPostBuildPlayerScriptDLLs的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IPostBuildPlayerScriptDLLs的应用办法Unity IPostBuildPlayerScriptDLLs是一个接口,它蕴含一个名为OnPostBuildPlayerScriptDLLs办法。在这个办法中,咱们能够编写咱们须要执行的操作,并且能够获取构建报告。下是一个简略的例子,演示了如何在构建我的项目后自定义哪些DLL文件须要被复制到输入目录中: using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEditor.Callbacks;using System.IO;public class BuildHandler : IPostBuildPlayerScriptDLLs{ public int callbackOrder { get { return 0; } } public void OnPostBuildPlayerScriptDLLs(BuildReport report) { string outputDirectory = Path.GetDirectoryName(report.summary.outputPath); string[] dllFiles = Directory.GetFiles(outputDirectory, "*.dll", SearchOption.AllDirectories); foreach (string dllFile in dllFiles) { if (!dllFile.Contains("MyNamespace")) { File.Delete(dllFile); } } }}在这个例子中,咱们实现了IPostBuildPlayerScriptDLLs接口,并重写了它的OnPostBuildPlayerScriptDLLs办法。在这个办法中咱们首先获取输入目录的门路。而后,咱们遍历输入目录中的所有DLL文件,如果DLL文件的名称不蕴含"MyNamespace",则将其删除。 应用例子上面是三个应用Unity IPostBuildPlayerScriptDLLs的例子,每个例子都供了具体的实现。 例子1:只复制指定的DLL文件在这个例子中,咱们将演示如何在构建我的项目后只复制指定的DLL文件。 using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEditor.Callbacks;using System.IO;public class BuildHandler : IPostBuildPlayerScriptDLLs{ public int callbackOrder { get { return 0; } } public void OnPostBuildPlayerScriptDLLs(BuildReport report) { string outputDirectory = Path.GetDirectoryName(report.summary.outputPath); string[] dllFiles = Directory.GetFiles(outputDirectory, "*.dll", SearchOption.AllDirectories); foreach (string dllFile in dllFiles) { if (dllFile.Contains("MyNamespace")) { File.Copy(dllFile, Path.Combine(outputDirectory, Path.GetFileName(dllFile)), true); } } }}在这个例子中,咱们实现了IPostBuildPlayerScriptDLLs接口,并重写了它的OnPostBuildPlayerScriptDLLs办法。在这个办法中,咱们首先获取输入目录的门路。而后,咱们遍历输入目录中的所有DLL文件,如果DLL文件的名称含"MyNamespace",则将其复制到输入目录中。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IFilterBuildAssemblies深入解析与实用案例

Unity IFilterBuildAssembliesUnity IFilterBuildAssemblies是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目时自定义哪些程序集须要被蕴含在构建中,哪些程序集须要被排除在建之外。这个性能能够帮忙开发者更好地管制我的项目的构建过程,缩小构建工夫和构建大小。在本文中,咱们将介绍Unity IFilterBuildAssemblies的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IFilterBuildAssemblies的应用办法Unity IFilterBuildAssemblies是一个接口,它蕴含一个名为Filter办法。在这个办法中,咱们能够编写咱们须要执行的操作,并且能够获取构建报告。下是一个简略的例子,演示了如何在构建我的项目时自定义哪些程序集须要被蕴含在构建中,哪些程序集须要被排除在构建外: using UnityEditor.Build;using UnityEditor.Build.Reporting;using System.Collections.Generic;public class BuildHandler : IFilterBuildAssemblies{ public int callbackOrder { get { return 0; } } public void OnBeforeBuild() { // Do nothing } public void OnAfterBuild() { // Do nothing } public string[] OnFilterAssemblies(string[] assemblies) { List<string> filteredAssemblies = new List<string>(); foreach (string assembly in assemblies) { if (assembly.Contains("MyNamespace")) { filteredAssemblies.Add(assembly); } } return filteredAssemblies.ToArray(); }}在这个例子中,咱们实现了IFilterBuildAssemblies接口,并重写了它的OnFilterAssemblies办法。在这个办法中,咱们首先创立了一个空的List<string>对象,用于存储须要蕴含在构建中的程序集。而后,咱们遍历所有的程序集,如果程序集的名称蕴含"MyNamespace",则将其增加到List<string>对象中。最初,咱们将List<string>对象转换为string[]数组,并返回这个数组。 应用例子上面是三个应用Unity IFilterBuildAssemblies的例子,每个例子都供了具体的实现。 例子1:只蕴含指定的程序集在这个例子中,咱们将演示如何在构建我的项目时只蕴含指定的程序集。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IPostprocessBuildWithReport深入解析与实用案例

Unity IPostprocessBuildWithReportUnity IPostprocessBuildWithReport是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目后主动执行一些操作,并且能够获取构建报告。这个性能能够帮忙开发进步工作效率,缩小手动操作的工夫和错误率。在本文中,咱们将介绍Unity IPostprocessBuildWithReport的应用办法,并提供三个应用例子,帮忙读者更好地了解这个。 Unity IPostprocessBuildWithReport的应用办法Unity IPostprocessBuildWithReport是一个接口,它蕴含一个名为PostprocessBuild办法。在这个办法中,咱们能够编写咱们须要执行的操作,并且能够获取构建报告。下是一个简略的例子,演示了如何在构建我的项目后主动关上目录,并获取构建报: using UnityEditor.Build.Reporting;using UnityEngine;using System.Diagnostics;public class BuildHandler : IPostprocessBuildWithReport{ public int callbackOrder { get { return 0; } } public void OnPostprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; Process.Start(outputPath); Debug.Log(report.summary.result.ToString()); }}在这个例子中,咱们实现了IPostprocessBuildWithReport接口,并重写了它的OnPostprocessBuild办法。在这个办法中,首先获取构建报告的门路,而后应用Process.Start办法关上这个输入目录。最初,咱们应用Debug.Log办法输入构建报告的后果。 应用例子上面是三个应用Unity IPostprocessBuildWithReport的例子,每个例子都提供了具体的实现。 例子1:主动上传构建后果在这个例子中,咱们将演示如何在构建我的项目后主动上传构建后果,并获取构报告。 using UnityEditor.Build.Reporting;using UnityEngine;using System.Net;using System.IO;public class BuildHandler : IPostprocessBuildWithReport{ public int callbackOrder { get { return 0; } } public void OnPostprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; string url = "http://myserver.com/upload.php"; WebClient client = new WebClient(); client.UploadFile(url, outputPath); Debug.Log(report.summary.result.ToString()); }}在这个例子中,咱们实现了IPostprocessBuildWithReport接口,并重写了它的OnPostprocessBuild办法。在这个办法中,咱们首先获取构建报告的输入门路,而后指定上传的URL,创立一个WebClient对象,并调用它的UploadFile办法,将构建后果上传到指定的URL。最初,咱们应用Debug.Log办法输入建报告的后果。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IPreprocessBuildWithReport深入解析与实用案例

Unity IPreprocessBuildWithReportUnity IPreprocessBuildWithReport是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目时主动执行一些操作,并且能够获取构建报告。这个性能能够帮忙开发者进步工作效率,缩小手动操作的工夫和错误率。在本文中,咱们将介绍Unity IPreprocessBuildWithReport的应用办法,并提供三个应用例子,帮忙读者更好地了解这个。 Unity IPreprocessBuildWithReport的应用办法Unity IPreprocessBuildWithReport是一个接口,它蕴含一个名为processBuild办法。在这个办法中,咱们能够编写咱们须要执行的操作,并且能够获取构建报告。下是一个简略的例子,演示了如何在构建我的项目时主动关上目录,并获取构建报告: using UnityEditor;using UnityEngineusing UnityEditor.Build;using UnityEditor.Build.Reporting;using System.Diagnostics;public class BuildHandler : IPreprocessBuildWithReport{ public int callbackOrder { get { return 0; } } public void OnPreprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; Process.Start(outputPath); Debug.Log(report.summary.result.ToString()); }}在这个例子中,咱们实现了IPreprocessBuildWithReport接口,并重写了它的PreprocessBuild办法。在这个办法中,首先获取构建报告的输入门路,而后应用Process.Start办法关上这个输入目录。最初,咱们应用Debug.Log办法输入构建报告的后果。 应用例子上面是三个应用Unity IPreprocessBuildWithReport的例子,每个例子都提供了具体的实现。 例子1:主动上传构建后果在这个例子中,咱们将演示如何在构建我的项目时主动上传构建后果,并获取构建报告。 using UnityEditor;using UnityEngine;using UnityEditor.Build;using UnityEditor.Build.Reporting;using System.Net;using System.IO;public class BuildHandler : IPreprocessBuildWithReport{ public int callbackOrder { get { return 0; } } public void OnPreprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; string url = "http://myserver.com/upload.php"; WebClient client = new WebClient(); client.UploadFile(url, outputPath); Debug.Log(report.summary.result.ToString()); }}在这个例子中,咱们实现了IPreprocessBuildWithReport接口,并重写了它的PreprocessBuild办法。在这个办法中,咱们首先获取构建报告的输入门路,而后指定上传的URL,创立一个WebClient对象,并调用它的UploadFile办法,将构建后果上传到指定的URL。最初,咱们应用Debug.Log办法输入构建报告的后果。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的BuildPlayerProcessor深入解析与实用案例

Unity BuildPlayerProcessorUnity BuildPlayerProcessor是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目时主动执行一些操作。这个性能能够帮忙开发者进步工作效率,缩小手动操作的工夫和错误率。在本文中,咱们将介绍Unity BuildPlayerProcessor的应用办法,并提供三个应用例子,帮忙读者更好地了解这个。 Unity BuildPlayerProcessor的应用办法Unity BuildPlayerProcessor是一个动态类,它蕴含一个名为BuildPlayer的静态方法。在这个办法中,咱们能够编写咱们须要执行的操作。下是一个简略的例子,演示了如何在构建我的项目时主动关上目录: using UnityEditor;using UnityEngine;using System.Diagnostics;public class BuildHandler{ [MenuItem("Build/Build and Open Output Folder")] public static void BuildAndOpenOutputFolder() { string outputPath = EditorUtility.SaveFolderPanel("Choose Location of Built Game", "", ""); if (outputPath.Length == 0) return; BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.scenes = EditorBuildSettings.scenes; buildPlayerOptions.locationPathName = outputPath; buildPlayerOptions.target = BuildTarget.StandaloneWindows64; buildPlayerOptions.options = BuildOptions.None; BuildPipeline.BuildPlayer(buildPlayerOptions); Process.Start(outputPath); }}在这个例子中,咱们首先应用EditorUtility的SaveFolderPanel办法获取构建我的项目的输入门路。而后,咱们创立一个BuildPlayerOptions,并设置它的scenes、locationPathName、target和options属性。接着,咱们调用BuildPipeline的BuildPlayer办法,构建我的项目。最初,咱们应用Process.Start办法关上这个输入目录。 应用例子上面是三个应用Unity BuildPlayerProcessor的例子,每例子都提供了具体的实现。 例子1:主动上传构建后果在这个例子中,咱们将演示如何在构建我的项目时主动上传构建后果。 using UnityEditor;using UnityEngine;using System.Net;using System.IO;public class BuildHandler{ [MenuItem("Build/Build and Upload")] public static void BuildAndUpload() { string outputPath = EditorUtility.SaveFolderPanel("Choose Location of Built Game", "", ""); if (outputPath.Length == 0) return; BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions(); buildPlayerOptions.scenes = EditorBuildSettings.scenes; buildPlayerOptions.locationPathName = outputPath; buildPlayerOptions.target = BuildTarget.StandaloneWindows64; buildPlayerOptions.options = BuildOptions.None; BuildPipeline.BuildPlayer(buildPlayerOptions); string url = "http://myserver.com/upload.php"; WebClient client = new WebClient(); client.UploadFile(url, outputPath); }}在这个例子中,咱们首先应用EditorUtility的SaveFolderPanel办法获取构建我的项目的输入门路。而后,咱们创立一个BuildPlayerOptions对象,并设置它的scenes、locationPathName、target和options属性。接着,调用BuildPipeline的BuildPlayer办法,构建我的项目。最初,咱们指定上传的URL,创立一个WebClient对象,并调用它的UploadFile办法,将构建后果上传到指定的URL。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IPostprocessBuild深入解析与实用案例

Unity IPostprocessBuild技术文章Unity IPostprocessBuild是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目后主动执行一些操作。这个性能能够帮忙开发者进步工作效率,缩小手动操作的工夫和错误率。在本文中,咱们将介绍Unity IPostprocessBuild的应用办法,并提供三个应用例子,帮忙读者更好地了解这个。 Unity IPostprocessBuild的应用办法Unity IPostprocessBuild的应用办法与IPreprocessBuild相似,只须要在Unity我的项目中创立一个Editor文件夹,而后在这个文件夹中创立一个C#脚本,名为BuildHandler.cs。在这个脚本中,咱们须要应用Unity的Editor命名空间,并实现IPostprocessBuild接口。而后,咱们须要重写OnPostprocessBuild办法,这个办法会在构建我的项目后主动执行。在这个中,咱们能够编写咱们须要执行的操作。上面是一个简略的例子,演示了如何在构建我的项目后主动关上目录: using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEngine;using System.Diagnostics;public class BuildHandler : IPostprocessBuild{ public int callbackOrder { get { return 0; } } public void OnPostprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; Process.Start(outputPath); }}在这个例子中,咱们实现了IPostprocessBuild接口,并重写了OnPostprocessBuild办法。在这个办法中,咱们首先获取构建我的项目的输入门路,而后应用Process.Start办法关上这个输入目录。 应用例子上面是三个应用Unity IPostprocessBuild的例子,每个例子都提供了具体的实现。 例子1:主动上传构建后果在这个例子中,咱们将演示如何在构建我的项目后主动上传构建后果。 using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEngine;using System.Net;using System.IO;public class BuildHandler : IPostprocessBuild{ public int callbackOrder { get { return 0; } } public void OnPostprocessBuild(BuildReport report) { string outputPath = report.summary.outputPath; string url = "http://myserver.com/upload.php"; WebClient client = new WebClient(); client.UploadFile(url, outputPath); }}在这个例子中,咱们首先获取构建我的项目的输入门路,而后指定上传的URL。接着,咱们创立一个WebClient对象,并调用它的UploadFile办法,将构建后果上传到指定的URL。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的IPreprocessBuild深入解析与实用案例

Unity IPreprocessBuildUnity IPreprocessBuild是Unity引擎中的一个十分有用的性能,它能够让开发者在构建我的项目时主动执行一些操作。这个性能能够帮忙开发者进步工作效率,缩小手动操作的工夫和错误率。在本文中咱们将介绍Unity IPreprocessBuild的应用办法,并提供三个应用例子,帮忙读者更好地了解这个性能。 Unity IPreprocessBuild的应用办法Unity IPreprocessBuild的应用办法非常简单,只须要在Unity我的项目中创立一个Editor文件夹,而后在这个文件夹中创立一个C#脚本,命名为BuildHandler.cs。在这个脚本中,咱们须要应用Unity的Editor命名空间,并实现IPreprocessBuild接口。而后,咱们须要重写OnPreprocessBuild办法,这个办法会在构建我的项目时主动执行。在这个办法中,咱们能够编写咱们须要执行的操作上面是一个简略的例子,演示了如何在构建我的项目时主动批改PlayerSettings: using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEngine;public class BuildHandler : IPreprocessBuild, IPostprocessBuild{ public int callbackOrder { get { return 0; } } public void OnPreprocessBuild(BuildReport report) { PlayerSettings.companyName = "My Company"; PlayerSettings.productName = "My Product"; } public void OnPostprocessBuild(BuildReport report) { Debug.Log("Build completed successfully!"); }}在这个例子中,咱们实现了IPreprocessBuild和IPostprocessBuild接口,并重写了OnPreprocessBuild和OnPostprocessBuild办法。在OnPreprocessBuild办法中,咱们批改了PlayerSettings的companyName和productName属性。在OnPostprocessBuild办法中,咱们输入了一条日志,示意构建我的项目曾经实现。 应用例子上面是三个应用Unity IPreprocessBuild的例子,每个例子都提供了具体的实现。 例子1:主动批改场景在这个例子中,咱们将演示如何在构建我的项目时主动批改场景。 using UnityEditor;using UnityEditor.Build;using UnityEditor.Build.Reporting;using UnityEngine;using UnityEngine.SceneManagement;public class BuildHandler : IPreprocessBuild{ public int callbackOrder { get { return 0; } } public void OnPreprocessBuild(BuildReport report) { Scene scene = SceneManager.GetSceneByName("MyScene"); if (scene.IsValid()) { SceneManager.SetActiveScene(scene); GameObject[] objects = scene.GetRootGameObjects(); foreach (GameObject obj in objects) { obj.transform.position = Vector3.zero; } } }}在这个例子中,咱们首先获取指定的场景,而后将这个场景设置为流动场景。接着,咱们获取场景中的所有根GameObject,并将它们的地位设置为Vector3.zero。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity的OnOpenAsset深入解析与实用案例

Unity OnOpenAsset在Unity中,OnOpenAsset是一个十分有用的回调函数,它能够在用户双击资源文件时主动关上一个编辑器窗口。这个回调函数能够用于自定义资源编辑,进步工作效率。本文将介绍OnOpenAsset的应用办法,并提供三个应用例子。 OnOpenAsset的应用办法OnAsset是Unity Editor的一个回调函数,它会在用户双击资源文件时被调用。这个回调函数有两个参数:instanceID和lineNumber。instanceID是资源的惟一标识符,lineNumber是资源文件中的行号。咱们能够利用这两个参数来关上资源编辑器。 要应用OnOpenAsset,咱们须要在Editor文件夹下创立一个脚本,并在脚本中实现OnOpenAsset办法。上面是一个简略的例子: using UnityEditor;using UnityEngine;public class MyEditor : Editor{ [UnityEditor.Callbacks.OnOpenAsset] public static bool OnOpenAsset(int instanceID, int lineNumber) { // 获取资源门路 string assetPath = AssetDatabase.GetAssetPath(instanceID); // 判断资源类型 if (assetPath.EndsWith(".txt")) { // 关上文本编辑器 TextAsset asset = AssetDatabase.LoadAssetAtPath<TextAsset>(assetPath); UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(assetPath, lineNumber); return true; } // 返回false示意不解决该资源 return false; }}在这个例子中,咱们判断资源类型是否为txt文件,如果是则关上文本编辑器。咱们能够依据须要自定义资源编辑器。 应用例案例1:关上场景文件using UnityEditor;using UnityEngine;public class SceneOpener : Editor{ [UnityEditor.Callbacks.OnOpenAsset] public static bool OnOpenAsset(int instanceID, int lineNumber) { // 获取资源门路 string assetPath = AssetDatabase.GetAssetPath(instanceID); // 判断资源类型 if (assetPath.EndsWith(".unity")) { // 关上场景文件 EditorSceneManager.OpenScene(assetPath); return true; } // 返回false示意不解决该资源 return false; }}在这个例子中,咱们判断资源类型是否为unity景文件,如果是则关上场景文件。 ...

May 27, 2023 · 1 min · jiezi

关于c#:Unity中的PostProcessBuild深入解析与实用案例

Unity中的PostProcessBuild:深刻解析与实用案例在Unity游戏开发中,咱们常常须要在构建实现后对生成的应用程序进行一些额定的解决。这时,咱们能够应用Unity提供的PostProcessBuild性能。本文将具体介绍Unity中的PostProcessBuild办法,并通过三个实用案例来展现其弱小的性能。 什么是PostProcessBuild?PostProcessBuild是Unity中的一个性能,容许咱们在构建实现后对生成的应用程序进行一些额定的解决。这能够帮忙咱们自动化一些构建后的工作,如批改配置文件、拷贝资源等。 如何应用PostProcessBuild?要应用PostProcessBuild,咱们须要在Unity我的项目的Assets目录下创立一个名为Editor的文件夹,并在其中创立一个C#脚本,用于编写构建后处理逻辑。而后,咱们须要在脚本中定义一个带有PostProcessBuildAttribute个性的静态方法,该办法将在构建实现后主动执行。 上面是一个简略的PostProcessBuild脚本示例: using UnityEditor;using UnityEditor.Callbacks;using UnityEngine;public class MyPostProcessBuild{ [PostProcessBuild] public static void OnPostProcessBuild(BuildTarget target, string path) { // 在这里编写构建后处理逻辑 }}实用案例接下来,咱们将通过三个实用案例来展现PostProcessBuild的性能。 案例1:批改配置文件在这个案例中,咱们将应用PostProcessBuild在构建实现后主动批改应用程序的配置文件。这能够帮忙咱们依据不同的构建指标生成不同的配置。 首先,咱们须要在Editor文件夹下创立一个C#脚本,用于编写构建后处理逻辑。 using UnityEditor;using UnityEditor.Callbacks;using UnityEngine;public class ConfigModifier{ [PostProcessBuild] public static void OnPostProcessBuild(BuildTarget target, string path) { // 在这里编写批改配置文件的逻辑 }}接下来,咱们能够在OnPostProcessBuild办法中编写批改配置文件的逻辑,如依据构建指标批改数据库连贯字符串等。 在这个例子中,咱们依据不同的构建指标应用程序的配置文件。在OnPostProcessBuild办法中,咱们首先获取应用程序的配置文件门路,而后依据不同的构建指标批改配置文件内容。 using UnityEditor;using UnityEditor.Callbacks;using UnityEngine;using System.IO;public ConfigModifier{ [PostProcessBuild] public static void OnPostProcessBuild(BuildTarget target, string path) { // 获取应用程序的配置文件门路 string configPath = Path.Combine(Path.GetDirectoryName(path), "config.txt"); // 依据不同的构建指标批改配置文件 if (target == BuildTarget.StandaloneWindows64) { File.WriteAllText(configPath, "Windows配置"); } else if (target == BuildTarget.iOS) { File.WriteAllText(configPath, "iOS配置"); } else if (target == BuildTarget.Android) { File.WriteAllText(configPath, "Android配置"); } }}案例2:拷贝资源文件首先,咱们须要在Editor文件夹下创立一个C#脚本,用于编写构建后处理逻辑。 ...

May 27, 2023 · 2 min · jiezi

关于c#:Unity中的RegisterPlugins深入解析与实用案例

Unity中的RegisterPlugins:深刻解析与实用案例在Unity游戏开发中,咱们常常须要应用第三方插件来实现一些特定的性能。为了让这些插件可能在Unity中失常工作,咱们须要对它们进行注册。本文将具体介绍Unity中的RegisterPlugins办法,并通过三个实用案例来展现其弱小的性能。 什么是RegisterPlugins?RegisterPlugins是Unity中的一个办法,用于在我的项目中注册第三方插件。注册插件后,咱们能够在Unity中间接调用这些插件提供的性能,而无需进行额定的配置。 如何应用RegisterPlugins?要应用RegisterPlugins,咱们须要在Unity我的项目中创立一个名为Plugins的文件夹,并将第三方插件的库文件(如.dll、.so、.a等)放入该文件夹。而后,咱们须要在我的项目的Assets目录下创立一个名为Editor的文件夹,并在其中创立一个C#脚本,用于编写插件注册逻辑。 上面是一个简略的RegisterPlugins脚本示例: using UnityEditor;using UnityEngine;public class MyPluginRegister{ [InitializeOnLoadMethod] private static void RegisterPlugins() { // 在这里编写插件注册逻辑 }}实用案例接下来,咱们将通过三个实用案例来展现RegisterPlugins的性能。 案例1:注册SQLite数据库插件在这个案例中,咱们将应用RegisterPlugins来注册一个名为SQLite的数据库插件。咱们将在Unity我的项目中应用这个插件来实现本地数据库的存储和查问性能。 首先,咱们须要下载SQLite插件的库文件,并将其放入我的项目的Plugins文件夹。而后,咱们须要在Editor文件夹下创立一个C#脚本,用于编写插件注册逻辑。 using UnityEditor;using UnityEngine;public class SQLitePluginRegister{ [InitializeOnLoadMethod] private static void RegisterPlugins() { // 在这里编写SQLite插件的注册逻辑 }}接下来,咱们能够在我的项目中应用SQLite插件提供的性能,如创立数据库、执行SQL语句等。 案例2:注册Firebase插件在这个案例中,咱们将应用RegisterPlugins来注册一个名为Firebase的插件。咱们将在Unity我的项目中应用这个插件来实现实时数据库、认证和云存储等性能。 首先,咱们须要下载Firebase插件的库文件,并将其放入我的项目的Plugins文件夹。而后,咱们须要在Editor文件夹下创立一个C#脚本,用于编写插件注册逻辑。 using UnityEditor;using UnityEngine;public class FirebasePluginRegister{ [InitializeOnLoadMethod] private static void RegisterPlugins() { // 在这里编写Firebase插件的注册逻辑 }}接下来,咱们能够在我的项目中应用Firebase插件提供的性能,如实时数据库的读写、用户认证等。 案例3:注册ARCore插件在这个案例中,咱们将应用RegisterPlugins来注册一个名为ARCore的插件。咱们将在Unity我的项目中应用这个插件来实现加强事实(AR)性能。 首先,咱们须要下载ARCore插件的库文件,并将其放入我的项目的Plugins文件夹。而后,咱们须要在Editor文件夹下创立一个C#脚本,用于编写插件注册逻辑。 using UnityEditor;using UnityEngine;public class ARCorePluginRegister{ [InitializeOnLoadMethod] private static void RegisterPlugins() { // 在这里编写ARCore插件的注册逻辑 }}接下来,咱们能够在我的项目中应用ARCore插件提供的性能,如追踪立体、搁置虚构物体等。 总结通过以上三个实用案例,咱们能够看到RegisterPlugins在Unity游戏开发中的弱小性能。它能够帮忙咱们轻松地集成第三方插件,进步游戏的可玩性和用户体验。心愿本文能对您在Unity游戏开发中的实际提供一些帮忙。 本文由博客一文多发平台 OpenWrite 公布!

May 27, 2023 · 1 min · jiezi

关于c#:Unity中的PostProcessScene深入解析与实用案例

Unity中的PostProcessScene:深刻解析与实用案例在Unity游戏开发中,咱们常常须要对场景进行后处理,以实现更丰盛的视觉效果。Unity提供了一个名为PostProcessScene的性能,能够让咱们在场景加载实现后,对场景进行一系列的解决。本文将具体介绍PostProcessScene的应用办法,并通过三个实用案例来展现其弱小的性能。 什么是PostProcessScene?PostProcessScene是Unity中的一个事件,当场景加载实现后,它会被触发。咱们能够在这个事件中编写自定义的脚本,对场景进行后处理。这些解决能够包含批改场景中的游戏对象、增加或删除组件、调整光照等。 如何应用PostProcessScene?要应用PostProcessScene,咱们须要创立一个脚本,并在其中编写解决逻辑。而后,咱们须要将这个脚本挂载到一个游戏对象上,并在Unity编辑器中将该游戏对象设置为“DontDestroyOnLoad”,以确保它在场景加载时不会被销毁。 上面是一个简略的PostProcessScene脚本示例: using UnityEngine;using UnityEngine.SceneManagement;public class MyPostProcessScene : MonoBehaviour{ private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { // 在这里编写场景后处理逻辑 }}实用案例接下来,咱们将通过三个实用案例来展现PostProcessScene的性能。 案例1:主动调整光照强度在这个案例中,咱们将应用PostProcessScene来主动调整场景中的光照强度。咱们将依据场景中的工夫(白天或夜晚)来设置不同的光照强度。 using UnityEngine;using UnityEngine.SceneManagement;public class AutoAdjustLightIntensity : MonoBehaviour{ public Light mainLight; public float dayIntensity = 1.0f; public float nightIntensity = 0.5f; private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (mainLight == null) { mainLight = GameObject.FindWithTag("MainLight").GetComponent<Light>(); } if (IsDaytime()) { mainLight.intensity = dayIntensity; } else { mainLight.intensity = nightIntensity; } } private bool IsDaytime() { // 在这里编写判断是否为白天的逻辑 // 示例:return DateTime.Now.Hour >= 6 && DateTime.Now.Hour <= 18; return true; }}案例2:动静增加组件在这个案例中,咱们将应用PostProcessScene来动静地为场景中的游戏对象增加组件。咱们将为所有带有“Enemy”标签的游戏对象增加一个名为“Health”的组件。 ...

May 27, 2023 · 2 min · jiezi

关于c++:结合实践重学C

联合实际重学C++在计算机科学畛域,C++是一种高级编程语言。它反对面向对象编程和泛型编程,并且具备弱小的性能和灵活性。如果你想要成为一名优良的程序员,学习C++是必不可少的。 然而,C++的学习过程并不容易。如果没有联合实际去学习,很容易呈现了解上的艰难。因而,在这篇文章中,咱们将介绍一些联合实际的办法,以帮忙你更好地把握C++。 抉择一个我的项目首先,抉择一个C++我的项目作为学习的指标。这个我的项目能够是一个简略的控制台应用程序,也能够是一个简单的图形界面应用程序。无论你抉择什么样的我的项目,都须要确保它与你的趣味相干,并且不会让你失去急躁。 学习基础知识在开始编写代码之前,你须要先理解C++的基础知识。这包含变量、运算符、数组、指针、函数等等。能够通过浏览书籍、查找在线教程或加入课程来学习这些内容。 编写代码当你把握了根本的C++常识后,就能够开始编写代码了。在这个过程中,你须要留神以下几点: 应用正文:为了更好地了解你的代码,你须要增加正文来解释每一行代码的作用。逐渐构建程序:不要一口气写出整个应用程序。相同,从简略的代码块开始,并逐渐减少性能。测试代码:在编写代码时,你须要测试它是否失常工作。通过输出不同的数据并查看后果,能够确定代码是否正确。学习高级主题当你可能编写根本的C++代码时,就能够开始学习更高级的主题,例如模板、异样解决、多线程编程等等。这些主题能够让你编写更简单和高效的应用程序。 加入开源我的项目最初,加入开源我的项目是一个十分好的学习C++的办法。通过加入开源我的项目,你能够与其余程序员单干,并且有机会参加到大型项目中。此外,你还能够从其余程序员的教训中学习,并且将本人的代码提交到GitHub等开源代码库中。 总之联合实际的形式是学习C++的最佳办法之一。通过抉择一个我的项目、把握基础知识、编写代码、学习高级主题和加入开源我的项目,你能够更快地把握C++编程语言,并成为一名优良的程序员。

May 26, 2023 · 1 min · jiezi

关于c#:Unity中的InitializeOnLoad特性深入解析与实践

Unity中的InitializeOnLoad个性:深刻解析与实际在Unity开发过程中,咱们常常须要在编辑器启动时或脚本从新编译后执行一些操作,例如初始化数据、注册事件等。这时,咱们能够应用InitializeOnLoad个性来实现这一需要。本文将具体介绍InitializeOnLoad个性的用法,并通过三个理论案例来展现其利用场景。 1. InitializeOnLoad个性简介InitializeOnLoad是Unity引擎提供的一种个性,用于在编辑器启动时或脚本从新编译后主动执行指定的操作。这种个性非常适合用于在编辑器启动时执行一些初始化操作,以确保我的项目在启动后可能失常运行。 要应用InitializeOnLoad个性,只需在编辑器脚本中为一个动态类增加该个性即可。例如: using UnityEditor;using UnityEngine;[InitializeOnLoad]public static class MyInitializer{ static MyInitializer() { Debug.Log("InitializeOnLoad called."); }}在这个例子中,咱们创立了一个名为MyInitializer的动态类,并为其增加了InitializeOnLoad个性。当编辑器启动时,MyInitializer类的动态构造函数将被主动调用,从而实现主动初始化的性能。 2. 理论案例上面咱们将通过三个理论案例来展现InitializeOnLoad个性的利用场景。 2.1 主动注册事件在某些状况下,咱们须要在编辑器启动时主动注册事件。例如,咱们可能须要在我的项目中监听某个自定义事件,以便在事件触发时执行相应的操作。这时,咱们能够应用InitializeOnLoad个性来实现主动注册。 using UnityEditor;using UnityEngine;[InitializeOnLoad]public static class EventRegistrar{ static EventRegistrar() { Debug.Log("Event registered."); MyCustomEventManager.OnCustomEvent += HandleCustomEvent; } private static void HandleCustomEvent(object sender, CustomEventArgs e) { Debug.Log("Custom event handled."); }}2.2 主动加载配置文件在某些状况下,咱们须要在编辑器启动时主动加载配置文件。例如,咱们可能须要在我的项目中保护一个全局配置文件,以便在运行时疾速读取配置信息。这时,咱们能够应用InitializeOnLoad个性来实现主动加载。 using UnityEditor;using UnityEngine;[InitializeOnLoad]public static class ConfigLoader{ static ConfigLoader() { Debug.Log("Config file loaded."); LoadConfigFile(); } private static void LoadConfigFile() { // Load the config file and parse its content. }}2.3 主动查看资源更新在某些状况下,咱们须要在编辑器启动时主动查看资源更新。例如,咱们可能须要在我的项目中查看近程服务器上的资源更新,以便在有新资源时及时下载并更新本地资源。这时,咱们能够应用InitializeOnLoad个性来实现主动查看。 ...

May 26, 2023 · 1 min · jiezi

关于c:Linux网络开发必学教程19分布式智能家居项目雏形

需要剖析客户端进入室内后可能被动发现服务(如,环境服务,灯光服务)各种服务能够有不同的载体(如:由不同设施提供)各种服务之间,服务与客户端之间齐全无耦合(服务可自在增减)客户端能够是挪动 APP ,能够是桌面软件 。。。技术可行性剖析发现服务: UDP 播送 + 自定义协定 客户端被动播送服务查问协定包服务设施接管到协定包,回复协定内容及协定应用形式服务自在增减:自定义协定 服务设施遵循雷同的协定:数据传输协定,服务提供模式,等客户端通过协定应用服务,无需关怀服务设施的状态及地位基础设施提供服务的设施(嵌入式,服务器,PC,等)必须具备联网能力,且遵循服务协定。 零碎概要设计 交互流程 零碎具体设计服务发现 客户端被动播送服务发现数据包 服务应答 服务设施将本机 IP 及可能提供的服务信息发回客户端 客户端具体设计通过播送服务发现数据包,收集以后环境的服务信息可用服务通过“菜单”形式出现,并提醒服务应用形式抉择服务后,连贯到对应设施,通过协定音讯发送服务申请命令收到设施回复后,断开设施连贯(申请 - 应答)服务端具体设计联网模块 设施提供服务前,必须联网(无线 or 有线)服务前端 接管服务发现数据包,并应答以后设施服务信息服务后端 服务设施驱动,如:温湿度传感器驱动,灯光管制驱动,等硬件选型这里展现应用的小熊派,运行 openharmony 。能够不用关怀硬件,间接在 PC 编写雷同网络性能可执行文件即可 服务设施软件架构设计 服务设施启动流程 几个问题设施上运行什么操作系统?设施运行的操作系统如何创立多个并行执行工作?设施如何通过 wifi 联网?设施上的网络编程通过什么接口实现?OpenHarmony 是什么凋谢原子基金会 (OpenAtom Foundation)旗下开源我的项目 定位是一个面项全场景的开源分布式操作系统我的项目蕴含了分布式操作系统所需的全副能力 包含内核层、零碎服务层、利用框架层华为及泛滥贡献者,在开源社区内间接奉献轻量零碎:硬件资源极其无限,反对的设施最小内存为 128KiB。可撑持的产品如智能家居畛域的连贯类模组、传感器设施、穿戴类设施等。小型零碎:面项利用处理器的设施,反对的设施最小内存为 1MBiB。可撑持的产品如智能家居畛域的 IP Camera、电子猫眼、路由器以及智慧出行的行车记录仪等。规范零碎:面项利用处理器例如 Arm Cortex-A 的设施,反对的设施最小内存为 128MiB, 能够提供加强的交互能力、3D GPU 以及硬件合成能力、更多控件以及动效更丰盛的图形能力、残缺的利用框架。可撑持的产品如高端的冰箱显示屏。OpenHarmony 轻量级零碎利用开发精要零碎组件裁剪与配置 .//vendor/hisilicon/hispark_pegasus/config.json板载性能裁剪与配置 .//device/hisilicon/hispark_pegasus/sdk_liteis/build/config/usr_config.mk在 application/sample/wifi-iot/app 目录下新建工程目录 (如:demo_server)工程目录下新建 BUILD.gn 文件批改 application 目录下的 BUILD.gn 文件画图 注册入口函数创立工作#include <stdio.h>#include <unistd.h>#include "ohos_init.h"#include "cmsis_os2.h"static void* Init_Task(const char* arg){ printf("[dt4sw] Hello, D.T.Software!\n"); return arg;}static void Main_Entry(void){ osThreadAttr_t attr = {0}; attr.name = "Init Task"; attr.stack_size = 1024 * 4; attr.priority = 20; if( osThreadNew((osThreadFunc_t)Init_Task, NULL, &attr) == NULL ) { printf("[dt4sw] Failed to create task!\n"); }}SYS_RUN(Main_Entry);

May 23, 2023 · 1 min · jiezi

关于c:基于C语言设计一个叫号系统

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档] 这道题的重点在于怎么解决患者的医治过程。大二上学期的理论课上,咱们在第一节的研究课上对于这道题的实现进行了探讨。本题的患者排队与数据结构中的队列构造完全符合,当患者挂号后,查看该科室是否还有闲暇的医生,若有,则间接进入进行医治。若没有,则进入该科室的诊疗队列排队。每个科室的排队状况通过查问各个队列的长度即可得悉。当工夫刷新,有病人的医生诊疗工夫发生变化,当变为 0 时,调配该病人 B 超工夫。对于须要 B 超的患者,进入 B 超等待队列,顺次进入各个 B 超室。 综合利用设计说明某医院一般门诊领有科室 15 个,每个科室值班医生 3 人;B 超室 1 个,有 3 台 B 超机。现需设计一个叫号零碎,通过挂号秩序,安顿每个科室叫号程序,各科室在诊断完病人后,依据其是否开具 B 超查看要求,安顿 B 超室的叫号程序,并在所有过程中,记录每位医生所看的病人及其听诊工夫。 需实现挂号过程,医生就诊过程。显示各科室、B超室目前排队状况。查看各医生就诊的所有病人。软件性能病人抉择科室进行挂号,主动调配患者编号显示各个科室与 B 超室以后仍在排队等待的人数显示每个医生(B 超室)以后病人还残余的诊疗(查看)工夫显示当天曾经过分钟数依据医生编号查问当天医生诊疗病人的记录依据工夫刷新,主动调配患者到对应的医生(B 超室)进行医治(查看)将所有就诊记录存于文件,运行完程序可进行保留(对应于医院一天的营业完结)查问就诊记录是通过数据文件读取比对实现的,当医生医治一个病人的同时,对数据文件进行写入。病人挂号零碎与主动调配诊室是通过建设病人的队列实现的,当工夫刷新,每个诊室的状况都会从新更新,从而实现挂号、就诊、查看的过程。而各科室、B 超室的排队状况只需查看病人的排队队列长度即可取得。设计思维这道题的重点在于怎么解决患者的医治过程。大二上学期的理论课上,咱们在第一节的研究课上对于这道题的实现进行了探讨。本题的患者排队与数据结构中的队列构造完全符合,当患者挂号后,查看该科室是否还有闲暇的医生,若有,则间接进入进行医治。若没有,则进入该科室的诊疗队列排队。每个科室的排队状况通过查问各个队列的长度即可得悉。当工夫刷新,有病人的医生诊疗工夫发生变化,当变为 0 时,调配该病人 B 超工夫。对于须要 B 超的患者,进入 B 超等待队列,顺次进入各个 B 超室。同样的,工夫刷新后 B 超室内患者查看工夫变为 0 时,患者的医治过程完结。B 超室会从 B 超的等待队列中寻找新的须要查看的患者。从事实中的排队联想到队列构造也是很失常的想法。 队列的元素为患者节点,节点自身有患者的各项信息,追随患者类进行传输。每个科室(包含 B 超室)均有一条患者队列,代表期待队列。患者医治状况的变动会引起患者节点的入队列与出队列。 而医生节点与 B 超室节点均需记录患者编号与剩余时间,而这两个节点的存储采纳程序表的构造(即数组)。 ui 界面中须要展现的局部,通过读取队列与医生数组、B 超室数组的数据即可解决。查问局部须要按行查问文件中的信息。

May 18, 2023 · 1 min · jiezi

关于c++:Makefile常用命令详解

在软件开发中,Makefile是一种十分罕用的自动化工具。Makefile文件蕴含了一系列规定,用于编译、打包、测试等操作,能够帮忙咱们自动化这些操作,进步我的项目的治理和编译效率。本文将介绍Makefile中罕用的命令,以及如何应用它们来编译和治理我的项目makemake命令是最根本的命令,用于执行Makefile文件中的规定。Makefile是由一系列规定组成的,每个规定由指标、依赖和命令三局部组成。make会依据这些规定,主动确定哪些文件须要从新编译,哪些文件不须要编译。通常,咱们能够应用如下命令运行make:  make [options] [target]其中,options是可选的参数,用于管制make的行为。例如,咱们能够应用“-j”参数指定并行编译的数量。target是要编译的指标文件名,能够省略。如果省略,则默认执行Makefile文件中的第一个指标。 cleanclean命令用于删除生成的指标文件。在编译过程中,咱们会生成一些两头文件和指标文件,这些文件可能会占用较多的磁盘空间。应用clean命令能够清理这些文件,开释磁盘空间。例如:  clean:    rm -rf *.o这条规定的作用是删除所有以“.o”结尾的文件。 allall命令用于生成所有的指标文件。通常,咱们在Makefile中会定义多个指标,应用all命令能够一次性编译所有指标。例如:  all: target1 target2 target3这条规定的作用是编译target1、target2、target3三个指标。 installinstall命令用于将生成的文件装置到指定的目录中。在编译实现后,咱们通常须要将生成的可执行文件或库文件装置到零碎中,以便其余程序应用。例如:  install: all    cp target /usr/local/bin/这条规定的作用是将编译生成的target文件拷贝到“/usr/local/bin/”目录下。 uninstalluninstall命令用于卸载已装置的文件。在装置实现后,咱们可能须要卸载已装置的文件,例如进行版本回滚。例如:  uninstall:    rm /usr/local/bin/target这条规定的作用是删除“/usr/local/bin/”目录下的target文件。 dependdepend命令用于自动更新源文件的依赖关系。在大型项目中,源文件之间可能存在简单的依赖关系,当一个源文件发生变化时,须要从新编译依赖于它的所有文件。应用depend命令能够自动更新依赖关系,防止手动保护依赖关系。例如:  depend:    gcc -M *.c > .depend这条规定的作用是生成一个.depend文件,保留所有源文件的依赖关系。 自定义命令除了上述常用命令外,Makefile还反对自定义命令。例如,咱们能够定义一个命令来运行我的项目的测试:  test:    ./run_tests这条规定的作用是运行我的项目的测试脚本。 高级个性Makefile还反对循环、条件语句等高级个性。例如,咱们能够应用循环来编译多个源文件:  objects = main.o foo.o bar.o  all: $(objects)  $(objects): %.o: %.c    gcc -c $< -o $@这条规定的作用是编译main.c、foo.c和bar.c三个源文件,生成对应的指标文件。其中,“%”示意通配符,示意匹配任意字符。 总结以上是罕用的Makefile命令,应用这些命令能够大大提高我的项目的治理和编译效率。另外,Makefile还反对循环、条件语句等高级个性,能够依据须要灵便应用。把握这些命令和个性,能够让你更加高效地治理和编译软件我的项目。

May 18, 2023 · 1 min · jiezi

关于c++:Cday12笔记无代码

C++day12笔记无代码1 设计类、求圆的周长1.1 关键字 class1.2 class + 类名 { 成员 }1.3 类的形成 : 成员函数 + 成员属性1.4 作用域 public : 公共作用域1.5 属性 : 半径1.6 行为 : 求圆周长、设置圆半径 、获取圆半径1.7 测试 : 实例化对象 通过类创建对象 Circle c1;1.8 给对象赋值 c1.setR(10) 获取半径 c1.getR(); 获取周长 c1.calculateZC();1.9 设计一个学生类,有姓名和学号,给姓名学号赋值,并且打印学生的信息2 内联函数2.1 内联函数的引出 --- 宏函数缺点2.1.1 必须保障运算完整性,加括号2.1.2 即便加了括号,有些状况仍然和预期后果不符2.1.3 宏函数 也不器重作用域2.2 内联函数 inline2.3 函数申明和实现必须同时加inline 才算内联函数2.4 类外部成员函数 默认后面加了inline关键字2.5 内联函数和编译器关系2.5.1 退出内联后只是对编译器的一个倡议,有些状况下编译器仍然不会依照内联形式处理函数2.5.2 循环、 判断、 函数体过于宏大、对函数取地址 ,不会依照内联解决2.5.3 一个好的编译器,会将短小的函数 暗藏的退出inline 关键字3 函数的默认参数以及占位参数3.1 默认参数3.1.1 在形参前面 = 默认值3.1.2 如果参数列表中 有一地位有了默认参数,那么从这个地位起从左到右都必须有默认参数3.1.3 函数的申明和实现 只能有一个有默认参数3.2 占位参数3.2.1 函数参数列表中 ( int )只写类型,调用必须要传入参数调用3.2.2 占位参数也能够有默认参数 (int = 0)3.2.3 目前用不到占位参数,前面学习符号重载才会用到4 函数重载4.1 满足条件4.1.1 同一个作用域,函数名称雷同4.1.2 函数参数 类型 、 个数、 程序不同4.2 函数的返回值 不能够作为函数重载条件4.3 援用 退出const 和不加const也能够作为重载条件4.4 函数重载碰到函数默认参数 也须要留神防止二义性5 extern C 浅析5.1 函数重载原理 编译器在底层会将函数名字做两次润饰,不便外部拜访函数体5.2 用处: 在C++下能够运行C语言的文件5.3 #ifdef __cplusplus 两个下划线 + c plus plus5.3.1 extern "C" {5.4 #endif5.5 #ifdef __cplusplus5.5.1 }5.6 #endif6 类的封装6.1 C语言的封装6.1.1 毛病:C语言下没有做类型转换的检测6.1.2 毛病2: 将属性和行为拆散6.2 C++封装6.2.1 将属性和行为作为一个整体,来体现生存中的事物6.2.2 将这些成员 加以权限管制6.3 权限6.3.1 public 私有权限6.3.2 protected 爱护权限6.3.3 private 公有权限6.4 C++中struct 和 class 区别6.4.1 struct 默认权限 public6.4.2 class 默认权限 private7 尽量将成员属性设置为公有7.1 设置为公有权限的属性,能够本人管制属性的读写操作7.2 能够将传入数据,进行有效性的检测8 ...

May 17, 2023 · 1 min · jiezi

关于c++:看动画轻松学习23种C设计模式我闻琵琶已叹息

download:看动画,轻松学习23种C++设计模式如听仙乐耳暂明音乐,心灵,美好生活人们常说“音乐是一种语言”,因为它不分国界、不分种族,可能用独特的形式传播情感和思维。在快节奏的古代生存中,很多人都深受各种压力的困扰,而寻找一个能够让本人放松、愉悦情绪的办法显得尤为重要。而听音乐就是其中一种很好的形式。 有一句流传甚广的名言:“如听仙乐耳暂明”。这句话出自唐代文学家白居易的《琵琶行》,他借助音乐的美好来表白对历史上妇女的同情和关爱。这句话意思是说,听到柔美的音乐时,心灵会因而失去短暂的安定和舒服,好像置身于仙境之中。 实际上,这句话的含意并不仅限于“霎时的安定”这一层面。当咱们凝听音乐时,不仅能够抚平焦虑和疲乏的情绪,还能够使咱们取得更深的思考和灵感。音乐能够激发出咱们心田最深处的情感和渴望,让咱们感触到生命的美妙和丰盛。同时,音乐还可能传播出一种超过语言、逾越文化的共鸣和情感,帮忙咱们与别人建设更严密的分割。 当然,不同的人喜爱的音乐类型也不尽相同。有些人喜爱古典音乐,因为它优雅、高贵,具备无奈言喻的韵味;有些人则喜爱流行音乐,因为它轻松、自在,可能很好地表白现代人的情感和思维。无论是什么类型的音乐,只有它可能触动你的心弦,传递给你真正的打动和力量,就是值得去凝听并收藏的。 总之,“如听仙乐耳暂明”这句话,通知咱们要用心去凝听音乐,尝试从中寻找生存的美妙和意义,让音乐成为咱们生存中不可或缺的一部分。

May 14, 2023 · 1 min · jiezi

关于c++:CC-从0到1系统精讲-项目开发综合基础课浔阳地僻无音乐

download:C/C++ 从0到1零碎精讲 我的项目开发综合基础课莫辞更坐弹一曲音乐,古琴,传统文化莫辞更是中国现代文人雅士中的代表人物之一,他是一位喜好古琴的文艺青年。据史料记录,莫辞更经常在宴会上弹奏古琴,给人们带来美好的音乐享受。其中最有名的就要数他“更坐弹一曲”的故事了。 相传有一次,莫辞更加入了一个宴会,过后的氛围非常热烈,人们喝着酒、谈着天。突然间,有人向莫辞更提出了一个挑战:“你能一边弹古琴,一边吟诗吗?”莫辞更并不慌乱,他微笑着承受了这个挑战,而后开始演奏起古琴来。他的指尖轻捷地拨动着琴弦,音乐随之流淌而出,像一朵绽开的花,漂亮而动人。同时,他还口吟着本人创作的诗歌,将音乐与诗意完满联合在一起。 这一幕场景,让在场的众人为之倾倒。他们惊叹于莫辞更的琴艺、诗才和气派,也由衷地感触到了中国传统文化的博大精深。 莫辞更“更坐弹一曲”的故事,至今仍被前人传颂不衰。这个故事通知咱们,艺术能够逾越时空的界线,它是人类智慧和理性的结晶。古琴作为中国传统音乐的代表,有着博大精深的历史渊源和独特的韵味,而莫辞更则将其演奏得酣畅淋漓,彰显出了中国文化的魅力与底蕴。 在当今社会,咱们应该更加关注和弘扬传统文化,让这些古老而神秘的艺术模式在古代焕发新的光辉。同时,咱们也要向莫辞更这样的前辈学习,用本人的才华和致力去发明属于本人的经典,为传统文化的倒退奉献本人的力量。

May 14, 2023 · 1 min · jiezi

关于c:C编译器和链接器的完全指南

C++是一种强类型语言,它的编译和链接是程序开发过程中不可或缺的两个环节。编译器和链接器是两个十分重要的概念。本文将具体介绍C++中的编译器和链接器以及它们的工作原理和应用办法。编译器编译器是将源代码转换为可执行文件的程序。在C++中,罕用的编译器有GCC和Clang。编译器的次要工作是将源代码翻译成汇编代码,而后再将汇编代码转换成机器码。编译器还能够进行优化,使得程序的执行效率更高。 在应用编译器时,咱们通常须要指定编译器的选项。罕用的选项包含: c:只编译源代码,生成指标文件o:指定生成的指标文件名g:生成调试信息Wall:开启所有正告信息例如,应用GCC编译源代码,并生成指标文件的命令如下: $ gcc -c main.cpp -o main.o除了上述罕用选项,编译器还提供了许多其余的选项,例如优化选项和预处理器选项。优化选项能够使程序的执行效率更高,而预处理器选项能够在编译之前进行宏替换和条件编译等操作。编译器的选项很多,须要依据理论状况抉择适合的选项。 编译器的外围工作是将源代码转换为机器码,这个过程中谬误和正告信息对于程序员来说十分重要。因而,咱们应该开启编译器的正告信息以及调试信息,以便在开发过程中及时发现和解决问题。 链接器链接器是将多个指标文件合并成一个可执行文件的程序。在C++中,罕用的链接器有GCC和ld。链接器的次要工作是将程序中援用的函数和变量与定义的函数和变量进行匹配,最终生成可执行文件。 在应用链接器时,咱们通常须要指定链接器的选项。罕用的选项包含: o:指定生成的可执行文件名L:指定链接库的搜寻门路l:指定链接库的名称例如,应用GCC链接指标文件,并生成可执行文件的命令如下: $ gcc main.o -o main -L/usr/lib -lm除了上述罕用选项,链接器还提供了许多其余的选项,例如符号表选项和动静链接选项。符号表选项能够打印出程序中的符号表信息,而动静链接选项能够将链接库的加载推延到运行时。链接器的选项也很多,须要依据理论状况抉择适合的选项。 链接器的次要作用是将多个指标文件合并成一个可执行文件。在程序开发中,咱们经常须要调用其他人编写的库函数。这时候,链接器会将程序中援用的函数与库函数进行匹配,从而生成可执行文件。如果链接器无奈找到所需的库函数,编译过程就会失败。 编译器和链接器的工作流程编译器和链接器是程序开发过程中不可或缺的工具,理解它们的工作流程有助于咱们更好地应用它们。上面是编译器和链接器的工作流程: 编译器将源代码转换为汇编代码。编译器将汇编代码转换为机器码,并生成指标文件。链接器将多个指标文件合并成一个可执行文件,并解决符号援用问题。在这个过程中,编译器和链接器都须要应用选项来管制其行为。这些选项能够管制编译器和链接器的优化等级、调试信息、符号表和库文件搜寻门路等等。 总结编译器和链接器是C++编程中不可或缺的工具。编译器能够将源代码转换成机器码,而链接器能够将多个指标文件合并成一个可执行文件。在程序开发过程中,咱们须要应用编译器和链接器来生成可执行文件。 除了编译器和链接器,还有很多其余的工具和技术能够帮忙咱们编写更高效、更牢靠的程序。例如,调试器能够帮忙咱们查找程序中的谬误;动态剖析工具能够帮忙咱们查看代码中的潜在问题;性能剖析工具能够帮忙咱们找到程序中的性能瓶颈。把握这些工具和技术,能够进步咱们的程序开发效率和代码品质。

May 13, 2023 · 1 min · jiezi

关于c++:力扣150-逆波兰表达式求值

中断表达式转后缀表达式规定:1.数字本人排列2.操作符: a栈为空 || 优先级比栈顶高:入栈b小于等于栈顶,就让栈顶pop,之后会有新的栈顶,接着比拟,直到满足条件a 题解class Solution {public: int evalRPN(vector<string>& tokens) { stack<int>st; for(auto x:tokens) { if(x == "+") { int x = st.top(); st.pop(); int y = st.top(); st.pop(); st.push(y+x); } else if(x == "-") { int x = st.top(); st.pop(); int y = st.top(); st.pop(); st.push(y-x); } else if(x == "*") { int x = st.top(); st.pop(); int y = st.top(); st.pop(); st.push(y*x); } else if(x == "/") { int x =st.top(); st.pop(); int y = st.top(); st.pop(); st.push(y/x); } else { st.push(stoi(x)); } } return st.top(); }留神点1.其余类型->string:to_string() ...

May 12, 2023 · 1 min · jiezi

关于c:第一个C程序的代码初解

 为什么要有C语言呢?!我以前感觉计算机好奇怪啊!她是怎么示意世界万物的!我通过搜查网络大略明确了点,不同的编码造就了不同的意义!哦!那计算机到底意识什么样子的数据呢!我据说计算机的大脑只意识二进制的数据。这个“猪脑袋”幸好她计算的时候速度快!不然真的就太笨蛋啦!据说世界上第一个程序是女的~!那她过后应该就是用二进制去写程序的了!好厉害啊!前段日子我在电驴下了不少视频教程!只有是对于计算机的我都去下载来瞧瞧,过后看到好多人讲什么OD!外面好多什么00FABAF4听他外面说是反编译的工具!不懂!不过!起初我晓得了1点进制转换的常识后明确了。原来啊!二进制写货色比拟长,而且很容易写错!所以经常用十六进制去示意二进制(ADA到底是用的二进制还是十六进制写的程序啊)。起初大家感觉这样写程序还是很麻烦!起初就用了汇编语言!汇编语言就像给“一个人”取的一个外号,而后这个外号又比拟容易记忆!所以汇编语言和二进制代码是一一对应的!然而起初!人们感觉汇编语言还是太繁琐了!要是写的程序就像谈话一样就该多好啊!起初所以才有了C语言!C语言呢比拟靠近自然语言了!然而计算机如何能力懂C语言啊!所以就有了编译器,什么gcc,cl啊之类的。编译器呢先把C语言转化为汇编语言!而后再转化为二进制的。这样计算机就能明确了!转载于{WRITE-BUG}、更多内容可查看原文链接:https://www.writebug.com/article/92f889cf-c790-11ed-9c16-6479...

May 11, 2023 · 1 min · jiezi

关于c:C语言入门

C 语言是 1972 年由美国的 Dennis Ritchie 设计创造的,并首次在 UNIX 操作系统的 DEC PDP-11 计算机上应用。它由晚期的编程语言 BCPL (Basic Combind Programming Language)倒退演变而来。在 1970 年,AT&T 贝尔实验室的 Ken hompson 依据 BCPL 语言设计出较先进的并取名为 B 的语言,最初导致了 C 语言的问世。随着微型计算机的日益遍及,呈现了许多 C 语言版本。因为没有对立的规范, 使得这些 C 语言之间呈现了一些不统一的中央。为了扭转这种状况,美国国家标准研究所(ANSI)为 C 语言制订了一套 ANSI 规范,成为现行的 C 语言规范。C 语言倒退如此迅速, 而且成为最受欢迎的语言之一,次要因为它具备弱小的性能。许多驰名的系统软件, 如 PC-DOS,DBASE Ⅳ 都是由 C 语言编写的。用 C 语言加上一些汇编语言子程序, 就更能显示 C 语言的劣势了。归纳起来 C 语言具备下列特点: C 是中级语言它把高级语言的根本构造和语句与低级语言的实用性联合起来。C 语言能够象汇编语言一样对位、字节和地址进行操作,而这三者是计算机最根本的工作单元。C 是结构式语言结构式语言的显著特点是代码及数据的分隔化,即程序的各个局部除了必要的信息交换外彼此独立。这种结构化形式可使程序档次清晰,便于应用、保护以及调试。C 语言是以函数模式提供给用户的,这些函数可不便的调用,并具备多种循环、条件语句控制程序流向,从而使程序齐全结构化。C 语言功能齐全C 语言具备各种各样的数据类型,并引入了指针概念,可使程序效率更高。另外 C 语言也具备弱小的图形性能,反对多种显示器和驱动器。而且计算性能、逻辑判断性能也比拟弱小,能够实现决策目标。C 语言适用范围大C 语言还有一个突出的长处就是适宜于多种操作系统,如 DOS、UNIX,也实用于多种机型转载于{WRITE-BUG}、更多内容可查看原文链接:https://www.writebug.com/article/93223235-c790-11ed-a615-6479...

May 10, 2023 · 1 min · jiezi

关于c++:C异常和错误处理机制如何使您的程序更加稳定和可靠

在C++编程中,异样解决和错误处理机制是十分重要的。它们能够帮忙程序员无效地解决运行时谬误和异常情况。本文将介绍C++中的异样解决和错误处理机制。什么是异样解决?异样解决是指在程序执行过程中产生异样或谬误时,程序可能捕捉并解决这些异样或谬误的机制。例如,当程序试图拜访一个未初始化的指针或除以零时,就会产生异样。异样解决的目标是确保程序可能在呈现问题的状况下继续执行,并且可能提供有用的错误信息,以便于程序员进行调试和修复。 C++中的异样解决机制C++中的异样解决机制基于三个关键字:try、catch、和throw。try块用于蕴含可能抛出异样的代码。如果在try块中产生异样,程序将跳转到与之关联的catch块。catch块用于解决异常情况。throw关键字用于抛出异样。当throw关键字被执行时,程序将跳转到try块之外的第一个catch块。 以下是一个简略的C++异样解决示例: #include <iostream>using namespace std;int main() { try { int age = 15; if (age >= 18) { cout << "能够进入网吧" << endl; } else { throw(age); } } catch (int myAge) { cout << "未满18岁,禁止进入网吧" << endl; } return 0;}在这个例子中,如果年龄小于18岁,程序会抛出一个异样,并跳转到catch块。catch块将输入一个谬误音讯,通知用户未满18岁禁止进入网吧。 什么是错误处理?错误处理是指在程序执行过程中呈现谬误时,程序可能捕捉并解决这些谬误的机制。错误处理的目标是确保程序可能正确地响应谬误,并且可能提供有用的错误信息,以便于程序员进行调试和修复。 C++中的错误处理机制在C++中,错误处理机制通常通过返回错误代码来实现。当程序执行到某个函数时,如果该函数执行呈现谬误,则会返回一个特定的错误代码,程序员能够依据该错误代码进行相应的解决。通过错误处理机制,程序可能更加强壮和牢靠地运行。通常,错误代码为正数,而胜利的返回值为零或负数。 以下是一个简略的C++错误处理示例: #include <iostream>using namespace std;int main() { int result = 0; result = 10 / 0; if (result < 0) { cout << "产生谬误" << endl; } else { cout << "后果为:" << result << endl; } return 0;}在这个例子中,程序试图除以零。因为除以零是一个谬误状况,程序将返回一个正数错误代码。在主函数中,咱们查看错误代码并输入一个谬误音讯。 ...

May 9, 2023 · 1 min · jiezi

关于c++:基于C实现旅行线路设计

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档] 零碎依据危险评估,为旅客设计一条合乎旅行策略的旅行线路并输入,零碎能查问以后时刻旅客所处的地点和状态(停留城市/所在交通工具)。 试验内容和试验环境形容1.1 试验内容城市之间有各种交通工具(汽车、火车和飞机)相连,有些城市之间无奈中转,须要路径直达城市。某旅客于某一时刻向零碎提出旅行要求。思考在以后 COVID-19 疫情环境下,各个城市的危险水平不一样,分为低危险、中危险和高风险三种。零碎依据危险评估,为该旅客设计一条合乎旅行策略的旅行线路并输入;零碎能查问以后时刻旅客所处的地点和状态(停留城市/所在交通工具)。 1.2 环境形容Windows 10 环境 PC 机;Microsoft Visual Studio 2019 集成化开发环境;Qt Creator 4.11.1(Based on Qt 5.14.1) 集成化开发环境;Qt 运行库(Qt 5.14.2 MinGW 32-bit) 软件设计2.1 数据结构City 类(city.h):class City : public QObject{public: City(string name = "", int number = 0, double risk = 0);string name; //城市名int number; //城市序号QPoint pos; //城市在地图上的地位double risk; //城市危险值void add_route(); //为该城市增加时刻表(未应用)vector<class Transport*> everyday_table; //每日时刻表signals: };Tourist 类(tourist.h): class Tourist{public: Tourist(City* A = nullptr, City* B = nullptr, int limit = 0, int number = 0);bool enabled; //是否启用int number; //旅客序号int status; //旅客状态int stlimit; //最早登程工夫int limit; //最晚达到工夫void plan_route(int time); //为旅客布局路线void update_status(int time); //更新旅客信息City* start; //出发点City* destination; //目的地City* nowat; //以后地位Route plan; //以后布局门路double risk; //以后旅客所接受的危险值void dfs(City* at, Route rut, int time); //以后所在位置 路线 以后工夫 工夫限度signals: ...

May 9, 2023 · 1 min · jiezi

关于c:7种常见网络并发模型介绍

概述对于网络服务器后端开发,为满足不同并发场景的须要,一般来说,不外乎几种常见的并发模型,除了一些教学场景罕用的单线程、多过程(线程)的服务器实现外,生产用的服务器,个别都会思考应用IO多路复用模型。 而常见的IO多路复用场景 ,能够设计得很简略,也能够设计得比较复杂,个别依据业务须要而定。本文总结了一些比拟常见的服务器并发模型,根本涵盖了 大部分业务场景 。在理论业务开发的技术选型时,可依据场景,选取一款稳固、牢靠的网络模型,还是非常要害的。 模型一: 单线程Accept(无IO复用 ) 模型剖析主线程main thread执行阻塞accept, 每次客户端connect连贯过去,main thread中accept响应并建设连贯创立连贯胜利,失去connect fd套接字后,仍然在main thread串行解决套接字读写,并解决业务在解决业务时,如果有新客户端connect过去,server无响应,直到以后socket全副业务处理完毕(完结while循环)以后客户端处理完毕之后,敞开连贯,解决下一个客户端申请优缺点长处socket编程流程清晰且简略,适宜学习应用,理解socket根本编程流程毛病该模型并非并发模型 ,是串行服务器,同一时刻,监听并响应的最大网络申请量为1, 即并发量为1仅适学习根本socket编程,不适宜任何服务器server构建模型二: 单线程 Accept + 多线程读写业务(无 IO 复用) 模型剖析主线程main thread阻塞在accept, 每次客户端 connect连贯过去,main thread中accept响应并建设连贯创立连贯胜利,失去connect fd套接字后,创立一个新的线程thread来解决客户端的读写业务,mian thread仍然回到accept阻塞期待新客户端thread通过套接字connect fd与客户端进行读写操作server在解决业务时,如果有新的客户端连贯过去,main thread中accept仍然能够响应并建设连贯,反复上述过程优缺点长处基于模型1的优化,反对了并发的个性应用比拟灵便,一个客户端对应一个线程独自解决,server解决业务的内聚性比拟高, 客户端无论如何读写 ,服务端 均会有一个 线程做资源响应毛病随着客户端梳理增多,须要开拓的线程数量也减少了,和server线程的数量是1:1的关系,因而对于高并发场景,线程数量受到硬件的瓶颈,线程过多也会 减少CPU的切换老本,升高CPU利用率对于长连贯,客户端一旦无业务读写,只有不敞开,server就应该对放弃这个连贯的状态(心跳查看,健康检查机制),占用连贯资源和线程的开销仅适宜客户端数量不大的场景,且可控的场景来应用该模型仅适宜学习根本的socket编程,不适宜做并发服务器模型三: 单线程多路IO复用 模型剖析主线程main thread创立listen fd之后,采纳多路IO复用机制(如select、epoll)进行IO状态阻塞监控,有client连贯申请,IO 复用机制检测到listen fd触发读事件,则进行accept建设连贯,并将新生成的connect fd退出到监听IO汇合中client再次进行失常读写业务申请,main thread的多路IO复用机制阻塞返回,会触发该套接字 的读写事件等对于client的读写业务,server仍然在main thread执行流程继续执行 ,此时如果有新的客户端connect申请过去,server将没有即时响应等到server解决完一个连贯的读写操作,持续回到多路IO复用机制阻塞,其余连贯过去才能够失常执行优缺点长处单流程体解决了能够同时监听多个客户端读写状态模型,不须要1:1客户端的线程数量关系多路IO复用机制 是阻塞的,非忙轮询的状态,不会节约CPU资源,对CPU的利用率较高对于连接数较多,然而并发不大的场景,或对实时性没有特地严格的场景,该模型曾经足够应用毛病尽管能够监听读个客户端的读写状态,然而同一时间内,只可能解决一个客户端的读写操作,实际上读写业务并发为1当多个客户端拜访server,业务是串行执行,大量申请的会有排队提早景象。模型四:单线程多路IO复用 + 多线程读写业务 (业务工作池) 模型剖析主线程main thread 创立listen fd后,采纳多路IO复用机制(如select、epoll)进行IO状态阻塞监控,有client客户端connect申请 ,IO复用机制检测到listenfd触发读事件,则进行accept建设连贯,并将新生成的connect fd退出到监听IO汇合中当connect fd有 可读音讯,触发读工夫,并进行读写音讯main thread依照固定协定读取音讯,并且交给worker pool工作线程池,工作线程池在server启动之前就曾经开启固定数量的thread,外面的线程只解决音讯 业务,不进行套接字读写操作工作池解决完业务,触发connect fd写事件,将回执客户端的音讯通过main thread写给对方即:main thread只解决IO阻塞监听以及具体的读写操作,读写到的数据交给具体的线程池解决,让main thread专一于解决IO事件相似于Redis的解决机制优缺点长处将业务解决的局部,通过工作池分离出来,可能缩小客户端拜访server导致业务串行执行会有大量申请排队的延迟时间实际上读写的业务并发为1,然而业务流程的并发为线程池数量,放慢了业务解决的并行效率毛病读写仍然是main thread独自解决,最高的读写并行通道仍然是1尽管多个worker thread解决业务,最初返回给client仍旧也须要排队,因为进口还是main thread的一个通道模型五:单线程IO复用 + 多线程IO复用 ...

May 8, 2023 · 1 min · jiezi

关于c++:C虚函数详解多态性实现原理及其在面向对象编程中的应用

在面向对象的编程中,多态性是一个十分重要的概念。多态性意味着在不同的上下文中应用同一对象时,能够产生不同的行为。C++是一种面向对象的编程语言,在C++中,虚函数是实现多态性的要害什么是虚函数虚函数是一个在基类中申明的函数,它能够被子类重写并提供不同的实现。在C++中,应用关键字virtual来申明一个虚函数。虚函数的原理是将函数调用的控制权交给运行时环境,而不是编译时环境。因而,虚函数的实现须要在运行时能力确定。虚函数的申明模式如下:  virtual 返回类型 函数名(参数列表) {   // 实现代码 }例如:  class Shape {   public:     virtual void draw() {       // 实现代码    } };  class Circle : public Shape {   public:     void draw() override {       // 实现代码    } };在下面的例子中,Shape类定义了一个虚函数draw(),并在Circle类中重写了它。留神,在Circle类中的重写函数中应用了override关键字,这是C++11中引入的新个性,示意该函数是对基类中同名函数的重写。 多态性的实现当应用基类指针或援用来拜访派生类对象时,如果虚函数已被重写,将调用派生类中的实现。这种行为称为运行时多态性,因为理论调用的函数是在运行时确定的。例如:  Shape* s = new Circle(); s->draw(); // 调用Circle类中的draw()函数在下面的例子中,咱们应用基类指针s来拜访Circle类的对象,因为Circle类重写了draw()函数,所以调用的是Circle类中的实现。这种行为能够使代码更加灵便、可扩大和易于保护。多态性的实现有两种形式:动态多态和动静多态。动态多态是通过函数重载实现的,而动静多态是通过虚函数实现的。 动态多态是在编译时确定函数的调用,函数重载是动态多态的一种模式。例如:  void print(int a) {   // 实现代码 }  void print(float b) {   // 实现代码 }在下面的例子中,咱们定义了两个函数print(),一个承受一个整数参数,另一个承受一个浮点数参数。在调用print()函数时,编译器会依据传递的参数类型确定调用哪个函数。 动静多态是在运行时确定函数的调用。虚函数是动静多态的一种模式。在应用虚函数时,能够将基类指针或援用指向派生类对象,这样就能够实现多态性调用。例如:  Shape* s = new Circle(); s->draw(); // 调用Circle类中的draw()函数在下面的例子中,咱们应用基类指针s来拜访Circle类的对象,因为Circle类重写了draw()函数,所以调用的是Circle类中的实现。这种行为称为运行时多态性,因为理论调用的函数是在运行时确定的。 多态的底层原理在C++中,多态是通过虚函数表和虚指针来实现的。虚函数表是一个非凡的表格,其中蕴含了虚函数的地址。每个类都有一个虚函数表,其中蕴含了该类及其基类的虚函数地址。当一个对象被创立时,它将蕴含一个指向其类的虚函数表的指针,称为虚指针。当调用一个虚函数时,程序将首先查找该对象的虚指针,而后应用虚指针中的虚函数表来查找正确的函数地址。这种办法使得程序在运行时可能动静地抉择正确的函数。 多态性的益处多态性能够使代码更加灵便、可扩大和易于保护。多态性能够使代码更加通用,能够使同样的代码实用于不同的对象。多态性能够进步代码的复用性,能够缩小代码的反复编写。多态性能够使代码更加易于保护,因为代码能够更加清晰、简洁和易于了解。 ...

May 7, 2023 · 1 min · jiezi

关于c++:C中的多线程编程和同步机制

C++中的多线程编程和同步机制使得程序员能够利用计算机的多外围来进步程序的运行效率和性能。本文将介绍多线程编程和同步机制的基本概念和应用办法。多线程编程根底在C++中,应用<thread>库来创立和治理线程。线程能够通过函数、成员函数或者Lambda表达式来实现。以下是一个应用Lambda表达式来创立线程的例子: #include <thread>#include <iostream>int main() { std::thread t([](){ std::cout << "Hello from thread " << std::this_thread::get_id() << std::endl; }); t.join(); return 0;}上述代码创立了一个线程并输入了该线程的ID。在创立线程时,须要将线程函数作为参数传递给std::thread。在上述例子中,咱们应用了Lambda表达式来定义线程函数,该表达式会输入一行文本。 同步机制多线程编程中最常见的问题是数据竞争和死锁。为了防止这些问题,咱们须要应用同步机制来控制线程的拜访。 互斥量互斥量是C++中最罕用的同步机制之一。互斥量能够保障同一时间只有一个线程能够访问共享资源。以下是一个应用互斥量来爱护共享资源的例子: #include <thread>#include <mutex>#include <iostream>std::mutex mtx;void thread_func() { mtx.lock(); std::cout << "Hello from thread " << std::this_thread::get_id() << std::endl; mtx.unlock();}int main() { std::thread t1(thread_func); std::thread t2(thread_func); t1.join(); t2.join(); return 0;}上述代码创立了两个线程,并应用互斥量来爱护共享资源。在线程函数中,咱们先调用mtx.lock()函数来锁定互斥量,而后访问共享资源,最初再调用mtx.unlock()函数来开释互斥量。在上述例子中,咱们应用了两个线程来访问共享资源,然而只有一个线程能够拜访该资源。这是因为在一个线程访问共享资源时,该资源会被锁定,其余线程无法访问该资源,直到该线程开释互斥量为止。 条件变量条件变量是C++中另一个罕用的同步机制。条件变量能够让线程在某些条件满足时才继续执行,否则就期待。以下是一个应用条件变量来同步线程的例子: #include <thread>#include <mutex>#include <condition_variable>#include <iostream>std::mutex mtx;std::condition_variable cv;bool ready = false;void consumer() { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [](){ return ready; }); std::cout << "Hello from consumer thread " << std::this_thread::get_id() << std::endl;}void producer() { std::this_thread::sleep_for(std::chrono::seconds(1)); ready = true; cv.notify_one();}int main() { std::thread t1(consumer); std::thread t2(producer); t1.join(); t2.join(); return 0;}上述代码创立了两个线程,一个生产者线程和一个消费者线程。生产者线程在1秒后将ready变量设置为true,而后告诉消费者线程继续执行。消费者线程期待条件变量cv,直到ready变量的值为true为止。在该例子中,咱们应用了条件变量来同步生产者和消费者线程。 ...

May 5, 2023 · 1 min · jiezi

关于c:SPISPI总线

SPI简介SPI是串行外设接口的缩写,SPI是一种高速的,全双工,同步的串行通信总线;SPI采纳主从形式工作,个别有一个主设施或多个从设施;SPI须要至多4根线,MISO(主设施输出从设施输入)、MOSI(主设施输入从设施输出)、SCLK(时钟)、CS(片选),SPI应用的引脚较少,通信不便。 寻址形式主设施和某个从设施进行通信时,主设施须要先向从设施的片选线上发送使能信号(高电平或者低电平,依据从机而定)示意选中该从设施。 通信过程SPI总线在进行数据传送时,先传送高位,后传送低位;数据线为高电平示意逻辑“1”,低电平示意逻辑“0”,一个字节传送实现后无需应答,即可开始下一字节的传送;SPI总线采纳同步工作形式,时钟线在回升沿或者降落沿时发送器向数据线上发送数据,再紧接着的降落沿或者回升沿时接收器从数据线上读取数据,实现一位数据传送,八个时钟周期可实现一个字节数据的传送。MSB最高位 LSB最低位 极性和相位SPI总线有四种不同的工作模式,取决于极性(CPOL)和相位(CPHL)CPOL示意SCLK闲暇时的状态CPOL=0;闲暇时SCLK为低电平CPOL=1;闲暇时SCLK为高电平CPHA示意采样时刻CPHA=0;每个周期的第一个时钟沿采样CPHA=1;每个周期的第二个时钟沿采样 四种状况极性为0的时候,闲暇时为低电平;极性为1的时候,闲暇时为高电平;相位为0的时候,回升沿发数据,降落沿读数据;相位为1的时候,降落沿发数据,回升沿读数据 极性和相位须要阐明的是,一个特定的从设施来说,个别再出厂时就会将其设计为某种特定的工作模式,咱们再应用设施时就必须保障主设施的工作模式和该从设施的设施保持一致,否则是无奈进行通信,个别咱们须要对主设施的CPOL和CPHA进行配置。 IIC与SPI的异同

May 5, 2023 · 1 min · jiezi

关于c++:C中的智能指针和内存管理

C++是一门弱小的编程语言,然而在内存治理方面却存在着一些问题。手动治理内存不仅费时费力,而且容易出错。因而,C++中引入了智能指针这一概念,以更好地治理内存。什么是智能指针?在C++中,内存的调配和开释都是由开发者手动实现的。这种形式尽管很灵便,但也非常容易出错,比方遗记开释内存或开释了曾经开释的内存等。为了防止这些问题,C++引入了智能指针这一概念。智能指针是一品种,它在析构时主动开释所治理的对象所占用的内存。这样,程序员就不须要手动治理内存,缩小了出错的可能性。智能指针是一种RAII(Resource Acquisition Is Initialization)技术的利用。 RAII的根本思维是:在对象的构造函数中进行资源的调配,在析构函数中进行资源的开释。智能指针也是这种思维的一种扩大,它在析构时主动开释资源。 C++中的几种智能指针C++中有三种智能指针:unique_ptr、shared_ptr和weak_ptr。每种智能指针都有其独特的性能和特点,上面将逐个介绍。 unique_ptrunique_ptr是一个独享所有权的智能指针,不能共享所有权。当unique_ptr被销毁时,它所治理的对象的内存也会被主动开释。unique_ptr也能够通过std::move()转移所有权。unique_ptr应用的办法很简略,只须要将所需治理的对象传递给unique_ptr即可。  #include <iostream> #include <memory>  int main() {     // 应用unique_ptr治理int类型的对象     std::unique_ptr<int> up1(new int(10));     std::cout << "up1: " << *up1 << std::endl;      // 应用make_unique函数创立unique_ptr对象     auto up2 = std::make_unique<int>(20);     std::cout << "up2: " << *up2 << std::endl;      // unique_ptr能够通过std::move()转移所有权     std::unique_ptr<int> up3 = std::move(up1);     std::cout << "up3: " << *up3 << std::endl;      return 0; }shared_ptrshared_ptr是一个共享所有权的智能指针,能够有多个shared_ptr指向同一个对象。每当一个shared_ptr被销毁时,它所治理的对象的援用计数会减1。当援用计数为0时,对象的内存也会被主动开释。shared_ptr的应用办法和unique_ptr相似,只须要将所需治理的对象传递给shared_ptr即可。须要留神的是,shared_ptr不能治理动态分配的数组,因为它无奈确定数组的长度。  #include <iostream> #include <memory>  int main() {     // 应用shared_ptr治理int类型的对象     std::shared_ptr<int> sp1(new int(10));     std::cout << "sp1: " << *sp1 << std::endl;      // 应用make_shared函数创立shared_ptr对象     auto sp2 = std::make_shared<int>(20);     std::cout << "sp2: " << *sp2 << std::endl;      // 能够有多个shared_ptr指向同一个对象     std::shared_ptr<int> sp3 = sp1;     std::cout << "sp1 count: " << sp1.use_count() << std::endl;     std::cout << "sp3 count: " << sp3.use_count() << std::endl;      return 0; }weak_ptrweak_ptr是一个弱援用的智能指针,它能够与shared_ptr一起应用。weak_ptr不会减少所治理的对象的援用计数,因而它不会影响对象的生命周期。能够通过weak_ptr的lock()成员函数来获取一个指向所治理的对象的shared_ptr。须要留神的是,在应用lock()函数之前,须要判断weak_ptr是否曾经过期,即判断其指向的对象是否曾经被销毁。 ...

May 3, 2023 · 2 min · jiezi

关于c++:开发复杂软件的系统方法二之软件建模

这几周与公司的软件开发专家(职称)探讨产品的软件新架构与计划,次要波及两点 是否复用现有的外围机制基于领域建模设计对于第一点,单方达成统一。 对于第二点,畛域能够了解为业务,业务专家(产品经理,需要工程师,临床工程师等)与研发人员一起,通过头脑风暴、事件风暴、会议、合作等形式,使得研发人员对产品业务进行正当、高效的软件建模。 但在大多数公司中,因为分工(考核)不同,不存在研发人员能高效的对业务进行软件建模,这也就要求研发人员本人去相熟、了解业务,比方你曾经在一个业务上做了5年研发了,经验了各种需要的迭代,探讨,那么你有可能就是你们公司的畛域(业务)专家。 软件开发专家是在一个行业深耕,对业务精通后,进行正当、高效的软件建模,从而为架构、设计、开发提供指南。 这章节,我给大家分享软件建模常识。 什么是软件建模模型是对客观存在的形象,例如驰名的物理学公式 E=mc2,就是品质能量转换的物理法则的数学模型。 除了物理学公式以外,还有一些货色也是模型,比方地图是对天文空间的建模;机械安装、电子电路、建筑设计的各种图纸是对物理实体的建模。 如下图所示,建模和修建的例子 具体解说请浏览开发简单软件的零碎办法(二)之软件建模 本文由IT文艺男(微信公众号itwenyinan) 原创!

May 3, 2023 · 1 min · jiezi

关于c++:软件开发设计架构的五大原则

惟一不变的就是变动自身。 咱们常常讲的零碎、子系统、模块、组件、类、函数就是从逻辑上将软件一步步合成为更轻微的局部,即逻辑单元, 分而治之, 简单问题拆解为若干简略问题, 一一解决。 逻辑单元外部、内部的交互会产生依赖,从而产生了内聚、耦合概念。内聚次要形容逻辑单元外部,耦合次要形容逻辑单元之间的关系。 咱们常常讲的高内聚,低耦合,如何做到,做到的规范是什么?这就是开发、设计、架构的五大准则所体现出的价值,最终达到高内聚,低耦合的软件指标。 耦合逻辑单元之间存在依赖, 导致改变可能会相互影响, 关系越严密, 耦合越强,逻辑单元独立性越差。 比方模块A间接操作了模块B中数据, 则视为强耦合, 若A只是通过数据与模块B交互, 则视为弱耦合。 内聚逻辑单元外部的元素, 关联性越强, 则内聚越高, 逻辑单元单一性更强。 一个逻辑单元该当尽可能独立实现某个性能。 比方有各种场景须要被引入到以后模块, 代码品质将变得十分软弱, 这种状况倡议拆分为多个模块。 高内聚、低耦合内聚性,又称块内分割。指逻辑单元的性能强度的度量,即一个逻辑单元外部各个元素彼此联合的严密水平的度量。 耦合性,又称块间分割。指逻辑单元互相分割严密水平的一种度量。 比方电脑USB口。能够插入USB口工作的设施和电脑都是低耦合性,电脑不依赖于内部任何内部USB设施,只有你合乎USB标准,插上就能够用。USB标准就像一个抽象类,所有外部设备必须实现抽象类,确保能被正确调用。 设计模式、SOLID准则等都是为了更好的做到高内聚、低耦合。 SOLID准则S:繁多职责准则 (<font color="#00b050">S</font>ingle Responsibility Principle)O:开闭准则 (<font color="#00b050">O</font>pen/Closed Principle)L:里氏替换准则 (<font color="#00b050">L</font>iskov Substitution Principle)I:接口隔离准则 (<font color="#00b050">I</font>nterface Segregation Principle)D:依赖倒置准则 (<font color="#00b050">D</font>ependency Inversion Principle)上述是面向对象编程的要害准则。诸如此类的设计准则可能帮忙开发人员构建更易于保护、扩大的零碎。 具体解说请浏览软件开发、设计、架构的五大准则 本文由IT文艺男(微信公众号itwenyinan) 公布!

May 3, 2023 · 1 min · jiezi

关于c:关于C语言结构体初始化问题

环境devCpp 5.11 问题简述近期在写C语言程序时发现了一个我以前没有留神的问题,代码如下: #include <stdio.h>//定义一个 "人" 构造体struct Person{ char name[50]="\0"; //姓名 unsigned short age=0; //年龄 float salary=0; //薪水};int main(){ //实例化两个构造体 张三 和 李四 Person arr[2]={{"张三",38,4800},{"李四",25,3700}}; return 0;}我感觉没有什么问题,然而编译器报错了,谬误如下:大略翻译过去的意思是:不能从初始化列表转为XXX类型。 谬误起因C语言在申明构造体类型时,如果在构造体申明的同时就将构造体中成员进行赋值的话那么在实例化构造体时就不可能应用初始化列表办法进行初始化。相当于创立构造体的霎时曾经被初始化,而再次应用初始化列表就是二次初始化,显然违反编译器的初心————初始化操作只能存在一次。不信?看上面代码及其运行后果。#include <stdio.h>struct Person{ char name[50]="张三"; unsigned short age=27; float salary=3750.25;};int main(){ Person zs; printf("%s %d %.2f\n",zs.name,zs.age,zs.salary); return 0;}创立即初始化。 如果仍想要创立构造体对象则能够应用第一种办法,即创立后再赋值。#include <stdio.h>struct Person{ char name[50]="\0"; unsigned short age=0; float salary=0;};int main(){ Person zs; //张三 sprintf(zs.name,"%s","张三\0"); //格式化写入 zs.age=27; //年龄赋值 zs.salary=4800; //薪水赋值 printf("%s %d %.2f\n",zs.name,zs.age,zs.salary);//打印信息 return 0;} ...

May 3, 2023 · 1 min · jiezi

关于c++:2023-Hubei-Provincial-Collegiate-Programming-Contest题解

补题链接:https://codeforces.com/gym/104337 原文链接:https://www.eriktse.com/algorithm/1136.htmlM. Different Billing签到题,写几个柿子而后枚举B或C即可。 #include <bits/stdc++.h>#define int long longusing namespace std;signed main(){ ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int x, y;cin >> x >> y; for(int c = 0;c <= x; ++ c) { int b = (y - 2500 * c) / 1000; if(b < 0 || 1000 * b + 2500 * c != y)continue; int a = x - b - c; if(a >= 0) { cout << a << ' ' << b << ' ' << c << '\n'; return 0; } } cout << -1 << '\n'; return 0;}C. Darkness I这题是对Minecraft中有限水的拓展过程为背景的一道思维题。 ...

May 2, 2023 · 5 min · jiezi

关于c++:C中的STL容器和算法

C++ STL(规范模板库)提供了一组丰盛的容器和算法,使得开发者可能更加高效地编写程序。本文将介绍STL中的一些罕用容器和算法。容器vectorvector是一个动静数组,能够在运行时调整大小。它的长处在于能够疾速地拜访元素,毛病是在插入和删除元素时须要挪动前面的元素。 #include <vector>#include <iostream>using namespace std;int main() { vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); for (int i = 0; i < v.size(); i++) { cout << v[i] << " "; } cout << endl; v.pop_back(); for (int i = 0; i < v.size(); i++) { cout << v[i] << " "; } cout << endl; return 0;}除了push_back和pop_back,vector还提供了很多其余的成员函数和迭代器,能够不便地拜访和批改元素。比方,能够应用v.front()和v.back()别离拜访首元素和尾元素,应用v.insert()和v.erase()在任意地位插入和删除元素。此外,vector还提供了v.empty()和v.size()别离判断容器是否为空和获取容器大小。 listlist是一个双向链表,能够在任意地位插入和删除元素,但拜访元素比较慢。 #include <list>#include <iostream>using namespace std;int main() { list<int> l; l.push_back(1); l.push_back(2); l.push_back(3); for (list<int>::iterator it = l.begin(); it != l.end(); it++) { cout << *it << " "; } cout << endl; l.pop_back(); for (list<int>::iterator it = l.begin(); it != l.end(); it++) { cout << *it << " "; } cout << endl; return 0;}和vector一样,list也提供了很多其余的成员函数和迭代器,能够不便地拜访和批改元素。比方,能够应用l.front()和l.back()别离拜访首元素和尾元素,应用l.insert()和l.erase()在任意地位插入和删除元素。此外,list还提供了l.empty()和l.size()别离判断容器是否为空和获取容器大小。 ...

April 29, 2023 · 2 min · jiezi

关于c:希望所有计算机学生能看到这篇c语言教程

大部分程序员走入编程世界第一个学习的语言就是C语言。 作为一门古老的编程语言,c语言领有48年的倒退历程。 为什么要学习 C语言?C语言是学习计算机程序设计语言的入门语言。最全面的编程面试网站C语言是一门偏底层的语言,学好它,能够让你更好的理解计算机。学会了C语言,你就能学习当初任何的高级编程语言。因为所有的高级语言都是以C语言为根底的。怎么学习c语言?先举荐一本书《C Primer Plus》,从这本书开始入门,系统地理解C语言的根底语法和简略利用。 学完之后,你应该把握C语言的根底语法:变量、字符串、条件、循环、数组、函数、构造体等,还有指针、内存治理,这两个是C语言中至关重要的知识点。 给大家分享一个Github仓库,下面有大彬整顿的300多本经典的计算机书籍PDF,包含C语言、C++、Java、Python、前端、数据库、操作系统、计算机网络、数据结构和算法、机器学习、编程人生等,能够star一下,下次找书间接在下面搜寻,仓库继续更新中~ Github地址 对C语言有肯定认知之后,就可以看其余进阶版的书籍了,比方《C和指针》和《C专家编程》以及《C陷阱与缺点》等。 对于视频教程,举荐翁恺传授的C语言视频课。 翁恺老师是土生土长的浙大码农,从本科到博士都毕业于浙大计算机系,起初留校教书,一教就是20多年。 翁恺老师的c语言课程十分好,解说特地乏味,很适宜初学者学习。 另外也能够看看清华大学的C语言课程,讲的也挺好。 动手做一些我的项目学习编程,光靠看书和看视频是没用的,肯定要入手写代码、做我的项目,纸上得来终觉浅,只有实际过能力真正的把握这些常识。 举荐几个C语言我的项目,都是比拟趣味性的,不会很干燥。 第一个是贪吃蛇,贪吃蛇是十分经典的一款游戏,置信大家都玩过这个游戏,然而应该很少有人会本人去做出这款游戏。 这个视频解说十分具体,感兴趣的小伙伴能够试着本人实现一下。 另一个是用c语言实现简略计算器,进行加、减、乘、除操作。课程波及的所有数学知识都很简略,都是C语言很根底的货色,适宜初学者。 c语言的知识点总结我整顿了C语言的外围知识点,不便大家学习。 数据类型常量运算符表达式输出/输入流程管制函数数组指针构造体宏定义文件操作内存治理

April 29, 2023 · 1 min · jiezi

关于c++:XMake学习笔记1WindowsMSYS2下MinGWw64环境搭建和XMake安装

以前写的C++根本都是C with STL,大多是面向过程的算法题,或者比拟小的我的项目,而后常常报各种编译谬误(对编译原理不熟),常常把人搞到解体,搞不懂构建、链接之类的货色。 当初开始记录一下XMake的学习笔记,记录一些学习过程中踩的坑,在这篇文章,你将学习到Windows下利用MSYS2进行Mingw-w64环境搭建和XMake装置,并用Xmake构建一个我的项目,编译一个HelloWorld程序。 作者:Eriktse 简介:19岁,211计算机在读,现役ACM银牌选手力争以通俗易懂的形式解说算法!❤️欢送关注我,一起交换C++/Python算法。(优质好文继续更新中……) 浏览原文取得更好浏览体验:https://www.eriktse.com/algorithm/1121.htmlXMake简介一个由国人开发的C++构建工具,真的很好用!yyds。 xmake 是一个基于 Lua 的轻量级跨平台构建工具,应用 xmake.lua 保护我的项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对老手十分敌对,短时间内就能疾速入门,可能让用户把更多的精力集中在理论的我的项目开发上。尽管,简略易用是 xmake 的一大特色,但 xmake 的性能也是十分弱小的,既可能像 Make/Ninja 那样能够间接编译我的项目,也能够像 CMake/Meson 那样生成工程文件,还有内置的包管理系统来帮忙用户解决 C/C++依赖库的集成应用问题。目前,xmake次要用于C/C++我的项目的构建,然而同时也反对其余native语言的构建,能够实现跟C/C++进行混合编译,同时编译速度也是十分的快,能够跟Ninja持平。官网:https://xmake.io/#/zh-cn/ Step1:装置MSYS2MSYS2是一个Windows平台上的GNU/Linux-like环境,能够用于开发和调试Unix/Linux软件。MSYS2应用pacman软件包管理器,能够不便地装置和治理软件包。它也提供了一个相似于Bash的shell,反对大多数Unix/Linux命令和工具。MSYS2还提供了穿插编译工具链,能够不便地在Windows上编译和构建Linux软件。 间接到官网https://www.msys2.org/ 找到 installer下载,而后装置到一个容易找到的门路,比方我装置到D:\msys2目录下,接下来你就能够假想这个目录是一个linux的根目录。 装置实现后的目录差不多是这样的:MSYS2中又有多个子系统,咱们用Mingw64就好。 Step2: 装置XMake接下来应用以下命令用pacman装置XMake: pacman -Sy mingw-w64-x86_64-xmake 装置实现后,用xmake命令就能够应用xmake了。 如果提醒xmake命令没有找到,那就是环境变量的问题,用上面的办法来批改:举荐在etc/profile.d里新建一个env.sh,外面写 export $PATH=$PATH:D:/msys2/mingw64/bin完预先用指令source /etc/profile来刷新配置,再用echo $PATH来查看环境变量是否增加胜利。 为了在VS Code的终端中应用xmake命令,还须要将D:\msys2\mingw64\bin退出到Windows的环境变量中。 留神,这里如果你发现改了环境变量,在vscode中还是不能用xmake命令,你须要重启一下vscode......这是一个小坑,过后困惑了良久。 Step3: 运行Hello World新建一个HelloWorld文件夹,在该文件夹下新建一个文件xmake.lua,外面编写以下内容: set_config("plat", "mingw")set_config("sdk", "D:/msys2/mingw64")target("HelloWorld")-- 设定为二进制文件,也就是windows下的exe文件 set_kind("binary") -- 将src目录下的所有cpp一起编译 add_files("src/*.cpp") 在src/HelloWorld.cpp中写一个简略的程序: #include <iostream>signed main(){ std::cout << "Hello, World!" << '\n'; return 0;}而后在终端中执行命令(留神在我的项目根目录执行): xmake构建实现后能够用xmake run间接运行,或本人用其余办法运行。二进制文件会保留在build外面,而后依据平台进行分类。 ...

April 29, 2023 · 1 min · jiezi

关于c#:C开发租房管理系统

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档]屋宇租赁管理系统是治理房屋出租、发售信息材料而设计的信息管理系统,蕴含有后盾数据库和前台应用程序零碎两大部分,后盾数据库要求数据的一.致性和完整性、安全性,用以贮存单位工程文档资料及相干信息,前台应用程序零碎要求应用程序性能齐备、易于应用和界面敌对等。引言屋宇租赁管理系统是治理房屋出租、发售信息材料而设计的信息管理系统,蕴含有后盾数据库和前台应用程序零碎两大部分,后盾数据库要求数据的一.致性和完整性、安全性,用以贮存单位工程文档资料及相干信息,前台应用程序零碎要求应用程序性能齐备、易于应用和界面敌对等。20世纪以来,社会生产力迅速倒退,科学技术突飞猛进,人们进行信息交换的深度与广度一直减少,信息量急剧增长,传统的信息处理与决策的伎俩已不能适应社会的须要,信息的重要性和信息处理问题的紧迫性空前进步了,面对着日益简单和一直倒退,变动的社会环境,特地是企业间日趋激烈的竞争局势,一个人、一个企业要在古代社会中求生存,求倒退,必须具备足够的信息和强有力的信息收集与解决伎俩。系统分析与设计需要剖析通过对工作的剖析,能够发现运行的零碎要能实现以下的性能:登录治理:实现以正确的员工号、明码和登录人员身份能力登陆零碎的性能,正确登录之后能力进行之后的治理。屋宇信息管理:包含增加新的房屋信息、批改房屋信息、查问房屋信息、删除房屋信息。用户信息管理:包含增加新的用户信息、批改用户信息、查问用户信息、删除用户信息。租赁信息管理:包含查问某个屋宇的租赁情况、增加租赁关系、删除租赁关系。水电费用治理:包含水电费用的查问、增加、批改、删除。财务收支记录:增加公司的财务记录(不容许批改和删除)。免费我的项目设置:设置水费、电费、物业费、宽带费单价及财务余额。管理员信息保护/明码批改:若登陆用户为超级管理员(admin),则能够治理其余员工的信息,否则就只有批改本人明码的权限。

April 29, 2023 · 1 min · jiezi

关于c#:基于C和MYSQL数据库实现的课程自动考试系统

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档] 1 问题定义考试作为教学环节中一个必不可少的局部,是掂量教学质量的重要指标,因而保障考试主观、精确、偏心成为永恒的话题,这不仅关系到人才的提拔和教学的品质,而且波及孩子的将来及千家万户的幸福。随着社会对高常识人才日益减少的需要及高考扩招所带来的学生数量越来越多的社会现状,老师和管理人员的工作量将越来越大,考试治理是一项十分繁琐并且容易出错的事件,能够说传统的考试模式曾经不能再适应社会倒退的需要。随着科学技术的倒退,人们迫切希望可能利用这种技术解决这个问题,加重老师和管理人员的工作压力,进步工作效率,使治理更科学化、规范化,同时进步考试的公平性和信息的安全性。 为了不便学生随时能参加考试进行查漏补缺,无效的布局将来学习打算。为了缩小改卷工作人员的工作量。同时缩小批改时的出错率,进步工作效率。次要使用者老师、在校学生以及其余参考人员等。 2 性能需要本零碎反对新用户注册性能。注册信息包含用户名、明码。其中用户名要求:4-16个字符;明码要求:6-16个字符登录分为学生登录与老师登录,输出用户名和明码,在下方选项中抉择学生或老师后登陆试卷智能生成,零碎依据学生抉择科目主动随机从题库整顿出一套该科目残缺的试卷,题目包含选择题,填空题与判断题试卷智能批阅,零碎依据题库中所给定的标准答案与提交答案比照后产生分数显示给学生题库治理,老师登录后可进行各科目减少、删除和查看试题库中题目等操作试卷治理,老师可对该系统生成过的试卷进行查看、及删除问题治理,零碎主动统计学生考试成绩。3 非性能需要在C/S模式下,学生确认提交试卷后,必须在10秒钟之内显示其考试成绩本零碎客户端反对所有windows零碎,但服务器与客户端须在同一设施上运行零碎需易于保护,投入较少工夫就能改善齐备零碎零碎题库中对应各题的答案必须正确无误

April 27, 2023 · 1 min · jiezi

关于c++:基于C的AI贪吃蛇

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档] 用C++做了个有AI性能的贪吃蛇小游戏,心愿大家enjoy it. 总体详情开发环境:VIsual Studio 2017 开发语言:C++ 和 少许Windows API 运行环境:Windows 10 01 初始化工作-游戏设置游戏设置和相干初始化放在了一个类外面,并进行了动态申明。次要设置了游戏窗口的长和款。并在GameInit()函数外面设置了窗口大小,暗藏光标,初始化随机数种子等。代码如下: //游戏设置相干模块,把函数都放到一个类外面了。函数定义为static动态成员,不生成实体也能够间接调用class GameSetting{public: //游戏窗口的长宽 static const int window_height = 40; static const int window_width = 80;public: static void GameInit() { //设置游戏窗口大小 char buffer[32]; sprintf_s(buffer, "mode con cols=%d lines=%d",window_width, window_height); system(buffer); //暗藏光标 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO CursorInfo; GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息 CursorInfo.bVisible = false; //暗藏控制台光标 SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态 //初始化随机数种子 srand((unsigned int)time(0)); }}; 用到了几个相干的Windows API,本文不做过多介绍,大家百度即可。

April 27, 2023 · 1 min · jiezi

关于c++:SpringBoot-之启动流程

SpringBoot 是一个基于 Spring 框架的疾速开发框架,旨在简化 Spring 应用程序的开发和部署。在本文中,咱们将深入分析 SpringBoot 启动过程的源代码,并提供必要的解释和阐明。SpringBoot启动过程简介SpringBoot应用程序的启动过程能够分为以下几个步骤: 加载应用程序上下文扫描应用程序中的所有组件主动配置应用程序环境启动嵌入式Web服务器 在上面的章节中,咱们将逐个剖析这些步骤的源代码。加载应用程序上下文SpringBoot 应用程序的上下文是一个蕴含所有应用程序组件的容器。在启动过程中,SpringBoot 会加载并初始化这个容器。这个步骤的源代码在SpringApplication类中。具体来说,SpringApplication类的run办法是这个过程的入口点。在这个办法中,Spring Boot会通过调用createApplicationContext办法来创立应用程序上下文。上面是createApplicationContext办法的源代码:protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass;if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable to create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); }}return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);}复制代码在这个办法中,SpringBoot 会依据应用程序类型(Servlet或Reactive)抉择适合的上下文类。而后,它会应用 Java 反射机制来实例化这个类并返回一个可配置的应用程序上下文对象。扫描应用程序中的所有组件在上一步中,SpringBoot创立了应用程序上下文。在这一步中,SpringBoot会扫描应用程序中的所有组件并将它们注册到应用程序上下文中。这个步骤的源代码在SpringApplication类中的scan办法中。具体来说,在这个办法中,SpringBoot 会创立一个SpringBootBeanDefinitionScanner对象,并应用它来扫描应用程序中的所有组件。上面是scan办法的源代码:private void scan(String... basePackages) { ...

April 25, 2023 · 2 min · jiezi

关于c++:基于C研究高并发内存池

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档]内存池:程序事后向零碎申请一大块足够的内存,尔后,当零碎须要申请内存的时候,不是间接向操作习题申请,而是向内存池中申请,当开释的时候,不返回给操作系统,而是返回给内存池,当程序退出时,内存池才将申请的内存真正开释高并发内存池借鉴tcmalloc(ThreadCaching Malloc),即线程缓存的malloc,实现了高效的多线程内存治理,用于代替零碎的内存调配相干的函数(malloc,free)池化技术:向零碎先申请适量的资源,而后本人治理,以备不时之需,之所以申请适量资源,是因为每次申请资源都有较大的开销,那边不如提前申请好,进步程序运行效率在计算机中除了内存池,还有连接池,线程池,对象池等,以线程池为例,它的次要思维是,先启动若干数量的线程,让他们处于睡眠状态,当接管到客户端申请时,唤醒某个沉睡的线程,让它解决客户端申请,当解决完申请之后,线程又进入了休眠状态内存池:程序事后向零碎申请一大块足够的内存,尔后,当零碎须要申请内存的时候,不是间接向操作习题申请,而是向内存池中申请,当开释的时候,不返回给操作系统,而是返回给内存池,当程序退出时,内存池才将申请的内存真正开释内存池解决问题:1.次要解决效率问题2.内存碎片问题malloc理论就是一个内存池定长内存池固定大小的内存申请治理特定:性能达到极致不思考内存碎片等问题设计形式:向内存申请一块足够大的内存块,而后每次申请内存时咱们就切出去一小部分拿来应用,

April 23, 2023 · 1 min · jiezi

关于c#:基于C开发三层架构图书管理系统

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档] 学校图书馆有许多书,如果靠人工的形式来进行治理,那么工作量会十分大。图书的统计和治理会成为让人头疼的问题,读者借阅图书进行注销也会非常的不不便。这时,利用计算机来为咱们进行这些统计治理的工作,能够给咱们的生存带来大大的便当,并且进步工作效率。因为条件无限,只能应用键盘输入书的信息,所以在输出图书的ISBN号时有些麻烦。所以在课设里,采纳了图书编号。在现实生活中,采纳扫描的形式录入ISBN号会更加精确,高效。 一、我的项目背景及意义当今因为信息技术的飞速发展,图书馆作为社会常识信息媒介的性能日益重要,网络环境下的信息资源建设常识仓库的设计,凋谢存取学术交流模式,常识管理系统,智能检索,数字参考征询,数字图书馆畛域成为图书馆零碎的钻研方向。 治理倒退至今,综合倒退的整体趋势已日渐显著。引进新办法,排汇新思维是促成图书馆零碎倒退的必要条件。因而,图书馆零碎的钻研要保持实践与技术相交融,发展跨学科的穿插钻研;要保持实践与实际相结合,而对事实,答复事实所提出的最迫切的问题;要保持根底钻研和利用钻研,前者对后者起指导作用,后者反过来对前者起丰盛和倒退的作用;要正确处理事实、历史、实践三者之间的关系,这是推动管理系统钻研的重要办法。 二、需要剖析2.1 现状剖析以往,人们应用传统的人工形式治理图书馆的日常业务,其操作流程比拟繁琐。在借书时,读者首先将要借的书好借阅证交给工作人员,而后工作人员将每本书的信息卡片好读者的借阅证放在一个小格栏里,最初在借阅证和每本书贴的借阅条上填写借阅信息。在还书时,读者首先将要还的书交给工作人员,而后工作人员依据图书信息找到相应的书卡好借阅证,并填写相应的还书信息。 学校图书馆有许多书,如果靠人工的形式来进行治理,那么工作量会十分大。图书的统计和治理会成为让人头疼的问题,读者借阅图书进行注销也会非常的不不便。这时,利用计算机来为咱们进行这些统计治理的工作,能够给咱们的生存带来大大的便当,并且进步工作效率。因为条件无限,只能应用键盘输入书的信息,所以在输出图书的ISBN号时有些麻烦。所以在课设里,采纳了图书编号。在现实生活中,采纳扫描的形式录入ISBN号会更加精确,高效。 2.2 零碎性能需要图书管理系统是针对图书馆工作人员开发的管理软件,实现对图书信息、用户信息的治理性能。 本零碎次要可能实现以下性能: 图书信息管理(查问、批改、新增、删除) 用户信息管理(查问、批改、新增、删除) 借书操作、还书操作、续借操作、借书记录查看 图书和用户分类管理(查问、批改、新增、删除) 2.3 零碎设计指标零碎中的数据表设计正当、高效、数据冗余少 软件界面敌对、安全性高 易于保护、不便降级 三、零碎可行性剖析3.1 技术可行性图书管理系统的开发环境是Visual Studio 2010、Microsoft SQL Server 2008R2 SP3。零碎是利用C/S的交互方式实现,本零碎具备稳定性、安全性、好看性、先进性。零碎现阶段的倒退过程中,利用现有的人力物力是齐全具备的能力开发进去的,作为阶段性产品,日后的倒退空间大,实现办法逐渐简略容易,所以图书管理系统的技术上是齐全可行的。在以后的限度条件下,该零碎的性能指标能达到。 3.2 经济可行性计算机专业师生团队能够进行日常的系统维护,工作量少,经济收入少。 3.3 操作可行性所有界面具备格调对立,不同栏目的页面文字格调对立,重点突出图书治理平台的特点,零碎页面敌对,操作简略,即便没有计算机根底的老师也很好上手。 四、应用的相干技术4.1 C#C#是微软公司公布的一种面向对象的、运行于.NET Framework之上的高级程序设计语言。并定于在微软职业开发者论坛(PDC)上登台亮相。C#是一种平安的、稳固的、简略的、优雅的,由C和C++衍生进去的面向对象的编程语言。它在继承C和C++弱小性能的同时去掉了一些它们的简单个性(例如没有宏以及不容许多重继承)。C#综合了VB简略的可视化操作和C++的高运行效率,以其弱小的操作能力、优雅的语法格调、翻新的语言个性和便捷的面向组件编程的反对成为.NET开发的首选语言。 4.2 SQL serverSQL Server是由Microsoft开发和推广的关系数据库管理系统(DBMS),它最后是由Microsoft、Sybase和Ashton-Tate三家公司共同开发的,并于1988年推出了第一个OS/2版本。Microsoft SQL Server近年来不断更新版本,1996年,Microsoft 推出了SQL Server 6.5版本;1998年,SQL Server 7.0版本和用户见面;SQL Server 2000是Microsoft公司于2000年推出,目前最新版本是2017年份推出的SQL SERVER 2017。 五、零碎具体设计5.1 总体设计以Microsoft SQL Server 2008R2 sp3、Visual Studio 2010作为开发环境,应用数据库技术以及.net开发技术,从用C#三层架构:体现层(UI(User Interface))、业务逻辑层(BLL(Business Logic Layer))、数据拜访层(DAL(Data Access Layer))再加上实体类库(Model),开发此图书管理系统。

April 23, 2023 · 1 min · jiezi

关于c:C语言项目实操学生管理系统

本文首发自「慕课网」,想理解更多IT干货内容,程序员圈内热闻,欢送关注"慕课网"!作者:张磊|慕课网讲师 0根底学员在通过C语言根底语法的学习后,须要通过一些实战案例来学习如何将C语言利用到理论工作中,明天咱们通过一个学生管理系统案例的开发来晋升理论开发能力。 1. 零碎介绍 在这里,咱们首先采纳了数组的形式来存储咱们输出的内容。同时,咱们这里利用里后面学习到的 struct 来结构化存储咱们的学生信息。 咱们实现了根本的对于数据操作的几项性能:增、删、改、查。 也就是咱们能够向这个零碎中增加数据,删除数据,批改数据,还有就是查问数据。这里的查问数据,咱们又分为了全副无条件的查问,和依照姓名条件的查问。 2. 性能 零碎的性能外面咱们设计了增加、删除、批改、列表显示和查问等 5 个性能。 增加:增加就是将数据增加到存储数据的数组中; 删除:删除就是依据指定的序列号删除特定的一条数据; 批改:批改就是依据指定的序列号来批改学生的问题; 列表显示:列表的显示,其实就是无条件的查问,也就是在没有特点查问条件的状况下,将存储的数据全副显示进去; 查问:这里的查问,就是依照姓名这个个性的条件。把合乎这个条件的数据筛选进去,并显示进去。 3.示例程序 #include <stdio.h>#include <string.h>#define StudentNumbers 50#define NameLength 50typedef struct{ int id; char name[NameLength]; int age; int score; int flag;} Student;int add(Student student, Student Students[]);int del(int id, Student students[]);int display(Student students[]);int update(int id, Student students[]);int search(char name[], Student students[]);int main(){ int id = -1; char name[NameLength]; int choice = 0; int stop = 0; Student students[StudentNumbers]; Student student; for (int i = 0; i < StudentNumbers; i++) { students[i].id = i; students[i].flag = 0; } while (stop == 0) { printf("-------------------------\n"); printf("* 学生管理系统 *\n"); printf("-------------------------\n"); printf("1 增加\n"); printf("2 批改问题\n"); printf("3 查问\n"); printf("4 删除\n"); printf("5 显示学生列表\n"); printf("0 退出程序\n"); printf("请间接输出数字选项:"); scanf("%d", &choice); switch (choice) { case 1: printf("请输出学生姓名:"); scanf("%s", student.name); printf("请输出学生的年龄:"); scanf("%d", &student.age); printf("请输出学生问题:"); scanf("%d", &student.score); add(student, students); break; case 2: printf("请输出要批改问题的学生编号:"); scanf("%d", &id); update(id, students); break; case 3: printf("请输出要查找的学生姓名:"); scanf("%s", name); search(name, students); break; case 4: printf("请输出要删除的学生编号:"); scanf("%d", &id); del(id, students); break; case 5: display(students); break; case 0: stop = 1; break; default: printf("输出选项有误\n"); break; } } return 0;}int add(Student student, Student students[]){ for (int i = 0; i < StudentNumbers; i++) { if (students[i].flag == 0) { strcpy(students[i].name, student.name); students[i].age = student.age; students[i].score = student.score; students[i].flag = 1; return 0; } } return 1;}int del(int id, Student students[]){ for (int i = 0; i < StudentNumbers; i++) { if (students[i].id == id) { students[i].flag = 0; return 0; } } return 1;}int display(Student students[]){ printf("******************\n"); printf("学生列表\n"); printf("******************\n"); for (int i = 0; i < StudentNumbers; i++) { if (students[i].flag == 1) { printf("学生编号:%d,学生姓名:%s,年龄:%d,问题:%d\n", students[i].id, students[i].name, students[i].age, students[i].score); } } printf("******************\n"); return 0;}int update(int id, Student students[]){ int score = -1; printf("请输出新的问题:"); scanf("%d", &score); for (int i = 0; i < StudentNumbers; i++) { if (students[i].id == id) { students[i].score = score; return 0; } } return 1;}int search(char name[], Student students[]){ for (int i = 0; i < StudentNumbers; i++) { if (strcmp(name, students[i].name) == 0) { printf("学生编号: %d,学生姓名: %s,年龄: %d,问题: %d\n", students[i].id, students[i].name, students[i].age, students[i].score); return 0; } } printf("没有查找到相干学生信息。\n"); return 1;}很多人可能会第一次接触这么长的程序,会产生畏惧的心理。其实不必放心。要置信本人能够看懂的。 ...

April 23, 2023 · 3 min · jiezi

关于c#:asyncawait-在-C-语言中是如何工作的下

接《async/await 在 C# 语言中是如何工作的?(上)》、《async/await 在 C# 语言中是如何工作的?(中)》,明天咱们持续介绍 SynchronizationContext 和 ConfigureAwait。 ▌SynchronizationContext 和 ConfigureAwait咱们之前在 EAP 模式的上下文中探讨过 SynchronizationContext,并提到它将再次出现。SynchronizationContext 使得调用可重用的辅助函数成为可能,并主动被调度回调用环境认为适合的任何中央。因而,咱们很天然地认为 async/await 能“失常工作”,事实也的确如此。回到后面的按钮单击处理程序: ThreadPool.QueueUserWorkItem(_ =>{ string message = ComputeMessage(); button1.BeginInvoke(() => { button1.Text = message; });});应用 async/await,咱们能够这样写: button1.Text = await Task.Run(() => ComputeMessage());对 ComputeMessage 的调用被转移到线程池中,这个办法执行结束后,执行又转移回与按钮关联的 UI 线程,设置按钮的 Text 属性就是在这个线程中进行的。 与 SynchronizationContext 的集成由 awaiter 实现(为状态机生成的代码对 SynchronizationContext 无所不知),因为当所示意的异步操作实现时,是 awaiter 负责理论调用或将所提供的 continuation 排队。而自定义 awaiter 不须要思考 SynchronizationContext。目前,Task、Task<TResult>、ValueTask、ValueTask<TResult> 的期待器都是 do。这意味着,默认状况下,当你期待一个工作,一个 Task<TResult>,一个 ValueTask,一个 ValueTask<TResult>,甚至 Task. yield() 调用的后果时,awaiter 默认会查找以后的 SynchronizationContext,如果它胜利地取得了一个非默认的同步上下文,最终会将 continuation 排队到该上下文。 ...

April 23, 2023 · 4 min · jiezi

关于c++:Visual-Leak-Detector源码文件概览

阐明应用 VLD 内存透露检测工具辅助开发时整顿的学习笔记。本篇对 VLD 源码包中的各文件用处做个概述。同系列文章目录可见 《内存透露检测工具》目录 [TOC] <br/> 1. 整体概览以 vld2.5.1 版本为例,下载源码 后,根目录下一共 5 个文件夹:.teamcity、lib、mfc_detect、setup、src。还有 12 个文件:.editorconfig、.gitignore、.mailmap、appveyor.yml、AUTHORS.txt、change_toolset.ps1、CHANGES.txt、COPYING.txt、README.md、vld.ini、vld_vs14.sln、vld_vs14_wo_mfc.sln。 2. 文件夹 .teamcity该文件夹的目录构造如下: vld-master\.teamcity└─Vld │ project-config.xml │ ├─buildTypes │ Vld_CompileAll.xml │ Vld_DebugCrtDllWin32.xml │ ├─pluginData │ plugin-settings.xml │ └─vcsRoots Vld_HttpsGithubComKindDragonVldGitRefsHeadsMaster.xml外面全是 xml 文件,是 teamcity 继续集成工具的配置文件,用于 VLD 我的项目源码的集成治理,对于该工具的介绍,可拜访其官网:Jetbrains-teamcity。 3 文件夹 lib该文件夹下有三个子文件夹:cppformat、dbghelp、gtest。 3.1 文件夹 cppformat(生成 libformat)该文件夹的目录构造如下: vld-master\lib\cppformat ChangeLog.rst format.cc format.h format.vcxproj format.vcxproj.filters LICENSE.rst posix.cc posix.hcppformat 是一个开源的 C++ 格式化库,仓库地址为 Github-fmtlib,在 VLD 中被用来格式化输入堆栈信息,详见 源码 callstack.cpp 第 224~275 行。 ...

April 23, 2023 · 5 min · jiezi

关于c++:Wallys-IPQ4019-IPQ4029-support-20-km-remote-transmission

The IPQ4019 and IPQ4029 chipsets from Qualcomm are designed for high-performance Wi-Fi networks, providing advanced features such as MU-MIMO, beamforming, and enhanced spectral efficiency. These chipsets are suitable for a wide range of applications, including enterprise, industrial, and residential wireless networks. When combined with the Wallys WiFi5 Industrial Wireless AP DR-AP40X9-A, these chipsets can provide exceptional long-range connectivity. The DR-AP40X9-A is designed for outdoor use and is equipped with high-power radios and antennas, allowing it to cover a large area with a strong Wi-Fi signal. With the IPQ4019 or IPQ4029 chipset, the DR-AP40X9-A can deliver reliable and high-speed wireless connectivity over long distances, making it an ideal solution for industrial applications, remote locations, and outdoor environments. ...

April 23, 2023 · 2 min · jiezi

关于c++:基于C控制台的吃豆人小游戏

拜访【WRITE-BUG数字空间】_[内附残缺源码和文档] 玩家指标是吃掉所有豆豆,途中,若玩家撞到怪兽则游戏完结。游戏中存在超级豆子,吃到后,所有怪兽静止,且玩家进入无敌状态(可撞怪兽使之回到初始地位)。玩家可应用键盘方向键进行抉择、管制挪动,回车键确定,Esc 键返回,空格键暂停。 控制台小游戏——吃豆豆一、概述1.1 次要内容:以吃豆豆大作战根底参考,实现了运行在 Windows 管制台下的一个吃豆豆小游戏。玩家指标是吃掉所有豆豆,途中,若玩家撞到怪兽则游戏完结。游戏中存在超级豆子,吃到后,所有怪兽静止,且玩家进入无敌状态(可撞怪兽使之回到初始地位)。玩家可应用键盘方向键进行抉择、管制挪动,回车键确定,Esc 键返回,空格键暂停。 1.2 已实现的指标:地图反对自定义编辑(可编辑地图中的:空地、墙、豆子、超级豆子、小怪初始地位及数量、吃豆人初始地位)可抉择游戏难度(即设定不同的小怪挪动速度)怪兽可追踪吃豆人地位,往吃豆人的所在位置凑近可查看历史记录 TOP 10,并且可对游戏记录进行回放在回放的过程中,反对按下方向键后,退出回放模式,在以后情景下,操纵吃豆人,进入失常的游戏模式,持续游戏有用户敌对的 UI 界面(比方:吃到超级豆子后吃豆人变黑白闪动,且下方显示进度条倒计时;抉择界面高亮显示选项)二、次要类的设计2.1 顺次介绍各个类的设计:Position 类因为是在管制台下实现本游戏,所以显示界面的所有元素都是字符,而一些较为好看,且合乎游戏中的元素的特殊字符个别都是 2 个英文字符的宽度,所以这里界面设计的次要思维使将整个控制台运行窗口看成一个二维的画布,横坐标以每两个英文字符的宽度为单位,纵坐标则以每行为单位。 而有了画布之后,画布上的每一个点其实能够看作一个数据结构,这就是 Position 类的意义。

April 22, 2023 · 1 min · jiezi

关于c++:VSCode-GCC编译器MinGW开发环境中文字符乱码问题踩坑与解决办法

@[toc] 问题背景在较长一段时间里,C/C++开发者所应用的集成开发环境(IDE)要么是比拟重量级的VS(Visual Studio),要么是Codeblocks·、·Visual C++ 6.0等轻量级IDE,又或者是诸如notepad++、sublime text等文本编辑器+GCC编译器+命令行工具的组合式开发环境。这几种开发方式要么太过宏大比拟吃硬件资源,比方VS动辄就要占用几十个G的硬盘空间,要么尽管轻量然而没有敌对的代码提醒和自动化的编译链接运行过程,开发体验并不是很敌对。 近几年来,随着VSCode(Visual Studio Code)的风行,越来越多的开发者抉择以此来作为集体的集成开发环境。应用VSCode开发C/C++程序能够下载安装VSCode官网的C/C++ for Visual Studio Code插件实现开发过程中的代码提醒、调试、运行等性能,然而须要自行装置C/C++编译器,笔者是用的是GCC编译器MinGW。具体开发环境的搭建过程在此不作解说,本文关注点在于开发过程中遇到的中文字符相干的乱码问题。 问题形容测试代码英文字符串文本文件 es_src.txt Chinese中文字符串文本文件 ch_src.txt 中文main.c #include <stdio.h>#include <stdlib.h>#include <string.h>int main(){ char str_es[] = "Chinese"; char str_ch[] = "中文"; char str[30]; // 读英文字符串的文本文件测试 printf("读文件测试:\n"); FILE *fpr_es = fopen("es_src.txt", "r"); while (fgets(str, 30, fpr_es) != NULL) { printf("strcmp(%s, %s)=%d\n", str_es, str, strcmp(str_es, str)); } fclose(fpr_es); // 间接打印含中文字符串测试 printf("请输出英文字符串“Chinese”:\n"); // 读入英文字符串 scanf("%s", str); printf("间接打印测试:\n"); // 间接打印英文字符串 printf("str=%s\n", str); // 与英文字符串常量进行比拟 printf("strcmp(%s, %s)=%d\n", str_es, str, strcmp(str_es, str)); // 英文字符串写入文件测试 printf("写文件测试:\n"); FILE *fpw_es = fopen("es_tar.txt", "w"); fprintf(fpw_es, "%s\n%s\n", str_es, str); fclose(fpw_es); printf("写入实现!\n"); // 读中文字符串的文本文件测试 printf("读文件测试:\n"); FILE *fpr_ch = fopen("ch_src.txt", "r"); while (fgets(str, 30, fpr_ch) != NULL) { printf("strcmp(%s, %s)=%d\n", str_ch, str, strcmp(str_ch, str)); } fclose(fpr_ch); // 间接打印中文字符串测试 printf("请输出中文字符串“中文”:\n"); // 读入中文字符串 scanf("%s", str); printf("间接打印测试:\n"); // 间接打印中文字符串 printf("str=%s\n", str); // 与中文字符串常量进行比拟 printf("strcmp(%s, %s)=%d\n", str_ch, str, strcmp(str_ch, str)); // 中文字符串写入文件测试 printf("写文件测试:\n"); FILE *fpw_ch = fopen("ch_tar.txt", "w"); fprintf(fpw_ch, "%s\n%s\n", str_ch, str); fclose(fpw_ch); printf("写入实现!\n"); system("pause"); return 0;}测试后果控制台输入后果能够看到(a) 从文件中读取英文字符串并打印能够失常显示;间接打印英文字符串常量和间接打印从键盘读入的英文字符串均失常显示,应用strcmp进行比拟后果为0。(b) 从文件中读取中文字符串并打印能够失常显示;间接打印中文字符串常量能够失常显示,然而没有显示出从键盘读入的中文字符串,应用strcmp进行比拟后果也不为0。读文件测试:strcmp(Chinese, Chinese)=0 请输出英文字符串“Chinese”:Chinese间接打印测试:str=Chinesestrcmp(Chinese, Chinese)=0写文件测试:写入实现!读文件测试:strcmp(中文, 中文)=0 请输出中文字符串“中文”: 中文间接打印测试:str=strcmp(中文, )=1写文件测试:写入实现!Press any key to continue . . .英文字符串文本文件 es_tar.txt英文字符串常量和从键盘读入的英文字符串均失常写入到文件中。 ...

April 22, 2023 · 1 min · jiezi

关于c:十进制转二进制的方法-写代码实现CC

作者:柒烨带你飞本文为原创文章,版权归自己所有。文章首发于CSDN:https://blog.csdn.net/m0_61643743/article/details/130260640 十进制转二进制整数十进制转二进制转换方法 + 如何用代码实现为次要内容一,十进制转二进制办法办法1:除二取余法十进制数除2得商取余法:对十进制进行除法运算,十进制除以2能够失去一个商和余数;再用失去的商除以2又失去一个商和余数,以此内推,中转最初一次除以2,商为0或1进行十进制转换例子:(13)(20)把这2个十进制数转换为二进制 13/2 = 6.....1 ,6/2 = 3.....0, 3/2 = 1.....1 , 1/2 = 0.....1 ; 把余数逆序排列,13的二进制数就是:1101。20/2 = 10.....0 10/2 = 5.....0 5/2 = 2.....1 2/2 = 1.....0 1/2 = 0.....1 20的二进制数就是:10100十进制转二进制时只需算出整数商即可,如理论 5/2 = 2.5,算出整数商2取余就好,如:5/2 = 2....1 办法2:按权相加法法则如下: 二进制100000001000000100000100001000100101十进制1286432168421位权(幂模式)2^72^62^52^42^32^22^12^0依据下面的法则,假如上面8位二进制都是0 128643216842110000001求129的二进制数:只需把下面表格中128和1上面的0改为1(128+1 =129) 129的二进制数:10000001128643216842110000111**求135的二进制数:(128+2+4+1=135)135的二进制数:10000111 128比135小所以128下改1,135-128 = 7。64,32,16,8比7大所以都设为0,4比7小设1,7-4=3;2比3小设1, 最初残余的1,1等于1设1**16842110100求20的二进制数:(16+4=20) 20的二进制数:10100。16比20小设1,20-16=4,8比4大设0,4等于4设1。84211010求10的二进制数:(8+2=10) 10的二进制数:1010。8比10小设1,10-8=2,4比2大设0,2等于2设1借助这个办法十进制转二进制更容易,纯熟了之后笔算,心算一下就能算出二进制数,不必像除2取余法一样繁冗 二,代码实现实例:步骤实现: 获取用户输出的十进制数。判断用户输出的数据是否不符合要求,合乎则进入下一阶段,不合乎则从新输出或退出。十进制转二进制运算实现区输入失去的二进制数1,C 代码实现#include<stdio.h>int main(){ short BinaryNumbe[32]={0};//定义一个数组存储二进制数 int i,n;//i为数组下标,n用来存储十进制数 /*步骤1: 获取用户输出的十进制数。 判断用户输出的数据是否符合要求,合乎则进入下一阶段,不合乎则从新输出*/ do { printf("请输出要转换的十进制数(1-2147483647):");//提醒输出十进制 scanf("%d",&n);//scanf获取输出的数据 if (n <= 0 || n > 2147483647)/*用if判断数据是否输出有误,有误则从新输出*/ { printf("输出有误,十进制转二进制范畴为(1-2147483647)\n"); continue; /*提醒输出有误,用continue完结本次循环,再进行一次循环*/ } } while (0); /*步骤2: 十进制转二进制计算实现区。 用for循环,i为数组下标,计算十进制除2去余赋值给寄存二进制数据的数组*/ for ( i = 0; i < 32 ; i++)//int最大值为(2147483647)32位二进制数最大也是2147483647。所以循环次数设置为32(0-31) { BinaryNumbe[i] = n % 2;//取余赋值给数组 n = n / 2; //除以2,失去下一个商,赋值给n if (n == 0) { break;//当商等于0时,不再进行多余次数的循环,break跳出循环; } } /*步骤3: 输入二进制数据。 下面i++曾经记录了循环计算的次数。 i循环的次数 == i位二进制数 == 数组[i]最初赋值的余数 。 间接在上面for循环中加个i >= 0 ; i--,就能逆序输入了。 */ printf("二进制数是:"); for (n = 1 ; i >= 0 ; i--) { printf("%d",BinaryNumbe[i]);//逆序打印二进制数 if (n%4 == 0 ) {//为了好看,用if判断每输入4个二进制数,打印一个空格。 //该段用n来记录了输入次数,该段代码可不加 printf(" "); } n++; } printf("\n");//换行 system("pause"); return 0;}把上述代码简化改成一个函数,思路不变 ...

April 22, 2023 · 2 min · jiezi

关于c:C语言的灵魂指针

本文首发自「慕课网」,想理解更多IT干货内容,程序员圈内热闻,欢送关注"慕课网"! 作者:精慕门1289550|慕课网讲师 C 语言中的指针C 语言的指针经常被人们认为是 C 语言中的灵魂所在,能够实现很多高难度的操作。然而更多的人感觉 C 语言的指针的存在如同噩梦个别,因为稍不留神,就会引起灾难性的结果。 不论你是不是喜爱 C 语言中的指针,咱们都要学习这种看起来很神奇的货色。因为指针这个概念不是 C 语言独创的,而是苏联的计算机科学家独创的。 1. 什么是指针?指针是什么?这是来自灵魂的拷问。其实指针也是一种变量。咱们之前也说过。只不过存储的是另外一个变量的地址。变量地址是变量在内存中存储的地位索引。 `int *a; int b=5; a = &b;`` 这里咱们定义了一个整数类型的指针 a ,能够看出指针的定义与变量的申明是统一的,只不过须要在变量明前加上一个额定的字符 * 。 因为指针中存储的应该是变量的地址,因而咱们在赋值的时候须要取得变量的地址,而不是变量自身所存储的数值。这里咱们采纳的 & 来获取变量的地址。将获取到的地址赋值给指针变量。 要是想应用指针中存储地址中所存储的值,那么就须要在指针变量名前加 * 来获取相应地址中存储的值。 2. 示例程序#include <stdio.h>int main(){ int *a, b = 100, *c; printf("a value = %p, a address = %p, a point value = %d\n", a, &a, *a); printf("b value = %d, b address = %p\n", b, &b); printf("c value = %p, c address = %p, c point value = %d\n", c, &c, *c); a = &b; printf("a value = %p, a address = %p, a point value = %d\n", a, &a, *a); c = a; printf("c value = %p, c address = %p, c point value = %d\n", c, &c, *c); printf("b value = %d, b address = %p\n", b, &b); return 0;}运行后果: ...

April 20, 2023 · 2 min · jiezi

关于c++:ACM算法竞赛日常训练DAY16奇♂妙拆分区区区间间间小AA的数列数学-位运算-前缀和

DAY16共3题: 奇♂妙拆分(简略数学)区区区间间间(枯燥栈)小AA的数列(位运算dp) 作者:Eriktse 简介:19岁,211计算机在读,现役ACM银牌选手力争以通俗易懂的形式解说算法!❤️欢送关注我,一起交换C++/Python算法。(优质好文继续更新中……) 浏览原文取得更好浏览体验:https://www.eriktse.com/algorithm/1119.html奇♂妙拆分(简略数学)依据贪婪的想法,若要使得因子尽可能多,那么因子该当尽可能小,大于根号n的因子至少一个,从小到大枚举[1, sqrt(n)]的所有整数,如果i可能整除n就作为一个因子。 Code: #include <bits/stdc++.h>#define int long longusing namespace std;void solve(){ int n;cin >> n; set<int> st; for(int i = 1;i <= n / i; ++ i) if(n % i == 0)st.insert(i), n /= i; st.insert(n); cout << st.size() << '\n';}signed main(){ ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int _;cin >> _; while(_ --)solve(); return 0;}区区区间间间(枯燥栈)题意:给定一个数组,求所有子区间的最大值与最小值的差的和。 如果暴力枚举必定不行,单单是子区间个数就有n ^ 2个,所以咱们应该思考每一个元素对答案的奉献,也就是说咱们须要晓得某个元素a[i]它会在多少个区间里作为最大值,在多少个区间里作为最小值。 咱们预处理出四个数组,别离是lmax[], rmax[], lmin[], rmin[]示意点i作为最大值的左右最远地位,和作为最小值的左右最远地位(lmax[i] = j,示意在区间[j, i]中的最大值都是a[i],其余的三个数组相似定义)。 用枯燥栈能够解决出这四个数组,一下以求lmax[]举例,保护一个枯燥不增栈,栈内寄存的是下标。 初始时栈内仅有一个a[0] = inf。 ...

April 20, 2023 · 3 min · jiezi

关于c++:ACM组合数学-错排公式写信

题目链接:https://ac.nowcoder.com/acm/contest/54484/B 题意很简略,然而数据范畴偏大。 错排公式首先来推导一下错排公式: $$D(n) = n!\sum_{k=0}^{n}\frac{(-1)^k}{k!}$$ 设一个函数: $$S_i示意一个排列中p_i = i的计划数$$ 那么咱们能够晓得: $$D(n) = n! - |\cup_{i=1}^{n}S_i|$$ 这个示意所有计划数减去至多有一个地位放对的计划数。 当初来考虑一下如何解决前面这个并集,并集往往是不好求的,而交加会好求很多,所以在求并集的时候咱们往往采取容斥原理将一个并集转换成诸多交加的加减运算。 咱们用一个图能够来示意当n = 3的状况: 其中有: $$|S_1 \cup S_2 \cup S_3| = |S_1| + |S_2| + |S_3| - |S_1 \cap S_2| - |S_1 \cap S_3| - |S_2 \cap S_3| + |S_1 \cap S2 \cap S_3|$$ 扩大一下就能够失去上面的柿子: $$|\cup_{i=1}^{n}S_i| = \sum_{k=1}^{n}(-1)^k\sum_{1\leq i_1 \leq i_2 \leq ... \leq i_k \leq n}|S_{i1}\cap S_{i2} ... \cap S_{ik}|$$ ...

April 17, 2023 · 2 min · jiezi

关于c:6-JNI-全局引用局部引用弱全局引用

从Java虚拟机创立的对象传到本地 C/C++ 代码时就会产生援用。依据Java的垃圾回收机制,只有有援用存在就不会触发该援用指向的Java对象的垃圾回收。这些援用在 JNI 中分为三种 全局援用 (Global Reference)部分援用 (Local Reference)弱全局援用 (Weak Global Reference), JDK 1.2 引入1. 部分援用最常见的援用类型,基本上通过JNI返回来的援用都是部分援用例如,应用NewObject就会返回创立进去的实例的部分援用。部分援用只在该native函数中无效,所有在该函数中产生的部分援用,都会在函数返回的时候主动开释(freed)。也能够应用DeleteLocalRef函数进行手动开释该援用。 想一想既然部分援用可能在函数返回时主动开释,为什么还须要DeleteLocalRef函数呢?实际上部分援用存在,就会避免其指向的对象被垃圾回收。尤其是当一个部分援用指向一个很宏大的对象,或是在一个循环中生成了部分利用;最好的做法就是在应用完该对象后,或在该循环尾部把这个援用开释掉,以确保在垃圾回收器被触发的时候被回收。 在部分援用的有效期中,能够传递到别的本地函数中,要强调的是它的有效期依然只在一次的Java本地函数调用中,所以千万不能用C++全局变量保留它或是把它定义为C++动态局部变量。2. 全局援用全局援用能够逾越以后线程,在多个native函数中无效,不过须要编程人员手动来开释该援用。全局援用存在期间会避免在Java的垃圾回收的回收。与部分援用不同,全局援用的创立不是由 JNI 主动创立的,全局援用须要调用 NewGlobalRef 函数,而开释它须要应用 ReleaseGlobalRef 函数。3. 弱全局援用弱全局利用是 JDK 1.2 新进去的性能,与全局援用类似,创立跟开释都须要由编程人员来进行操作。这种援用与全局援用一样能够在多个本地代码无效,也能够逾越多线程无效;不一样的是,这种援用将不会阻止垃圾回收器回收这个援用所指向的对象。 应用 NewWeakGlobalRef 跟 ReleaseWeakGlobalRef 来产生和开释利用。 4. 对于援用的一些函数jobject NewGlabalRef(jobject obj);jobject NewLocalRef(jobject obj);jobject NewWeakGlobalRef(jobject obj);void DeleteGlobalRef(jobject obj);void DeleteLocalRef(jobject obj);jboolean IsSameObject(jobject obj1, jobject obj2);IsSameObject 函数对于弱援用全局利用还有一个特地的性能,把NULL传入要比拟的对象中,就可能判断弱全局援用所指向的Java对象是否被回收。 5. 缓存jfieldID / jmethodID获取 jfieldID与jmethodID 的时候会通过该属性/办法名称加上签名来查问相应的 jfieldID/jmethodID。这种查问相对来说开销较大。在开发中能够将这些 FieldID/MethodID 缓存起来,这样就只须要查问一次,当前就应用缓存起来的 FieldID/MethodID。 上面介绍两种缓存形式在应用时缓存 (Caching at the Point of Use)在Java类初始化时缓存 (Caching at the Defining Class's Inititalizer)5.1 在应用时缓存在native 代码中应用static局部变量来保留曾经查问过的jfieldID/jmethodID ,这样就不会在每次的函数调用时查问,而只有一次查问胜利后就保存起来了。 ...

April 15, 2023 · 1 min · jiezi

关于c:5JNI-操作数组

1. 数组的分类数组分为两种根本数据类型的数组对象类型(Object[])的数组一个能通用于两种不同数据类型数组的函数GetArrayLength( jarray array);//获取长度2. 根本数据类型数组解决根本数据类型数组的时候,也是跟解决字符串类型,有很类似的函数Get<TYPE>ArrayElements( <TYPE>Array arr, jboolean* isCopied);这类函数能够把Java根本类型的数组转换到C/C++的数组,有两种解决形式,一是拷贝一份传回本地代码,另一个是把指向Java数组的指针间接传回到本地代码。解决完本地的数组后,通过Release<TYPE>ArrayElements来开释数组。 Release<TYPE>ArrayElements( <TYPE>Array arr, <TYPE>* array, jint mode );用这个函数能够抉择将如何解决Java跟C++的数组。是提交、还是撤销等;内存开释还是不开释等。 mode 能够取上面的值: 0 对Java的数组进行更新,并开释 C/C++ 的数组JNI_COMMIT 对Java的数组进行更新,然而不开释C/C++的数组JNI_ABORT 对Java的数组不进行更新,开释C/C++的数组JDK 1.2 为了减少间接传回指向 Java 数组的指针,而减少了以下函数。然而同样的,也会有同GetStringCritical的死锁问题GetPrimitiveArrayCritical( jarray arr, jboolan* isCopied);ReleasePrimitiveArrayCritical(jarray arr, void array, jint mode);在C/C++事后开拓一块内存,而后把Java根本数组类型的数组拷贝到这块内存当中。跟GetStringRegion原理类似Get<TYPE>ArrayRegion( <TYPE>Array arr, jsize, start, jsize len, <TYPE>* buffer);把Java根本数据类型的数组中的指定范畴的元素用 C/C++的数组中的元素来赋值Set<TYPE>ArrayRegion( <TYPE>Array arr, jsize start, jsize len, const <TYPE>* buffer );指定一个长度,而后返回相应Java根本类型的数组<TYPE>Array New<TYPE>Array( jsize len );3. 对象类型数组Object[] JNI 没有提供间接把Java的对象类型数组( Object[] )间接转到 C/C++ 的 jobject[] 数组的函数。而是间接通过GetObjectArrayElement /SetObjectArrayElement 这样的函数来对Java的Object[]数组进行操作。 ...

April 15, 2023 · 1 min · jiezi

关于c:4JNI-操作字符串String

1. 在C/C++本地代码中创立Java的对象1.1 Java对象的创立应用 NewObject 办法应用函数 NewObject 能够用来创立Java对象GetMethod 可能获得构造方法的 jmethodID,如果传入的要取的办法名称设定为 "<init>" 就可能获得构造方法因为构造方法没有返回值,所以构造方法的办法返回值类型的签名始终为void案例 jclass class_date = env->FindClass("java/util/Date");jmethodID mid_date = env->GetMethodId(class_date, "<init>", "()V");jobject now = env->NewObject(class_date, mid_date);jmethodID mid_date_getTime = env->GetMethod(class_date , "getTime", "()j");jlong time = CallLongMethod(now, mid_date_getTime);cout << time << endl;1.2 Java对象的创立 AllocObject应用函数 AllocObject 能够依据传入的 jclass 创立一个 Java 对象,然而他的状态是非初始化的,在应用这个对象之前肯定要调用 CallNonvirtualVoidMethod 来调用该 jclass 的构造函数,这样就能够提早构造函数的调用。这一个局部用的很少,在这里只做简略的阐明。jclass clazz_str = env->FindClass("java/lang.String");jmethodID methodID_str = env->GetMethodID(clazz_str, "<init>", "([C)V");//事后创立一个没有初始化的字符串jobject str = env->AllocObject(clazz_str);//创立一个4个元素的字符串数组,而后以 'B' 'U' 'G' '弄' '潮' '儿' 赋值jcharArray arg = env->NewCharArray(6);env->SetCharArrayRegion(arg, 0, 6, L"BUG弄潮儿");//调用构造函数env->CallNonvirtualVoidMethod(str, clazz_str, methodID_str, arg);jclass clazz_this = env->GetObjectClass( obj );//这里假如这个对象的类中有定义 static String STATIC_STR;jfieldID jfield_str = env->GetStaticField( clazz_this, "STATIC_STR", "Ljava/lang/String;");env->SetStaticObjectField(clazz_str, jfield_str, str);2. Java字符串 & C/C++的字符串在C/C++本地代码中拜访Java的String字符串对象 ...

April 15, 2023 · 2 min · jiezi

关于c:IIC典型IIC时序

典型IIC时序主机向从机发送数据从机向主机发送数据 主机先向从机发送数据,而后从机再向主机发送数据

April 12, 2023 · 1 min · jiezi

关于c:IIC总线

IIC总线简介1、IIC是一种串行、半双工总线,SDA收发数据,SCL用于通信单方时钟的同步;2、IIC总线是一种多主机总线,器件分为主机从机有权发动完结一次通信,从机只能被主机呼叫;当总线上有多个主机同时启用总线时,IIC具备冲突检测仲裁性能搁置谬误的产生;3、每个连贯到IIC总线的器件都有一个惟一的地址(7bit),每个器件都能够作为主机也能够作为从机(同一时刻只能有一个主机),总线上的器件减少和删除不影响其余前器件失常工作;4、IIC总线在通信中总线上发送数据的器件为发送器,接收数据的器件为接收器; IIC总线通信过程1、主机发送一个起始信号启用总线2、主机发送一个字节数据指明从机地址和后续字节的传送方向高7位为从机地址,第0位为传送方向,主机往最初一位写的是0,主机给从机发数据;主机往最初一位写的是1,从机给主机发数据。3、被寻址的从机发送应答信号回应主机4、发送器发送一个字节数据5、接收器发送应答信号,回应发送器.....n、通信实现后主机发送进行信号开释总线 IIC总线寻址形式 起始信号和进行信号SCL为高电平时,SDA由高变为底示意起始信号SCL为高电平时,SDA由底变高示意进行信号起始信号与进行信号都是由主机收回,起始信号产生后总线处于占用状态,进行信号产生后总线处于闲暇状态。 字节传送与应答IIC总线通信时每个字节为8位长度,数据传送时,先传送最高位,后传送低位,发送器发送完一个字节数据后接收器必须发送1位应答位来回应发送器即一帧共有9位。 同步信号IIC总线在进行数据发送时,时钟线SCL为低电平期间发送器向数据线上发送一位数据,在此期间数据线上的信号容许发生变化,时钟线SCL为高电平期间接收器从数据线上读取一位数据,在此期间数据线上的信号不容许发生变化,必须保持稳定。

April 11, 2023 · 1 min · jiezi