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

站内seo内容优化包括做网站运营经理的要求

站内seo内容优化包括,做网站运营经理的要求,网站开发代淘宝店铺装修,wordpress设置文章标题W...Y的主页#x1f60a; 代码仓库分享#x1f495; #x1f354;前言#xff1a; 今天我们依旧来完善补充C#xff0c;区分C与C语言的区别。上一篇我们讲了关键字、命名空间、C的输入与输出、缺省参数等知识点。今天我们继续走进C的世界。 目录 函数重载 函数重载概… W...Y的主页 代码仓库分享  前言 今天我们依旧来完善补充C区分C与C语言的区别。上一篇我们讲了关键字、命名空间、C的输入与输出、缺省参数等知识点。今天我们继续走进C的世界。 目录 函数重载 函数重载概念 C支持函数重载的原理--名字修饰(name Mangling) 引用 引用概念 引用特性 常引用 使用场景 做参数 做返回值 传值、传引用效率比较  值和引用的作为返回值类型的性能比较  引用和指针的区别 内联函数  概念 特性 函数重载 函数重载有点像“一词多义”我们汉语的博大精深就经常会出现一词多义的现象就如同一个笑话一样以前有一个笑话国有两个体育项目大家根本不用看也不用担心。一个是乒乓球一个 是男足。前者是“谁也赢不了”后者是“谁也赢不了” 函数重载概念 函数重载是函数的一种特殊情况C允许在同一作用域中声明几个功能类似的同名函数这 些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同常用来处理实现功能类似数据类型 不同的问题。 C语言是不支持同名函数的这就是C语言的一个“坑”。比如我们想要实现整数的相加与浮点数的相加 int Add(int left, int right) { cout int Add(int left, int right) endl; return left right; } double Add(double left, double right) { cout double Add(double left, double right) endl; return left right; } 当我们在C语言中调用此函数时就会报错但是在C中就不会。在C中函数重载支持的条件是函数名相同参数不同。而函数名相同参数不同的情况有三种 1.类型不同。2.个数不同。3.顺序不同。 举三个不同例子 #includeiostream using namespace std; // 1、参数类型不同 int Add(int left, int right) { cout int Add(int left, int right) endl; return left right; } double Add(double left, double right) { cout double Add(double left, double right) endl; return left right; } // 2、参数个数不同 void f() { cout f() endl; } void f(int a) { cout f(int a) endl; } // 3、参数类型顺序不同 void f(int a, char b) { cout f(int a,char b) endl; } void f(char b, int a) { cout f(char b, int a) endl; } int main() { Add(10, 20); Add(10.1, 20.2); f(); f(10); f(10, a); f(a, 10); return 0; } 这串代码很好诠释了三种不同让我们更容易理解。 注意如果两个函数构成重载不传参数时使用函数参数的缺省参数就会存在二义性  #includeiostream using namespace std; void f() {cout f() endl; } void f(int a 0) {cout f(int a) endl; } int main() {f();return 0; } 上述代码就是一个二义性代码当函数不传参时两个函数都可以调用这时就非常危险。所以我们要避免这种情况的发生 函数重载不同点全部在函数参数的地方却在返回值处没有做过多工作这时为什么呢我们使用反证法假设返回值不同但是函数调用却不知道调用谁所以只能是参数不同才可以区分。 C支持函数重载的原理--名字修饰(name Mangling) 为什么C支持函数重载而C语言不支持函数重载呢 在C/C中一个程序要运行起来需要经历以下几个阶段预处理、编译、汇编、链接。 1.实际项目通常是由多个头文件和多个源文件构成而通过C语言阶段学习的编译链接我们 可以知道【当前a.cpp中调用了b.cpp中定义的Add函数时】编译后链接前a.o的目标 文件中没有Add的函数地址因为Add是在b.cpp中定义的所以Add的地址在b.o中。那么 怎么办呢 2. 所以链接阶段就是专门处理这种问题链接器看到a.o调用Add但是没有Add的地址就 会到b.o的符号表中找Add的地址然后链接到一起。 3. 那么链接时面对Add函数链接接器会使用哪个名字去找呢这里每个编译器都有自己的 函数名修饰规则。 4. 由于Windows下vs的修饰规则过于复杂而Linux下g的修饰规则简单易懂下面我们使 用了g演示了这个修饰后的名字。 5. 通过下面我们可以看出gcc的函数修饰后名字不变。而g的函数修饰后变成【_Z函数长度 函数名类型首字母】。  采用C语言编译器编译后结果 采用C编译器编译后结果  结论在linux下采用g编译完成后函数名字的修饰发生改变编译器将函数参 数类型信息添加到修改后的名字中。 Windows下名字修饰规则 对比Linux会发现windows下vs编译器对函数名字修饰规则相对复杂难懂但道理都 是类似的我们就不做细致的研究了。下面是对函数名修饰C/C的调用约定http://blog.csdn.net/lioncolumn/article/details/10376891 6. 通过这里就理解了C语言没办法支持重载因为同名函数没办法区分。而C是通过函数修 饰规则来区分只要参数不同修饰出来的名字就不一样就支持了重载。 7. 如果两个函数函数名和参数是一样的返回值不同是不构成重载的因为调用时编译器没办 法区分。  所以C语言不支持函数重载C支持函数重载 引用 引用概念 引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空 间它和它引用的变量共用同一块内存空间。比如水浒传中的林冲被称为“豹子头”。 类型 引用变量名(对象名) 引用实体 void TestRef() {int a 10;int ra a;//定义引用类型printf(%p\n, a);printf(%p\n, ra); } 注意引用类型必须和引用实体是同种类型的 引用特性 1. 引用在定义时必须初始化 2. 一个变量可以有多个引用 3. 引用一旦引用一个实体再不能引用其他实体 void TestRef() {int a 10;// int ra;  // 该条语句编译时会出错int ra a;int rra a;printf(%p %p %p\n, a, ra, rra); } 别名与原变量的地址相同所以a创建了变量b是a的别名所以b就是a的结果。 int main() {int a 0;int b a;a;b;cout a endl b endl;return 0; } 注意也可以给别名取别名!!!  当我们创建一个函数时参数是指针时我们也可以用引用进行表示。 void Swap(int left, int right) {int temp left;left right;right temp; } 所以在无哨兵位链表时我们可以用引用代替二级指针! 引用与指针用法非常相似但是引用能完全替代指针吗我们来看一段代码  int main() {int a 0;int c a;int b 1;//c变成b的别名还是给c赋值呢c b;printf(%d %d %d \n, a, b, c);return 0; } 上述代码是c变成b的别名还是给c进行赋值呢如果c变成b的别名就是改变指向的如果b给c进行赋值就不能改变指向。很明显不能改变指向。只是单纯的赋值所以引用与指针的区别出现了引用无法替代指针。 常引用 什么是常引用就是对不可修改的常量做引用这样做与#define宏定义有点类似但是底层逻辑是不相同的宏定义是在预处理阶段进行替换所以常引用可以进行调试出理但是宏定义就不行。 那怎样进行常引用定义呢 void TestConstRef() {const int a 10;//int ra a;  // 该语句编译时会出错a为常量const int ra a;// int b 10; // 该语句编译时会出错b为常量const int b 10;double d 12.34;//int rd d; // 该语句编译时会出错类型不同const int rd d; } 以上是常引用定义的错误点就是因为使用了常引用将本没有权限的内容变得有权限导致不合理所以出现错误。 总结常引用可以将定义的内容权限缩小但是不能进行放大。 使用场景 做参数 void Swap(int left, int right) {int temp left;left right;right temp; } 做参数在上文已经提到这里就不做过多的解释。 做返回值 int Count() {static int n 0;n;// ...return n; } 我们可以将返回值设置为int但是我们没有进行取别名的操作为什么还可以进行返回呢因为计算机可以帮我们自动取一个别名(我们不知道)然后进行函数返回值的返回。我们一般int的类型的返回值是将返回内容进行拷贝一份进行返回因为在函数栈帧调用后函数内存就会被销毁那就有人会闻函数栈帧都被销毁了取的别名传的内容就是一个错误的内容吗 这就会引出我们下面的问题下面代码会输出什么结果 int Add(int a, int b) {int c a b;return c; } int main() {int ret Add(1, 2);Add(3, 4);cout Add(1, 2) is : ret endl;return 0; } 那为什么是7不应该是3吗 注意如果函数返回时出了函数作用域如果返回对象还在(还没还给系统)则可以使用 引用返回如果已经还给系统了则必须使用传值返回。 这里无论是3还是7都是不严谨的有的程序还会返回错误值这都取决于内存是否环给系统。但是我们这里给ret赋值一次但是却出现了第二次调用的值就是因为ret是计算机给出c的别名地址都是相同的所以只要调用一次函数就会更新ret中的值上面函数栈帧图非常清楚我们可以理解一下  所以用引用作为返回值去返回临时变量是非常危险的所以我们应该返回static静态变量  传值、传引用效率比较  以值作为参数或者返回值类型在传参和返回期间函数不会直接传递实参或者将变量本身直 接返回而是传递实参或者返回变量的一份临时的拷贝因此用值作为参数或者返回值类型效 率是非常低下的尤其是当参数或者返回值类型非常大时效率就更低。 #include time.h struct A{ int a[10000]; }; void TestFunc1(A a){} void TestFunc2(A a){} void TestRefAndValue() { A a; // 以值作为函数参数 size_t begin1 clock(); for (size_t i 0; i 10000; i) TestFunc1(a); size_t end1 clock(); // 以引用作为函数参数 size_t begin2 clock(); for (size_t i 0; i 10000; i) TestFunc2(a); size_t end2 clock(); // 分别计算两个函数运行结束后的时间 cout TestFunc1(A)-time: end1 - begin1 endl; cout TestFunc2(A)-time: end2 - begin2 endl; } 当我们进行大规模传参时传值需要进行拷贝而传引用却不需要所以根据上述代码我们可以看到传引用比传值的效率高很多。  值和引用的作为返回值类型的性能比较  #include time.h struct A{ int a[10000]; }; A a; // 值返回 A TestFunc1() { return a;} // 引用返回 A TestFunc2(){ return a;} void TestReturnByRefOrValue() { // 以值作为函数的返回值类型 size_t begin1 clock(); for (size_t i 0; i 100000; i) TestFunc1(); size_t end1 clock(); // 以引用作为函数的返回值类型 size_t begin2 clock(); for (size_t i 0; i 100000; i) TestFunc2(); size_t end2 clock(); // 计算两个函数运算完成之后的时间 cout TestFunc1 time: end1 - begin1 endl; cout TestFunc2 time: end2 - begin2 endl; } 返回值也是如此传值时需要将返回值进行拷贝而传引用不用所以传引用相率高。 总结通过上述代码的比较发现传值和指针在作为传参以及返回值类型上效率相差很大。 引用和指针的区别 在语法概念上引用就是一个别名没有独立空间和其引用实体共用同一块空间。 int main() { int a 10; int ra a; couta aendl; coutra raendl; return 0; } 上述代码所打印出的地址相同所以从语法层面来看引用是没有空间开辟的。  在底层实现上实际是有空间的因为引用是按照指针方式来实现的。 int main() { int a 10; int ra a; ra 20; int* pa a; *pa 20; return 0; } 上述代码我们转成汇编语言进行观看 转成汇编语言后发现引用与指针的逻辑是相同的。  引用和指针的不同点: 1. 引用概念上定义一个变量的别名指针存储一个变量地址。 2. 引用在定义时必须初始化指针没有要求 3. 引用在初始化时引用一个实体后就不能再引用其他实体而指针可以在任何时候指向任何 一个同类型实体 4. 没有NULL引用但有NULL指针 5. 在sizeof中含义不同引用结果为引用类型的大小但指针始终是地址空间所占字节个数(32 位平台下占4个字节) 6. 引用自加即引用的实体增加1指针自加即指针向后偏移一个类型的大小 7. 有多级指针但是没有多级引用 8. 访问实体方式不同指针需要显式解引用引用编译器自己处理 9. 引用比指针使用起来相对更安全 内联函数  概念 以inline修饰的函数叫做内联函数编译时C编译器会在调用内联函数的地方展开没有函数调 用建立栈帧的开销内联函数提升程序运行的效率。 如果在上述函数前增加inline关键字将其改成内联函数在编译期间编译器会用函数体替换函数的 调用。 查看方式 1. 在release模式下查看编译器生成的汇编代码中是否存在call Add 2. 在debug模式下需要对编译器进行设置否则不会展开(因为debug模式下编译器默认不 会对代码进行优化以下给出vs2013的设置方式) 特性 1. inline是一种以空间换时间的做法如果编译器将函数当成内联函数处理在编译阶段会 用函数体替换函数调用缺陷可能会使目标文件变大优势少了调用开销提高程序运 行效率。 2. inline对于编译器而言只是一个建议不同编译器关于inline实现机制可能不同一般建 议将函数规模较小(即函数不是很长具体没有准确的说法取决于编译器内部实现)、不 是递归、且频繁调用的函数采用inline修饰否则编译器会忽略inline特性。下图为 《Cprime》第五版关于inline的建议 3. inline不建议声明和定义分离分离会导致链接错误。因为inline被展开就没有函数地址 了链接就会找不到  所以inline的特性与register非常相似是一种“请求”程序会根据实际进行选择优化 以上就是本次博客全部内容感谢大家观看一键三连支持一下博主吧
http://www.tj-hxxt.cn/news/139159.html

