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

销售网站的技巧深圳专业营销网站设计

销售网站的技巧,深圳专业营销网站设计,商务网站建设模块,一般做一个网站专题页多少钱✨感谢您阅读本篇文章#xff0c;文章内容是个人学习笔记的整理#xff0c;如果哪里有误的话还请您指正噢✨ ✨个人主页#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏#xff1a;c篇–CSDN博客 文章目录 前言一.c/c内存分布二.c/c的动态内存管理方式2.1.c语言的动态内存管… ✨感谢您阅读本篇文章文章内容是个人学习笔记的整理如果哪里有误的话还请您指正噢✨ ✨个人主页余辉zmh–CSDN博客 ✨ 文章所属专栏c篇–CSDN博客 文章目录 前言一.c/c内存分布二.c/c的动态内存管理方式2.1.c语言的动态内存管理方式2.2.c的动态内存管理方式2.3.c/c动态内存管理方式的区别 三.new和delete的底层实现原理3.1operator new和operator delete函数3.2new 和delete的实现原理 四.定位new表达式五.内存泄漏六.模版初阶6.1泛型编程6.2函数模版6.3类模版 前言 内存管理和模板是C编程中两个重要的主题它们共同构成了高效、灵活和可复用的代码基础。内存管理涉及到如何有效利用计算机内存资源确保程序的性能和稳定性而模板则提供了一种参数化类型和函数的机制使得代码能够以类型无关的方式编写从而实现高度的抽象和复用。理解这些概念对于编写高质量和可维护的C代码至关重要。本文将探讨C中的内存管理和模板的基础知识帮助读者掌握这两个核心主题为构建复杂系统打下坚实的基础。 一.c/c内存分布 在一个程序中对于各种不同的数据需要存储在不同的地方比如局部数据存储在栈区静态数据和全局数据存储在静态区或者数据段常量数据存储在常量区或代码段动态申请的数据则是存储在堆上。 在c/c中内存分为以下几个区域 栈区 编译器自动分配和释放。存放函数的局部变量函数参数返回地址等。具有先进后出的特性栈是向下增长的。内存分配率高但空间有限 堆区: 由程序员自己手动分配空间和释放在C语言中由malloc,calloc,realloc等函数分配空间而c中使用new操作符。如果没有释放程序结束时操作系统会回收释放空间时C语言使用free,而c使用delete。内存分配效率相对较低但空间较大。堆是可以向上增长的。 全局或静态区 存放全局变量和静态变量。程序加载时分配内存空间程序结束时释放。 区或代码段 常量区存放常量等只读数据防止修改数据。代码段存放程序的机器指令只能读取不能修改。 这里提供一段代码来分析一下数据的存储区域 int globalVar 1; static int staticGlobalVar1; void Test(){static int staticVar1;int localVar1;int num1[10]{1,2,3,4};char char2[]abcd;const char*pChar3abcd;int*ptr1(int*)malloc(sizeof(int)*4);free(ptr1); }globalVar 全局变量 在数据段静态区 staticGlobalVar 静态全局变量 在数据段静态区 staticVar 静态局部变量 在数据段静态区 localVar 局部变量 在栈 num1局部数组 在栈 char2 字符数组 在栈 *char2 数组元素存储位置 在栈 pchar3 指针变量 在栈 *pchar3常量字符 在代码段常量区 ptr1指针变量 在栈 *ptr1 动态内存 在堆 二.c/c的动态内存管理方式 2.1.c语言的动态内存管理方式 在C语言中申请动态内存主要通过malloc,calloc,realloc等函数这些函数都是堆上申请空间且都是void*类型需要进行数据类型转换在申请完之后还要进行判断是否为空因为申请失败会返回空。 malloc函数在动态存储区申请申请一块指定大小的连续空间返回空间的地址数组返回的是首元素的地址类型为void*类型。释放时使用free函数。 int* p1(int*) malloc(sizeof(int)); free(p1);calloc函数在内存的动态存储区申请指定数量相同大小的内存空间返回空间的地址数组返回的是首元素的地址类型为void*类型和malloc不同的是calloc会将申请成功的空间初始化为0。 int *p2(int*)calloc(3,sizeof(int));realloc函数是对原来申请空间的扩充也就是增加原来空间的大小如果原先空间后面大小充足允许扩充就会原地扩充大小不足时就会重新在其他地方申请空间再将原本空间的数据拷贝过来类型依然是void*类型。 int* p3(int*)realloc(p2,sizeof(int)*10); free(p3);2.2.c的动态内存管理方式 在c中动态内存分配主要通过new,delete两个关键字实现相比于C语言的动态内存分配c的更为直观和方便。 new关键字用于动态申请内存空间不需要显示内存空间大小编译器会根据类型自己计算返回的是申请空间的地址对于数组来说返回的是首元素的地址也可以设置初始值来初始化申请的内存空间。 delete关键字1用于释放动态分配的内存空间对于单个对象使用delete释放对于数组空间需要在delete后加上[]表示释放整个数组空间。 对于内置类型 动态申请一个int类型的未初始化空间 int* ptr1new int; delete ptr1;动态申请一个int类型的空间并初始化为10 //初始化使用的是 int* ptr2new int(10); delete ptr2;动态申请10个int类型的空间 //申请连续的空间时使用的是[]; int* ptr3new int[10]; delete[] ptr3;对于自定义类型 new会调用构造函数delete会调用析构函数而malloc和free不会 class A { public:A(int a0) :int _a(a){cout A() endl;}~A() {cout ~A() endl;} private:int _a; };int main() {//new申请空间后调用构造函数完成初始化A* ptr1 new A;//delete在释放空间前会调用析构函数完成对空间资源的清理delete ptr1;A* ptr2 (A*)malloc(sizeof(A));if (ptr2 NULL) {perror(malloc fail);}free(ptr2);return 0; }2.3.c/c动态内存管理方式的区别 c语言使用的是malloc和free而c使用的是new和delete,他们的共同点是都是从堆上申请内存空间并且需要用户手动释放空间。而不同点是 malloc和free是函数而new和delete是操作符。malloc申请的空间不会初始化而new申请的空间可以初始化,初始化时使用new 类型(初始值)malloc申请空间时需要手动计算空间大小并传递而new只需在new后面加上类型就可以如果申请多个对象时使用new 类型[个数]malloc的返回值为void*类型并且需要强制转换类型而new不需要直接在new后面加上类型既可malloc申请空间失败时返回NULL所以需要判断空间是否申请成功而new不需要判断因为new是抛异常对于自定义类型对象malloc和free只能开辟空间和释放不会调用构造函数和析构函数而new在申请空间后会调用构造函数完成初始化delete在释放空间前会调用析构函数完成对空间中资源的清理 三.new和delete的底层实现原理 3.1operator new和operator delete函数 operator new是系统提供的全局函数new在底层调用operator new全局函数来申请空间而operator new实际上也是通过malloc来申请空间如果malloc申请空间成功就会直接返回否则就会抛异常。 和operator new一样operator delete也是系统提供的全局函数delete在底层通过operator delete全局函数来释放空间而operator delete最终也是通过调用free来释放空间。 下面代码通过模拟实现来演示new和delete如何完成空间的申请和释放 void* operator new(size_t size) {void* ptr malloc(size);if (!ptr) {throw bad_alloc();}cout 申请空间调用operator new函数: endl;cout void* operator new(size_t size) ptr endl;return ptr; }void operator delete(void* ptr) {cout 释放空间调用operator delete函数: endl;cout void operator delete(void* ptr) ptr endl;free(ptr); }class Myclass { public:Myclass() {cout 申请空间后调用构造函数完成初始化: endl;cout Myclass() endl;}~Myclass() {cout 释放空间前调用析构函数完成对象资源的清理: endl;cout ~Myclass() endl;} };int main() {Myclass* ptr new Myclass;cout endl;delete ptr;return 0; }3.2new 和delete的实现原理 对于内置类型 如果申请的是内置类型的空间new和mallocdelete和free基本类似不同点可以看上面的2.3内容。 对于自定义类型 new的原理 1.调用operator new申请空间 2.申请空间成功后调用构造函数完成初始化 new T[N]的原理 1.调用operator new[]函数实际调用operator new函数完成对N个对象空间的申请 2.申请N个空间就要调用N次构造函数完成初始化 delete的原理 1.在释放空间前调用析构函数完成对对象空间中资源的清理 2.调用operator delete函数释放空间 delete []的原理 1.在释放空间前调用N次析构函数完成对N个对象的资源的清理 2.调用operator delete[]函数释放空间实际上是调用operator delete函数来释放空间 四.定位new表达式 在c中定位new表达式是一种特殊的语法结构它允许程序员在自定义的内存位置上构造对象。定位new不会分配内存他只会在指定的内存地址上调用对象的构造函数。使用定位new需要确保提供的内存位置足够大否则可能会导致未定义行为。同样的如果不再需要该对象时需要手动调用析构函数来释放空间因为定位new不会管理内存的生命周期。 以下面这段代码为例 class Myclass { public:Myclass(int a):_a(a){cout Myclass(int a) endl;}~Myclass() {cout Myclass() endl;}private:int _a; };int main() {//分配一块足够大的内存char ptr[sizeof(Myclass)];//在ptr指向的内存上构造Myclass对象//使用定位new格式new(内存空间)类类型(初始化值)Myclass* p new(ptr)Myclass(12);//不再需要该对象时手动调用析构函数p-~Myclass();return 0; }在上面这个例子中ptr是一个字符数组其大小足够容纳一个Myclass对象然后使用定位new在ptr的内存空间上构造一个Myclass对象最后在手动调用析构函数来销毁。 五.内存泄漏 内存泄漏Memory Leak是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放造成系统内存的浪费导致程序运行速度减慢甚至系统崩溃等严重后果。 内存泄漏的常见原因包括 程序员的错误程序员未正确地释放动态内存或者使用了不恰当的数据结构导致内存无法释放。循环引用在使用面向对象的编程语言时两个或多个对象彼此引用导致它们之间形成了循环引用使得这些对象无法被垃圾回收器及时释放。 内存泄漏的解决办法主要包括: 正确使用动态内存分配在使用完动态内存之后及时将其释放。使用内存泄漏检测工具可以自动检测出内存泄漏问题并给出错误信息和定位。常见的内存泄漏检测工具包括Valgrind、GDB、DMalloc、Purify、Electric Fence等。 六.模版初阶 6.1泛型编程 我们首先来看一下下面这段代码 void Swap(int a,intb){int tmpa;ab;btmp; } void Swap(double a,doubleb){double tmpa;ab;btmp; } void Swap(char a,charb){char tmpa;ab;btmp; }如果我们要写一个交换函数对于不同类型的数据需要不同的类型函数虽然可以使用函数重载来实现但是复用率较低而且有新的类型时还需要自己增加对应类型的函数并且可维护性较低如果一个出错可能所有的重载函数均会出错。 那么能不能给编译器一个模版让编译器自己根据类型来生成对应的代码呢?答案是当然可以这就是我们接下来需要了解的泛型编程。 泛型编程编写与类型无关的通用代码是代码复用的一种手段。模版是泛型编程的基础。 模版分为函数模版和类模版 6.2函数模版 函数模版与类型无关在使用时被参数化可以根据使用类型产生对应类型的函数。 函数模版格式 //可以使用typename或者class来定义模版参数但不能使用struct templatetypename/class T1,typename/class T2.... 返回值类型 函数名参数列表{... }以上面的交换函数为例 templatetypename T void Swap(T a, T b) {T tmp a;a b;b tmp; }函数模版的实例化 用不同类型的参数使用函数模版时称为函数模版的实例化实例化分为隐式实例化和显示实例化。 隐式实例化让编译器根据实参推演模版参数的实际类型 templatetypename T void Swap(T a, T b) {T tmp a;a b;b tmp; } int main() {int a 1, b 2;Swap(a, b);double c 3, d 4;Swap(c, d);cout a b endl;cout c d endl;return 0; }显示实例化在函数名前面指定模版参数的实际类型 如果对于a,b两个不同类型的数据使用函数模版时就会产生歧义 templatetypename T T Add(const T a, const T b) {return a b; } int main() {int a 10;double b 20.0;cout (Add(a, b)) endl;return 0; }此时有两种处理方式: 1.用户自己强制转化 Add(a,(int)b);2.使用显示实例化 Addint(a,b);以上两种方式结果都为30 函数模版的原理 在编译阶段对于模版函数的使用编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。 6.3类模版 类模版的定义格式 //使用的是class关键字 templateclass T1,class T2.... class 类模版名 {//类中成员定义.... }以栈Stack为例 templateclass T class Stack { public:Stack(int capacity4):_a(new T[capacity]), _top(0), _capacity(capacity){cout Stack() endl;}//其他成员函数....//析构函数在类中声明在类外定义~Stack();private:T* _a;int _top;int _capacity; }; //在类外定义时需要加模版参数列表 //函数名前加:(类名T::) templateclass T StackT::~Stack() {cout StackT::~Stack() endl;delete _a;_top 0;_capacity 0; }类模版的实例化 类模版实例化与函数模版实例化不同类模版实例化需要再类模版名字后加然后将实例化的类型放在中类模版名字不是真正的类而实例化的结果才是真正的类。 以上面的栈模版为例 int main() {//Stack为类名Stack数据类型才是类型Stackint s1(5);Stackdouble s2(10);Stackchar s3(2);return 0; }以上就是关于c内存管理方式和模版初阶的讲解如果哪里有错的话可以在评论区指正也欢迎大家一起讨论学习如果对你的学习有帮助的话点点赞关注支持一下吧
http://www.ho-use.cn/article/10815635.html

