当前位置: 首页 > news >正文

杭州学校网站开发做网站彩票网站

杭州学校网站开发,做网站彩票网站,网站建设要购买服务器吗,石家庄网络seo推广文章目录零、前言一、在C中,往vector插入1000个数字#xff0c;怎么做能保证性能最高二、在vector中对10000个数字删除偶数位置的数#xff0c;怎么做保证性能较高三、malloc用delete会出现什么问题四、weak_ptr解决的是什么问题#xff0c;lock返回的对象可以直接使用吗五、… 文章目录零、前言一、在C中,往vector插入1000个数字怎么做能保证性能最高二、在vector中对10000个数字删除偶数位置的数怎么做保证性能较高三、malloc用delete会出现什么问题四、weak_ptr解决的是什么问题lock返回的对象可以直接使用吗五、C中的左值引用和右值引用是什么 如果不写移动构造函数那调用的会是什么六、移动构造函数实例七、std::move八、对于map和unordered_map容器怎么分别做到对字母的大小写不敏感零、前言 今天在朋友圈看到别人发的一套C面经特意思考了一下 一、在C中,往vector插入1000个数字怎么做能保证性能最高 以下是一些可以提高在C中向vector中插入大量数字性能的技巧 预先分配内存空间使用vector::reserve函数预先分配足够的内存空间以避免在插入元素时进行重新分配内存的开销。例如如果你需要插入1000个数字可以使用vector::reserve(1000)在插入前先为向量分配1000个元素的空间。使用移动语义使用std::move将元素插入vector而不是使用拷贝构造函数。因为拷贝构造函数会导致新的内存分配和数据复制而使用移动语义可以避免这些开销。例如可以使用以下代码向vector中插入一个元素 vectorint v; int x 123; v.push_back(std::move(x));批量插入元素: 使用std::vector::insert函数批量插入元素而不是使用单个插入函数。因为单个插入函数可能会多次进行内存分配和内存复制而批量插入函数可以减少这些开销: vectorint v; vectorint data(1000); v.insert(v.end(),data.begin(),data.end());使用移动迭代器: 使用std::make_move_iterator将元素转换为移动迭代器以避免拷贝构造函数的开销。 std::vectorstd::string v; std::string str hello; v.insert(v.end(), std::make_move_iterator(std::begin(str)), std::make_move_iterator(std::end(str)));二、在vector中对10000个数字删除偶数位置的数怎么做保证性能较高 以下是一些可以提高在C中从vector中删除偶数位置的数字的性能的技巧 使用erase-remove惯用法使用erase-remove惯用法从vector中删除偶数位置的数字。该惯用法的思想是先使用std::remove_if算法将所有需要删除的元素移动到vector的末尾然后再使用std::vector::erase函数删除这些元素。例如可以使用以下代码从vector中删除偶数位置的数字 std::vectorint v{...}; // 假设有10000个数字 v.erase(std::remove_if(v.begin(), v.end(), [](const auto x){ return x - v[0] % 2 0; }), v.end());使用reserve预分配内存在删除元素之前使用std::vector::reserve函数预分配足够的内存以避免在移动元素时进行重新分配内存的开销。例如可以使用以下代码预分配内存 std::vectorint v{...}; // 假设有10000个数字 v.reserve(v.size() / 2);使用迭代器递增器在使用std::remove_if算法时使用迭代器递增器std::next来遍历vector中的元素而不是使用索引操作符。例如可以使用以下代码遍历vector中的元素 std::vectorint v{...}; // 假设有10000个数字 v.erase(std::remove_if(v.begin(), v.end(), [i 0](const auto){ return i % 2 0; }), v.end());该代码使用了lambda表达式作为std::remove_if算法的谓词其中[i 0]表示定义了一个名为i的变量并初始化为0。i % 2 0表示先取i的值然后将i加1再判断该值是否为偶数。使用迭代器递增器可以避免使用索引操作符的性能开销。 在这句代码中const auto是一个lambda表达式的参数它代表了一个引用类型的元素。lambda表达式是一个匿名函数它可以接受一个或多个参数这些参数可以是值类型、引用类型或者指针类型。 在这个lambda表达式中使用const auto作为参数表示接受一个任意类型的常量引用。在std::remove_if算法中该lambda表达式作为谓词被调用每次调用时会传入vector中的一个元素并对该元素进行判断。由于lambda表达式中的参数是一个常量引用所以在对该元素进行判断时不会改变原始vector中的元素。 在该lambda表达式中i % 2 0表示先取i的值然后将i加1再判断该值是否为偶数。由于在lambda表达式中定义了一个变量i所以可以通过该变量来判断元素在vector中的位置是否为偶数位置。 三、malloc用delete会出现什么问题 malloc()和delete是两个不同的内存分配和释放函数它们具有不同的行为和约定。使用malloc()分配的内存需要使用free()函数进行释放而使用new运算符分配的内存需要使用delete运算符进行释放。因此如果使用delete释放使用malloc()分配的内存会导致内存错误和未定义的行为。 使用delete释放使用malloc()分配的内存可能会导致以下问题 内存泄漏如果使用delete释放使用malloc()分配的内存将无法正确释放内存导致内存泄漏。 崩溃或异常使用delete释放使用malloc()分配的内存可能会导致程序崩溃或抛出异常因为delete假设它的参数是通过new分配的内存。 不正确的内存释放使用delete释放使用malloc()分配的内存可能会释放掉不属于该内存块的内存或者释放掉一个已经被释放的内存块导致不正确的内存释放。 四、weak_ptr解决的是什么问题lock返回的对象可以直接使用吗 weak_ptr是C11中引入的一种智能指针类型用于解决shared_ptr循环引用导致的内存泄漏问题。在使用shared_ptr进行循环引用时如果存在两个或多个shared_ptr相互引用那么它们之间的引用计数永远不会达到0导致分配的内存永远无法被释放。而weak_ptr则可以作为一个非拥有者指针指向shared_ptr所管理的对象但不会增加引用计数因此不会导致循环引用和内存泄漏问题。 lock()函数是weak_ptr提供的一个成员函数用于返回一个指向weak_ptr所管理对象的shared_ptr对象。lock()函数首先检查weak_ptr所指向的对象是否还存在如果存在则返回一个指向该对象的shared_ptr对象否则返回一个空的shared_ptr对象。使用lock()函数获得shared_ptr对象后可以使用该对象来访问weak_ptr所管理的对象。需要注意的是在使用lock()函数获得shared_ptr对象之前需要检查lock()返回的shared_ptr对象是否为空如果为空则表示weak_ptr所指向的对象已经被销毁了。 返回的shared_ptr对象可以直接使用但需要注意其生命周期。shared_ptr对象在所有指向该对象的shared_ptr对象都被销毁后才会自动销毁因此如果需要使用shared_ptr对象需要确保该对象的生命周期符合预期以避免内存泄漏等问题。另外由于weak_ptr对象只是一个非拥有者指针它并不拥有shared_ptr所管理的对象因此需要确保在使用lock()函数返回的shared_ptr对象之前shared_ptr所管理的对象仍然存在否则会出现未定义的行为。 五、C中的左值引用和右值引用是什么 如果不写移动构造函数那调用的会是什么 左值引用和右值引用都是C中的引用类型用于表示一个对象的别名。其中左值引用表示对一个左值对象的引用而右值引用表示对一个右值对象包括临时对象和将要销毁的对象的引用。 左值引用的声明形式为T表示对类型为T的左值对象的引用而右值引用的声明形式为T表示对类型为T的右值对象的引用。例如以下代码声明了一个左值引用和一个右值引用 int x 123; int lref x; // 左值引用 int rref 123; // 右值引用在C11之前如果没有编写移动构造函数当一个对象被移动构造时实际上是调用了该对象的拷贝构造函数。因此如果一个类没有显式定义移动构造函数但是有拷贝构造函数当使用右值引用移动构造该对象时实际上是调用该类的拷贝构造函数。 在C11及之后的版本中如果一个类定义了移动构造函数那么当使用右值引用移动构造该对象时实际上是调用该类的移动构造函数。移动构造函数是一种特殊的构造函数用于将一个对象的资源如堆内存、文件句柄等从一个对象转移到另一个对象而不进行数据的复制。使用移动构造函数可以避免拷贝大量数据的开销提高程序的性能。 需要注意的是如果一个类既定义了拷贝构造函数又定义了移动构造函数那么在使用右值引用移动构造该对象时会优先调用移动构造函数。如果没有定义移动构造函数但是定义了移动赋值运算符那么在使用右值引用进行赋值操作时会调用移动赋值运算符。如果同时没有定义移动构造函数和移动赋值运算符但是定义了析构函数那么在对象销毁时会使用拷贝构造函数进行拷贝构造。如果以上所有函数都没有定义那么编译器会生成默认的函数实现。 六、移动构造函数实例 class MyClass { public:// 移动构造函数MyClass(MyClass other) noexcept {// 将other对象的资源移动到当前对象data_ other.data_;size_ other.size_;// 将other对象的资源释放other.data_ nullptr;other.size_ 0;}// 其他成员函数// ...private:int* data_;size_t size_; };该移动构造函数使用右值引用作为参数类型并且使用了noexcept关键字表示该函数不会抛出异常。在移动构造函数中首先将另一个对象的资源移动到当前对象然后将另一个对象的资源释放以避免资源的重复释放。 在该例子中假设data_是一个指向堆内存的指针size_表示堆内存的大小。在移动构造函数中将另一个对象的data_指针和size_成员移动到当前对象然后将另一个对象的data_指针置为nullptrsize_成员置为0以表示另一个对象的资源已经被移动到当前对象。 移动构造函数可以在类中定义也可以在类外定义。如果在类外定义需要在函数名前添加类名和作用域解析符::。需要注意的是移动构造函数的参数应该是一个非const右值引用并且应该使用noexcept关键字标记以便在移动操作时可以获得更好的性能和安全性。 移动构造函数的参数为什么要是一个非const右值引用呢 这是因为移动构造函数的参数为非const右值引用是为了表示该参数是一个将要销毁的对象右值对象并且该对象的资源可以被移动到另一个对象中。非const右值引用参数的特点是不能被赋值、取地址和修改值因此移动构造函数可以对该参数进行资源的“窃取”而不必担心该对象被修改或复制。此外由于移动构造函数可以修改参数对象的状态因此该参数不能是const类型的否则会导致编译错误。 七、std::move std::move是C11引入的一个函数模板用于将一个左值转换为右值引用以便在移动构造函数和移动赋值运算符中使用。std::move本质上只是将一个左值强制转换为右值引用它并不会实际地移动对象或改变对象的状态。 在正常情况下使用std::move可以将一个左值对象的资源如堆内存、文件句柄等移动到一个新的对象中从而避免了拷贝大量数据的开销提高了程序的性能。使用std::move时需要注意以下几点 std::move只能用于可移动的对象使用std::move时需要确保对象的类型支持移动语义即有移动构造函数和移动赋值运算符。如果对象没有移动构造函数和移动赋值运算符则无法使用std::move进行移动操作。移动后对象的状态使用std::move将一个对象的资源移动到另一个对象中后原始对象的状态可能会发生变化例如指针会被置为空、计数器会被减少等。需要确保移动后对象的状态符合预期以避免错误的操作。临时对象的生命周期在某些情况下使用std::move将一个左值对象转换为右值引用后会生成一个临时对象。例如将一个std::vector对象传递给函数时如果使用std::move将该对象转换为右值引用则会生成一个临时对象。需要确保临时对象的生命周期符合预期以避免临时对象在不适当的时候被销毁或者访问已经失效的对象。 八、对于map和unordered_map容器怎么分别做到对字母的大小写不敏感 在map和unordered_map容器中实现大小写不敏感可以通过自定义比较函数来实现。具体来说可以重载std::map和std::unordered_map容器中的Compare类型定义一个自己的比较函数对象并将其作为容器的第三个模板参数传递进去。比较函数对象需要重载operator()运算符对于字符串类型的键可以在比较之前将所有字符转换成小写或大写字母然后再进行比较。 以下是一个示例代码 #include iostream #include map #include unordered_map #include string #include algorithmstruct CaseInsensitiveLess {bool operator()(const std::string lhs, const std::string rhs) const{std::string lstr(lhs);std::string rstr(rhs);std::transform(lstr.begin(), lstr.end(), lstr.begin(), ::tolower);//transform函数: transform是一个通用算法用于对指定区间内的元素进行转换并将结果存储在另一个区间中。transform算法接受两个输入迭代器和一个输出迭代器作为参数以及一个一元或二元操作函数对象可通过函数指针、函数对象、Lambda表达式等形式指定将指定区间内的元素依次传入操作函数进行转换然后将转换后的结果存储到输出迭代器指向的位置。std::transform(rstr.begin(), rstr.end(), rstr.begin(), ::tolower);return lstr rstr;} };int main() {std::mapstd::string, int, CaseInsensitiveLess m;m[a] 1;m[B] 2;m[c] 3;std::cout m[A] std::endl; // 输出 1std::cout m[b] std::endl; // 输出 2std::unordered_mapstd::string, int, std::hashstd::string, CaseInsensitiveLess um;um[a] 1;um[B] 2;um[c] 3;std::cout um[A] std::endl; // 输出 1std::cout um[b] std::endl; // 输出 2return 0; }
http://www.w-s-a.com/news/84256/