相关文章:

  • 最新网站建设哪家快河南建筑公司排名
  • 微信手机网站门户网站开发难点
  • 网站怎么做支付宝接口网站定制开发
  • 松江品划网站建设维护tvc广告片制作公司
  • 杭州网站开发建设济宁市建设工程质量监督站网站
  • 墙外必去的网站网站建设毕业设计
  • 襄阳作风建设年活动网站厦门公司注册名称查询系统
  • 网站制作 外包天津网站建设 阿土伯
  • 在百度上怎么建立网站吗阿里云网站开发服务器
  • 网站建设流程和费用网站代理服务器连接失败
  • 购物网站开发方案怎么直接做免费网站吗
  • 怎样建设档案馆网站wordpress权限设置
  • 关于h5的网站福田庆三眼睛案例图片
  • 建设一个电子商务网站修复WordPress图片上传错误
  • 消防网站建设的风格做海报的网站知乎
  • 做网站中的剪辑图片wordpress 可爱主题
  • 建设网站计划ppt模板二建报名入口官网
  • 设计建筑的软件上海百度移动关键词排名优化
  • 10个免费网站卖菜网站应该怎么做
  • 网站 自助建站中国建设移动门户网站
  • 网站备案号在哪儿查询教育类网站策划书
  • 潍坊 公司 网站网络运维工程师需要具备什么证书
  • 广州外贸网站设计网站名字重复
  • 企业网站建设协议范本西安wordpress建站
  • 名片型网站开发物流网站如何设计
  • 山西网站开发佛山网站建设服务公司
  • 怎么找回网站用php做的网站怎么上传
  • 网站开发 鲁山风机 东莞网站建设
  • 软装设计网站排名广东网站建设电话咨询
  • 亚马逊网站建设案例分析网站建设工作小组推进表