科技建站网站源码,女生学建筑工程技术就业前景,深圳品牌策划设计方案,wordpress文章页面添加打赏这一章会介绍C入门必须掌握的一些基础概念。
一、函数重载 1、什么是函数重载#xff1f; 函数重载是C相比于C语言的一个重大改进。 即C允许在同一作用域内声明多个功能类似的同名函数#xff0c;这些函数的参数类型 / 个数 / 类型顺序不同。#xff08;注#xff1a;返回…这一章会介绍C入门必须掌握的一些基础概念。
一、函数重载 1、什么是函数重载 函数重载是C相比于C语言的一个重大改进。 即C允许在同一作用域内声明多个功能类似的同名函数这些函数的参数类型 / 个数 / 类型顺序不同。注返回值不同不能构成重载这是由后文会介绍的函数名修饰规则所决定 2、C如何支持函数重载的Linux g编译器环境下 在C/C一中介绍了在C / C中想要形成一个可执行程序必须经历 预处理 -- 编译 -- 汇编 -- 链接 四个阶段。 在编译阶段g 编译器会根据其函数名修饰规则_Z 函数长度 函数名 函数参数类型的首字母可以发现修饰规则中没有返回值因此返回值不同不能构成函数重载对函数进行修饰根据其规则可以看出函数参数不同实际上在编译阶段会被修饰成不同的函数。这也就是C支持函数重载的根基。 示例代码 #include iostream
using namespace std;int add(int x, int y)
{return x y;
}
int add(int x, int y, int z)
{return x y z;
}
int main()
{int res1 add(1, 2);int res2 add(1, 2, 3);
} 3、为什么C语言不支持函数重载C支持 因为C语言的编译器的函数名修饰规则并不会修饰函数名而是按照原先函数名。 二、引用和指针 1、什么是引用 引用是给已经存在的变量取别名 编译器不会为引用开辟空间引用和其引用的变量共用同一块内存空间。 使用格式 类型 引用变量名对象名 引用实体 1.1 有关引用的一些注意事项 1、 跟在类型和变量名之间叫做引用。否则叫做取地址。 2、引用必须在定义时就初始化。 3、一个变量可以有多个引用引用本身也可以有引用。 4、引用一旦引用了一个实体就不能再引用其它实体。 5、非常量应用不能绑定到常量对象 / 临时常量对象 /不同类型的对象常量引用可以绑定到 常量对象、临时常量对象或不同类型的对象需要显式类型转换。 1.2 常引用常量引用 / const 引用 常引用是引用的一种特殊形态允许引用一个对象可以绑定到常量对象 / 临时常量对象 / 不同类型的对象需要显式类型转换但是不能通过该引用修改对象的值主要用途是提高代码的安全性和可读性。 示例代码 void TestConstRef()
{const int a 10;// int ra a; // 该语句编译时会出错a为常量普通引用不能绑定常量对象const int ra a; // 正确方法// int b 10; // 该语句编译时会出错10为临时常量const int b 10; // 正确方法double d 12.34;//int rd d; // 该语句编译时会出错类型不匹配具体原因是由于类型转换时会产生临时变 // 量而临时变量具有常性造成无法引用const int rd static_castint(d); // 正确方法1double rd d // 正确方法2
} 2、指针和引用的区别用法 底层原理 1、引用是定义一个变量的别名与这个变量共用同一内存空间大小也与这个变量的大小 相同而指针存储的是变量的地址需要额外占用一小段空间储存大小也始终是指针 的大小。32位下是4字节、64位下是8字节 2、引用必须在声明的时候就进行初始化不能为空并且一旦初始化就不能改变引用的对 象因为要让编译器知道引用总是指向这个有效的对象以便生成更高效的代码 直接访问目标变量的内存地址而不需要额外的解引用操作指针由于通过解引用显 式访问变量所以可以在声明的时候不初始化也可以随时改变指向的对象。 3、引用就相当于其引用的变量指针则是指针指向下一个内存地址。 4、引用访问绑定的实体直接访问由编译器来优化而指针需要解引用。 5、因为引用不能为空 编译器优化引用比指针更安全。 3、引用的两大使用场景 三、宏的替代方案
宏作为从C语言继承而来的概念C / C一中有详细介绍其有着一定的优点代码复用性强可以提高性能但是其缺点更多由于预编译阶段进行了替换宏不方便调试代码的可读性较差可维护性也不好还容易误用也没有类型安全的检查
所以C提供了三种用来替代宏的方案
替代宏定义标识符const变量 / enum枚举
替代宏函数inline内联函数 1、const变量替代宏定义标识符 // 宏定义标识符
#define PI 3.14159// const变量定义
const double PI 3.14159; 优点 1、类型安全const 变量具有明确的类型编译器可以进行类型检查避免类型错误。 2、调试友好const 变量在调试器中可以显示其值和类型便于调试。 3、作用域控制const 变量可以有局部作用域而宏定义在整个文件范围内有效容易引起 命名冲突。 2、enum枚举替代宏定义标识符 // 宏定义标识符
#define RED 0
#define GREEN 1
#define BLUE 2// 枚举定义标识符
enum Color
{RED,GREEN,BLUE
}; 优点 1、类型安全enum 类型的变量只能取枚举值方便编译器进行类型检查。 2、语义清晰enum 明确表示一组相关的常量代码更具可读性。 3、范围限制枚举值在编译时有固定的范围避免了非法值的赋值。 3、inline 内联函数替代宏函数 3.1 什么是内联函数 以 inline 关键字修饰的函数叫做内联函数 特性在编译的时候C编译器会在调用内联函数的地方直接用函数体替换没有调用普 通函数需要建立栈帧的额外开销可以提升程序运行的效率。 缺点以空间换时间可能会导致目标文件变大。因此内联 inline 关键字实际上只是向 编译器发出的一个内联请求编译器会自己决定是否把这个函数设置为内联函数如 果函数过长编译器将忽略内联请求 使用建议 1、函数规模较小、不是递归调用不频繁的函数可以采用 inline 内联修饰其它 的不建议 2、同时也不建议内联函数的声明与定义分离因为分离了每个cpp文件里都会有内联函数 的内联展开链接器会发现不同的对象文件中都有这个内联函数的定义。无法确定应该 使用哪个定义导致多重定义错误。如果一定要使用内联函数的声明和定义必须放 在同一个地方通常是头文件中确保每个编译单元都能看到完整的内联函数定义 3.2 以内联函数替代宏函数 #define MAX(a, b) ((a) (b) ? (a) : (b)) // #define 定义宏
#define MAX(a, b) ((a) (b) ? (a) : (b))// inline内联函数代替宏函数
inline int max(int a, int b)
{return (a b) ? a : b;
} 优点 1、类型安全inline 函数具有明确的参数类型和返回类型编译器可以进行类型检查。 2、副作用避免宏定义在参数计算上有潜在的副作用而 inline 函数没有这个问题。 3、调试友好inline 函数在调试器中可以显示调用栈和局部变量而宏定义则不行。 4、代码可读性inline 函数的代码更具可读性和可维护性。 四、新的空指针表示方式nullptr
nullptr是C11引入的一种新的空指针表示方式。在C11中sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
在传统的C语言 / C98标准中空指针的表示方式一般是NULL而NULL的定义存在缺陷。 NULL的缺陷 NULL在在 C 中通常定义为 0 或 (void*)0这可能导致一些意外的行为 void f(int)
{coutf(int)endl;
}
void f(int*)
{coutf(int*)endl;
}
int main()
{f(0);f(NULL);f((int*)NULL);return 0;
} 这段代码的本意是希望想通过 f(NULL) 调用指针版本的 f(int*) 函数但是由于NULL被定义成0因此与程序的初衷相悖。 在C98中字面常量0既可以是一个整形数字也可以是无类型的指针(void*)常量但是编译器默认情况下将其看成是一个整形常量如果要将其按照指针方式来使用还必须对其进行强转 (void *)0。 nullptr的优势 1、类型安全nullptr 是一个类型避免了与整数类型的隐式转换。 2、更好的可读性nullptr 明确表示这是一个空指针且不需要包含其它头文件。 3、兼容性更好nullptr 可以更好地与模板一起使用。 4、避免宏定义的问题nullptr 是一个关键字不会受到宏定义的影响。 5、支持 nullptr 类型的检查可以使用 std::nullptr_t 类型进行类型检查。 因此为了提高代码的健壮性在后续表示指针空值时建议最好使用 nullptr。