nas做网站需要备案吗,天津商城网站设计公司,别墅装修排名,做网站要先申请域名吗1.函数重载 C支持在同一作用域中出现同名函数#xff0c;但是要求这些同名函数的形参不同#xff0c;可以是参数个数不同或者类型不同。这样C函数调用就表现出了多态行为#xff0c;使用更灵活。C语言是不支持同一作用域中出现同名函数的。 1、参数类型不同 2、参数个数不同…1.函数重载 C支持在同一作用域中出现同名函数但是要求这些同名函数的形参不同可以是参数个数不同或者类型不同。这样C函数调用就表现出了多态行为使用更灵活。C语言是不支持同一作用域中出现同名函数的。 1、参数类型不同 2、参数个数不同 3、参数类型顺序不同 注意返回值不同不能作为重载条件因为调用时也无法区分 只是返回类型不同的话下面编译就会报错 这种情况也是不行的下面两个函数构成重载但第二个f1函数使用了缺省参数f1()调用时会报错存在歧义编译器不知道调用谁。 2.引用
2.1引用的概念和定义 引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间它和它引用的变量共用同一块内存空间。比如水浒传中李逵江湖上人称黑旋风林冲外号豹子头 类型 引用别名 引用对象; C中为了避免引入太多的运算符会复用C语言的一些符号比如前面的 和 这里引用也和取地址使用了同一个符号大家注意使用方法角度区分就可以。 如下图引用其实就是取别名本质上还是a只不过给他起了个外号同样在对a引用时改变引用也会改变它本身。 2.2引用的特性 • 引用在定义时必须初始化 • 一个 变量可以有多个引用 • 引用 一 旦引用一个实体再不能引用其他实体 注意引用必须初始化 2.3引用的使用 • 引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被引用对象。 • 引用传参跟指针传参功能是类似的引用传参相对更方便一些。 • 引用返回值的场景相对比较复杂我们在这里简单讲了一下场景还有一些内容后续类和对象中会继续深入讲解。 • 引用和指针在实践中相辅相成功能有重叠性但是各有特点互相不可替代。C的引用跟其他语言的引用(如Java)是有很大的区别的除了用法最大的点C引用定义后不能改变指向Java的引用可以改变指向。 • 一 些主要用C代码实现版本数据结构教材中使用C引用替代指针传参目的是简化程序避开复杂的指针。 先来看一下引用传参 就比如栈其他接口就不去一一实现了如果我们要修改栈顶的话可以直接对STTop()函数的返回值进行操作因为它返回的是栈顶值的引用我们改变它的引用就是改变栈顶本身不然还要去实现修改栈顶数据的接口就显得繁琐了 int STTop(ST rs)
{assert(rs.top 0);return rs.a[rs.top];
}STTop(st1) 10;
cout STTop(st1) endl; 2.4const引用 • 可以引用一 个const对象但是必须用const引用。const引用也可以引用普通对象因为对象的访问权限在引用过程中可以缩小但是不能放大。 • 不过需要注意的是类似 int rb a*3; double d 12.34; int rd d; 这样一些场景下a*3的结果保存在一个临时对象中 int rd d 也是类似在类型转换中会产生临时对象存储中间值也就是rb和rd引用的都是临时对象而C规定临时对象具有常性所以这里就触发了权限放大必须要用常引用才可以。 • 所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象C中把这个未命名对象叫做临时对象。 我们用const修饰变量a那么a只能读不能写如果我们对a引用ra如果不加const修饰我们就可以对ra进行读写操作权限就放大了这样就矛盾了因为ra是a的引用别名a只能读不能写那么ra也应该只能读不能写所以编译就会报错。权限不能放大但是可以缩小就像b对b引用rb并用const修饰那么b可读可写rb只能读不能写。 const引用可以直接引用一个数字常量然后就是上面提到的第二点。 2.5指针和引用的关系
总结一下指针和引用 C中指针和引用就像两个性格迥异的亲兄弟指针是哥哥引用是弟弟在实践中他们相辅相成功能有重叠性但是各有自己的特点互相不可替代。 • 语法概念上引用是一个变量的取别名不开空间指针是存储一个变量地址要开空间。 • 引用在定义时必须初始化指针建议初始化但是语法上不是必须的。 • 引用在初始化时引用一个对象后就不能再引用其他对象而指针可以在不断地改变指向对象。 • 引用可以直接访问指向对象指针需要解引用才是访问指向对象。 • sizeof中含义不同引用结果为引用类型的大小但指针始终是地址空间所占字节个数(32位平台下占4个字节64位下是8字节) • 指针很容易出现空指针和野指针的问题引用很少出现引用使用起来相对更安全一些。 3.inline • 用“ inline”关键字修饰的函数叫做内联函数编译时C编译器会在调用的地方展开内联函数这样调用内联函数就需要建立栈帧了就可以提高效率。 • inline对于编译器而言只是一个建议也就是说你加了inline编译器也可以选择在调用的地⽅不展开不同编译器关于inline什么情况展开各不相同因为C标准没有规定这个。inline适用于频繁调用的短小函数对于递归函数代码相对多一些的函数加上inline也会被编译器忽略。 • C语言实现宏函数也会在预处理时替换展开但是宏函数实现很复杂很容易出错的且不方便调试C设计了inline目的就是替代C的宏函数。 • vs编译器 debug版本下面默认是不展开inline的这样方便调试。 • inline不建议声明和定义分离到两个文件分离会导致链接错误。因为inline被展开就没有函数地址链接时会出现报错。 内联函数能够提高程序效率主要归因于以下几个方面 1. 减少函数调用开销当普通函数被调用时会产生一系列额外的操作比如将参数压入栈、保存当前指令地址、跳转至函数起始地址等。而内联函数在编译阶段会将函数体的代码直接替换到调用处避免了这些额外的操作从而节省了时间。 2. 避免上下文切换函数调用可能涉及到不同的指令地址和上下文切换。使用内联函数可以消除这种切换使得程序的执行更加流畅减少了 CPU 因切换上下文而产生的延迟。 3. 更好的优化机会由于内联函数的代码直接嵌入到调用处编译器能够更好地对整个代码段进行优化。例如可以更有效地利用寄存器、进行指令重排等以提高程序的执行速度。 4. 减少缓存缺失函数调用可能导致跨越不同的缓存行增加缓存缺失的概率。内联函数减少了这种可能性因为相关的代码在物理上更加接近提高了缓存的命中率进而提高了程序的性能。 综上所述内联函数通过消除函数调用的额外开销、优化代码布局和利用缓存等方式有效地提高了程序的执行效率。但需要注意的是内联函数并非适用于所有情况对于复杂的大型函数内联可能会导致代码膨胀等问题。 4.nullptr NULL实际是一个宏在传统的C头文件(stddef.h)中可以看到如下代码 #ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif • C中NULL可能被定义为字面常量0或者C中被定义为无类型指针(void*)的常量。不论采取何种定义在使用空值的指针时都不可避免的会遇到一些麻烦本想通过f(NULL)调用指针版本的f(int*)函数但是由于NULL被定义成0调用了f(int x)因此与程序的初衷相悖。f((void*)NULL)调用会报错。 • C11中引入nullptrnullptr是一个特殊的关键字nullptr是一种特殊类型的字面量它可以转换成任意其他类型的指针类型。使用nullptr定义空指针可以避免类型转换的问题因为nullptr只能被隐式地转换为指针类型而不能被转换为整数类型。 在C中NULL被定义为字面常量0我们可以显式转换为int*如果强制转换为void*则会报错。 这是为什么呢 在 C中 null 实际上被定义为 0 。C是一种强类型语言不允许将 void* 类型的指针隐式转换为其他类型的指针。 虽然在 C 语言中可以进行这样的隐式转换但 C对类型要求更严格。任何指针类型可以隐式转换为 void* 但反过来则必须进行强制类型转换。 例如以下代码在 C中会报错 //cppint* a null;
void* b null;
char* c null;
c a; // 出错
b a; // 通过
c b; // 出错 如果要进行赋值必须进行显式转换 //cppint* a null;
void* b null;
char* c null;
c (char*)a; // 通过
b a; // 通过
c (char*)b; // 通过 这样的设计是为了增强类型安全性避免潜在的类型错误和歧义。在 C11 中引入了 nullptr 关键字来更明确地表示空指针。 nullptr 并非整型类别也不是指针类型但能转换成任意指针类型。使用 nullptr 可以更清晰地表达空指针的意图并且避免了 null 可能导致的一些二义性问题。例如如果有重载的函数 //cppvoid func(int x);
void func(char* y); 调用 func(nullptr) 会明确地调用 func(char* y) 而使用 func(null) 则可能会因为 null 被视为 0 而产生歧义。 所以我们可以用nullptr来解决这一问题可以更清晰的表达空指针的意图。