相关文章:

  • 门户网站建设运营百度云 wordpress
  • 只做一页的网站多少钱代理网络手游
  • 杭州网站建设 网络服务如何下载wordpress
  • 商业网站设计惠州中小企业网站制作
  • 网站内链怎么删除wordpress标题带竖
  • 网站自然排名成都百度快照优化排名
  • 网站建设 国外wordpress 微信发布文章
  • 上海文明城市建设网站北京工程建设公共资源交易平台
  • 如何查看网站服务器网络公司加盟代理
  • 多就能自己做网站巴中汽车网站建设
  • 张家港外贸网站建设建设电商网站报价
  • 注册微商店铺如何注册青岛百度排名优化
  • discuz做电影网站软件开发项目预算
  • 南昌建设企业网站网站asp文件只读
  • 东莞正规网站建设如何编写一份网站开发需求文档
  • 西工网站建设设计东莞房价2023年最新房价走势
  • 国有企业投资建设项目厦门seo收费
  • 巧家县住房和城乡建设局网站接网站建设的单子
  • 深圳华强北商业圈广州seo成功案例
  • 网站开发项目报告主机网站建设制作
  • 网站备案要多长时间网站内容更新用什么
  • 美发店网站源码热门关键词
  • 手机网站怎样做解析红河州做网站
  • 杭州鼎易做的网站广州必去的十大景点
  • 用win2008做网站淘宝seo优化
  • 搬瓦工做网站稳定吗无为县建设局网站
  • 用网站做淘宝客怎么样开发银行助学贷款系统登录官网
  • 网站后台访问权限设置新媒体运营方案
  • 山西孝义网站开发工程建设信息都在哪个网站发布
  • 网站建设主要哪些内容wordpress 添加二级