相关文章:

  • 山西免费网站制作中天建设集团有限公司第九建设公司
  • 好的网站有哪些企业微信开发者工具
  • 网站通栏代码老外做的中国汉字网站
  • 东莞公司建站哪个更便宜wordpress宝塔伪静态
  • 六安网站建设价格做网站好吗
  • 中小企业网站建设咨询湖南省邵阳建设局网站
  • 分类网站一天做几条合适南安网络推广
  • 案例学 网页设计与网站建设百度竞价关键词出价技巧
  • 做公司网站要那些资料南雄网站建设
  • 自己做的网站发布到网上视频播放不了网页游戏奥奇传说
  • 网站效果用什么软件做品牌网站建设等高端服务
  • 四川省成华区建设局网站网站专业制作
  • 网站建设如何开票网站后台怎么做超链接
  • 教育网站设计方案建设网站技术公司电话号码
  • 建网站要定制还是第三方系统传奇网站模板psd
  • 免费搭建企业网站什么叫网站定位
  • 网站建设cms程序员培训班
  • 网站seo技术wordpress editor ios
  • 红酒网站设计成立公司需要哪些手续
  • 广州做网站哪个好网站建网站建设网站站网站
  • 如何快速提升网站pr短剧个人主页简介模板
  • 上海网站建设 永灿百度权重3的网站值多少
  • 公司展示网站模板模板工
  • 网站建设收费详情舟山公司做网站
  • 深圳宝安区住房和建设局网站html模板大全
  • 和田哪里有做网站的地方wordpress地址更改
  • 恒通建设集团有限公司网站企业网站百度指数多少算竞争大
  • 雅虎网站收录提交入口如何使用wordpress搭建网站
  • 微商城网站建设怎么样发稿是什么意思
  • dz建站与wordpress群晖做网站服务器速度快吗