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

旅游电子商务网站的品牌建设seo关键词推广渠道

旅游电子商务网站的品牌建设,seo关键词推广渠道,wordpress包邮插件,网页魔域目录 1、C发展历史 2、C版本更新 3、C参考文档 4、C书籍推荐 5、C的程序 6、命名空间 6.1 namespace的作用 6.2 namespace的定义 6.3 namespace的使用 7、C输入输出 8、缺省参数 9、函数重载 10、引用 10.1 引用的概念和定义 10.2 引用的特性 10.3 引用的使…目录 1、C发展历史 2、C版本更新 3、C参考文档 4、C书籍推荐 5、C的程序 6、命名空间 6.1 namespace的作用 6.2 namespace的定义 6.3 namespace的使用 7、C输入输出 8、缺省参数 9、函数重载 10、引用 10.1 引用的概念和定义 10.2 引用的特性 10.3 引用的使用 10.4 const引用 10.5 指针和引用的关系(面试高频考查点) 11、inline 12、nullptr 1、C发展历史 C的起源可以追溯到1979年当时Bjarne Stroustrup(本贾尼·斯特劳斯特卢普这个翻译的名字不同的地方可能有差异)在贝尔实验室从事计算机科学和软件工程的研究工作。面对项目中复杂的软件开发任务特别是模拟和操作系统的开发工作他感受到了现有语言如C语言在表达能力、可维护性和可扩展性方面的不足。 1983年Bjarne Stroustrup在C语言的基础上添加了面向对象编程的特性设计出了C语言的雏形 此时的C已经有了类、封装、继承等核心概念为后来的面向对象编程奠定了基础。这一年该语言被正式命名为C。 在随后的几年中C在学术界和工业界的应用逐渐增多。一些大学和研究所开始将C作为教学和研究的选语言而一些公司也开始在产品开发中尝试使用C。这一时期C的标准库和模板等特性也得到了进一步的完善和发展。 C的标准化使得 C 代码在不同的编译器下表现一致工作于1989年开始并成立了一个ANSI和ISOInternational Standards Organization国际标准化组织的联合标准化委员会。1994年标准化委员会提出了第一个标准化草案。在该草案中委员会在保持斯特劳斯特卢普最初定义的所有特征的同时还增加了部分新特征。 在完成C标准化的第一个草案后不久STLStandard Template Library是惠普实验室开发的系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。在通过了标准化第一个草案之后联合标准化委员会投票并通过了将STL包含到C标准中的提议。STL对C的扩展超出C的最初定义范围。虽然在标准中增加STL是个很重要的决定但也因此延缓了C标准化的进程。 1997年11月14日联合标准化委员会通过了该标准的最终草案。1998年C的ANSI/IS0标准被投入使用。 2、C版本更新 C98这是第一个 ANSI/ISO 标准化的 C 版本发布于 1998 年。它基于 Bjarne Stroustrup 于 1985 年创建的原始 C 设计并加入了一些重要特性如 STL标准模板库、异常处理、I/O Streams、命名空间和 RTTI运行时类型识别。 C03这个版本主要是对 C98 的一些修正和改进发布于 2003 年并未引入新的语言特性所以一般不把它当做重要版本存在感也不强。 C11这是 C 历史上最重大的更新之一有时被称为 C0x因为它原计划在 200x 年发布一直跳票。它引入了大量新特性如自动类型推断auto 关键字、基于范围的 for 循环、Lambda 表达式、智能指针、并发支持、移动语义、nullptr 和更强大的模板功能等。 C14作为 C11 的小幅度更新C14 引入了一些改进和新特性包括泛型 Lambda 表达式、返回类型推导、二进制字面量、数字分隔符、弃用属性等。 C17这个版本进一步提升了 C 的功能和易用性新功能不是很多引入了结构化绑定、if constexpr、std::optional、std::variant、std::string_view、并行算法等特性。 C20 是继 C11 之后又一个重大更新引入了概念concepts、范围库ranges、协程coroutines、模块modules、三元运算符的改进、constexpr 的增强、std::span 等新特性。 C23 是 2023 年 7 月份刚确定下的新标准目前能完整支持 C23 的编译器基本没有。变化包括引入标准库的模块化支持、扩展 constexpr 、增加并行算法、ranges 扩展、this 推导、引入更多的属性和注解、增加 std::mdspan、std::generator 等新特性。 3、C参考文档 不是C官官方文档标准也只更新到C11但是以头文件形式呈现内容比较易看好懂 Reference - C Reference 是C官方文档的英文版更新到了最新的C标准但相比第一个不那么易看 https://en.cppreference.com/w/ 是C官方文档的中文版 https://zh.cppreference.com/w/cpp 4、C书籍推荐 C Primer主要讲解语法经典的语法书籍可以作为语法字典非常好用。 STL源码剖析主要从底层实现的角度结合STL源码庖丁解牛式剖析STL的实现是侯捷老师的经典之作。可以很好的帮助我们学习别人用语法是如何实现出高效简洁的数据结构和算法代码如何使用泛型封装等。让我们不再坐井观天闭门造车适合中后期可以看。 Effctive C本书也是侯捷老师翻译的本书有的一句评价把C程序员分为看过此书的和没看过此书的。本书主要讲了55个如何正高效使用C的条款建议中后期可以看一遍工作1-2年后再看遍相信会有不一样的收获。 5、C的程序 C兼容C语言绝大多数的语法所以C语言实现的hello world依旧可以运行C中需要把定义文件代码后缀名改为.cppvs编译器看到是.cpp就会调用C编译器编译linux下要用g编译不再是gcc // 兼容C语言 // test.cpp #includestdio.h int main() {printf(hello world\n);return 0; } 当然C有一套自己的输入输出严格说C版本的hello world应该是这样写的 // test.cpp // 这里的std cout看不懂没关系下面会依次讲解 #includeiostream using namespace std;int main() {cout hello world\n endl;return 0; } 6、命名空间 6.1 namespace的作用 在C/C中变量、函数和后面要学到的类都是大量存在的这些变量、函数和类的名称将都存在于全局作用域中可能会导致很多冲突。 使用命名空间的目的是对标识符的名称进行本地化以避免命名冲突或名字污染namespace关键字的出现就是针对这种问题的。 c语言项目类似下面程序这样的命名冲突是普遍存在的问题如 #include stdio.h #include stdlib.h int rand 10; int main() {// 编译报错error C2365: “rand”: 重定义以前的定义是“函数”printf(%d\n, rand);return 0; } 在#include stdlib.h中有rand函数int rand (void);此时不知道是rand是变量名函数名 6.2 namespace的定义 • 定义命名空间需要使用到namespace关键字后面跟命名空间的名字然后接一对{}即可{}中即为命名空间的成员。命名空间中可以定义 变量 / 函数 / 类型 等。 • namespace本质是定义出一个域这个域跟全局域各自独立不同的域可以定义同名变量所以下面的rand不在冲突了。 • C中域有 函数局部域全局域命名空间域类域。域影响的是编译时语法查找一个 变量 / 函数 / 类型 出处(声明或定义)的逻辑所以有了域隔离名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑还会影响变量的生命周期命名空间域和类域不影响变量生命周期。 • namespace只能定义在全局当然他还可以嵌套定义。 • 项目工程中多文件中定义的同名namespace会认为是一个namespace不会冲突。 • C标准库都放在一个叫std(standard)的命名空间中。 #include stdio.h #include stdlib.h// 1. 正常的命名空间定义 // Lzc是命名空间的名字⼀般开发中是用项目名字做命名空间名 // 日常练习可以用自己的名字命名 namespace Lzc {// 命名空间中可以定义变量/函数/类型int rand 10;int Add(int left, int right){return left right;}struct Node{struct Node* next;int val;}; }int main() {printf(%p\n, rand);// 打印rand函数的地址printf(%d\n, Lzc::rand);// 打印Lzc命名空间里的rand变量return 0; }//2. 命名空间可以嵌套 namespace S {namespace Lzc{int rand 1;int Add(int left, int right){return left right;}}namespace Ysy{int rand 2;int Add(int left, int right){return (left right) * 10;}} }int main() {printf(%d\n, S::Lzc::rand);// 1printf(%d\n, S::Ysy::rand);// 2printf(%d\n, S::Lzc::Add(1, 2));// 3printf(%d\n, S::Ysy::Add(1, 2));// 30return 0; }//3. 多文件中可以定义同名namespace他们会默认合并到⼀起就像同一个namespace一样 // Stack.h #pragma once #includestdio.h #includestdlib.h #includestdbool.h #includeassert.h namespace Lzc {typedef int STDataType;typedef struct Stack{STDataType* a;int top;int capacity;}ST;void STInit(ST* ps, int n);void STDestroy(ST* ps);void STPush(ST* ps, STDataType x);void STPop(ST* ps);STDataType STTop(ST* ps);int STSize(ST* ps);bool STEmpty(ST* ps); }// Stack.cpp #includeStack.h namespace Lzc {void STInit(ST* ps, int n){assert(ps);ps-a (STDataType*)malloc(n * sizeof(STDataType));ps-top 0;ps-capacity n;}// 栈顶void STPush(ST* ps, STDataType x){assert(ps);// 满了 扩容if (ps-top ps-capacity){printf(扩容\n);int newcapacity ps-capacity 0 ? 4 : ps-capacity* 2;STDataType* tmp (STDataType*)realloc(ps-a,newcapacity * sizeof(STDataType));if (tmp NULL){perror(realloc fail);return;}ps-a tmp;ps-capacity newcapacity;}ps-a[ps-top] x;ps-top;}//... }// test.cpp #includeStack.h // 全局定义了一份单独的Stack typedef struct Stack {int a[10];int top; }ST; void STInit(ST* ps) {} void STPush(ST* ps, int x) {}int main() {// 调用全局的ST st1;STInit(st1);STPush(st1, 1);STPush(st1, 2);printf(%d\n, sizeof(st1));// 调用S namespace的Lzc::ST st2;printf(%d\n, sizeof(st2));Lzc::STInit(st2, 4);Lzc::STPush(st2, 1);Lzc::STPush(st2, 2);return 0; } 6.3 namespace的使用 编译查找一个变量的声明/定义时默认只会在局部或者全局查找不会到命名空间里面去查找。所以下面程序会编译报错。我们要使用命名空间中定义的变量/函数有三种方式 • 指定命名空间访问项目中推荐这种方式。 • using将命名空间中某个成员展开项目中经常访问的不存在冲突的成员推荐这种方式。 • using展开命名空间中全部成员项目不推荐冲突风险很大日常小练习程序为了方便推荐使用。 #includestdio.hnamespace Lzc {int a 0;int b 1; }int main() {// 编译报错error C2065: “a”: 未声明的标识符printf(%d\n, a);return 0; }//1. 指定命名空间访问 int main() {printf(%d\n, Lzc::a);return 0; }//2. using将命名空间中某个成员展开 using Lzc::b; int main() {printf(%d\n, Lzc::a);printf(%d\n, b);printf(%d\n, b);printf(%d\n, b);printf(%d\n, b);printf(%d\n, b);return 0; }//3. 展开命名空间中全部成员 using namespace Lzc; int main() {printf(%d\n, a);printf(%d\n, b);return 0; } 7、C输入输出 • 是 Input Output Stream 的缩写是标准的输入、输出流库定义了标准的输入、输出对象。 • std::cin 是 istream 类的对象它主要面向窄字符narrow characters (of type char)的标准输 入流。 • std::cout 是 ostream 类的对象它主要面向窄字符的标准输出流。 • std::endl 是一个函数流插入输出时相当于插如一个换行字符加刷新缓冲区。 现在的阶段std::endl可以理解为就是\n • 是流提取运算符。C语言还用这两个运算符做位运算左移/右移 • 使用C输入输出更方便不需要像printf/scanf输入输出时那样需要手动指定格式C的输入输出可以自动识别变量类型(本质是通过函数重载实现的这个以后会讲到)其实最重要的是 C的流能更好的支持自定义类型对象的输入输出。 • IO流涉及类和对象运算符重载、继承等很多面向对象的知识这些知识我们还没有讲解所以这里我们只能简单认识一下C IO流的用法后面我们会有专门的一个章节来细节IO流库。 • cout/cin/endl等都属于C标准库C标准库都放在一个叫std(standard)的命名空间中所以要 通过命名空间的使用方式去用他们。 注意这里不是说std里有iostream那为什么还要引入头文件iostream 在C标准库中iostream是一个命名空间包含了处理输入输出操作的主要类和函数如cin、cout等。虽然这些功能已经包含在库中但是通过引入#include iostream头文件程序员可以明确地告诉编译器他们想要使用这部分功能并使得编译器能在程序中定位到这些相关的声明和定义。 头文件不仅提供类和函数的原型还可以包含一些预处理器指令如宏定义以及可能导致链接阶段错误的其他信息。此外通过引用头文件我们能享受到编译器的依赖管理和类型检查提高代码的可读性和维护性。 所以即使库内部已经有了这些内容每使用一次iostream里的功能都需要包含这个头文件这是一种编程约定和组织方式。 • 一般日常练习中我们可以using namespace std实际项目开发中不建议using namespace std。 • VS系列编译器没有包含stdio.h也可以使用printf和scanf因为在iostream里间接包含了。其他编译器可能会报错就加上stdio.h。 #define _CRT_SECURE_NO_WARNINGS 1 #include iostream using namespace std; int main() {int a 0;double b 0.1;char c x;cout a b c endl;std::cout a b c std::endl;scanf(%d%lf, a, b);printf(%d %lf\n, a, b);// 可以自动识别变量的类型cin a;cin b c;cout a endl;cout b c endl;return 0; }#includeiostream using namespace std; int main() {// 在io需求⽐较⾼的地方如部分大量输入的竞赛题中加上以下3行代码// 可以提高CIO效率ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);return 0; } ios_base::sync_with_stdio(false)取消标准输入输出缓冲区stdio与C库的标准输入输出缓冲区之间的同步。这可以避免在处理大量数据时由于等待I/O操作完成而导致的性能瓶颈。 cin.tie(nullptr) 和 cout.tie(nullptr)取消 cin 和 cout 对齐到同一线程的同步。当有多线程同时读写控制台输出时这可以避免因为线程间的同步而产生的额外开销。 在需要频繁输入输出、并且对速度有较高要求的情况下例如编程竞赛或大数据处理等场景加入这些代码有助于提升程序运行效率。然而在日常开发中如果不需要处理这种高并发场景保持默认设置通常是更安全的选择。 8、缺省参数 • 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时如果没有指定实参则采用该形参的缺省值否则使用指定的实参缺省参数分为全缺省和半缺省参数。有些地方把缺省参数也叫默认参数 • 全缺省就是全部形参给缺省值半缺省就是部分形参给缺省值。C规定半缺省参数必须从右往左依次连续缺省不能间隔跳跃给缺省值。 • 带缺省参数的函数调用C规定必须从左到右依次给实参不能跳跃给实参。 • 函数声明和定义分离时缺省参数不能在函数声明和定义中同时出现规定函数声明处给缺省 值。考虑到函数声明和定义处的缺省值不一致等问题 #include iostream #include assert.husing namespace std; void Func(int a 0) {cout a endl; }int main() {Func(); // 没有传参时使用参数的默认值 0Func(10); // 传参时使用指定的实参 10return 0; } #include iostreamusing namespace std;// 全缺省 void Func1(int a 10, int b 20, int c 30) {cout a a endl;cout b b endl;cout c c endl endl; }// 半缺省 void Func2(int a, int b 10, int c 20) {cout a a endl;cout b b endl;cout c c endl endl; }int main() {Func1();Func1(1);Func1(1, 2);Func1(1, 2, 3);Func2(100);Func2(100, 200);Func2(100, 200, 300);return 0; } // Stack.h #include iostream #include assert.husing namespace std;typedef int STDataType; typedef struct Stack {STDataType* a;int top;int capacity; }ST;void STInit(ST* ps, int n 4);// Stack.cpp #includeStack.h// 缺省参数不能声明和定义同时给 void STInit(ST* ps, int n) {assert(ps n 0);ps-a (STDataType*)malloc(n * sizeof(STDataType));ps-top 0;ps-capacity n; }// test.cpp #includeStack.hint main() {ST s1;STInit(s1);// 确定要插入1000个数据初始化时就开好避免扩容ST s2;STInit(s2, 1000);return 0; } 9、函数重载 C支持在同一作用域中出现同名函数但是要求这些同名函数的形参不同可以是 参数个数不同参数类型不同参数类型顺序不同。 注意返回值类型不同不能作为重载条件因为调用时也无法区分 C语言是不支持同一作用域中出现同名函数的。 #includeiostreamusing 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; }// 返回值不同不能作为重载条件因为调用时也无法区分 //void fxx() //{} // //int fxx() //{ // return 0; //}// 下面两个函数构成重载 // f1()调用时会报错存在歧义编译器不知道调用谁 void f1() {cout f() endl; }void f1(int a 10) {cout f(int a) endl; }int main() {Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, a);f(a, 10);return 0; } 10、引用 10.1 引用的概念和定义 引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间 它和它引用的变量共用同一块内存空间。 类型 引用别名 引用对象; #includeiostream using namespace std; int main() {int a 0;// 引用b和c是a的别名int b a;int c a;// 也可以给别名b取别名d相当于还是a的别名int d b;d;// 这里取地址我们看到是⼀样的cout a endl;cout b endl;cout c endl;cout d endl;return 0; } 10.2 引用的特性 • 引用在定义时必须初始化 • 一个变量可以有多个引用 • C规定引用不能改变指向引用一旦引用一个实体再不能引用其他实体 #includeiostreamusing namespace std;int main() {int a 10;// 编译报错“ra”: 必须初始化引⽤//int ra;int b a;int c 20;// 这里并不是让b引用c因为C规定引用不能改变指向// 这里是⼀个赋值即 a 20;b c;cout a endl;cout b endl;cout c endl;return 0; } 10.3 引用的使用 • 引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用别名时同时改变引用对象。 • 引用传参跟指针传参功能是类似的引用传参相对更方便一些。 • 引用返回值的场景相对比较复杂我们在这里简单讲了一下场景还有一些内容后续类和对象章节中会继续深入讲解。 • 引用和指针在实践中相辅相成功能有重叠性但是各有特点互相不可替代(如在链表里的next如果用引用因为不能改变其指向所以不能改变next只能用指针)。C的引用跟其他语言的引用(如Java)是有很大的区别的除了用法最大的区别就是是C引用定义后不能改变指向 Java的引用可以改变指向。 • 一些主要用C代码实现版本数据结构教材中使用C引用替代指针传参目的是简化程序避开复杂的指针。 #includeiostreamusing namespace std;void Swap(int rx, int ry) {int tmp rx;rx ry;ry tmp; }int main() {int x 0, y 1;cout x y endl;Swap(x, y);cout x y endl;return 0; } #includeiostreamusing namespace std;typedef int STDataType; typedef struct Stack {STDataType* a;int top;int capacity; }ST;void STInit(ST rs, int n 4) {rs.a (STDataType*)malloc(n * sizeof(STDataType));rs.top 0;rs.capacity n; }// 栈顶 void STPush(ST rs, STDataType x) {// 满了 扩容if (rs.top rs.capacity){printf(扩容\n);int newcapacity rs.capacity 0 ? 4 : rs.capacity * 2;STDataType* tmp (STDataType*)realloc(rs.a, newcapacity *sizeof(STDataType));if (tmp NULL){perror(realloc fail);return;}rs.a tmp;rs.capacity newcapacity;}rs.a[rs.top] x;rs.top; }// int STTop(ST rs) int STTop(ST rs) {return rs.a[rs.top - 1]; }int main() {ST st1;STInit(st1);STPush(st1, 1);STPush(st1, 2);cout STTop(st1) endl;// 2STTop(st1) 10;// 返回了rs.a[rs.top - 1]的别名可以进行修改cout STTop(st1) endl;// 12return 0; } #includeiostream #includeassert.husing namespace std; typedef struct SeqList {int a[10];int size; }SLT;void SeqPushBack(SLT sl, int x) {}typedef struct ListNode {int val;struct ListNode* next; }LTNode, * PNode;// 指针变量也可以取别名这里LTNode* phead就是给指针变量取别名 // 这样就不需要用⼆级指针了相对而言简化了程序 //void ListPushBack(LTNode** phead, int x) //void ListPushBack(LTNode* phead, int x) void ListPushBack(PNode phead, int x) {PNode newnode (PNode)malloc(sizeof(LTNode));assert(newnode);newnode-val x;newnode-next NULL;if (phead NULL){phead newnode;}else{//...} }int main() {PNode plist NULL;ListPushBack(plist, 1);return 0; } 10.4 const引用 • 可以引用一个const对象但是必须用const引用。const引用也可以引用普通对象因为对象的访 问权限在引用过程中可以缩小但是不能放大。 • 不需要注意的是类似 int rb a * 3; double d 12.34; int rd d; 这样一些场景下a * 3的结果保存在一个临时对象中 int rd d 也是类似在类型转换中会产生 存储中间值的临时对象也就是rb和rd引用的都是临时对象而C规定临时对象具有常性(只能读不能改)所以这里就触发了权限放大必须要用const引用才可以。 • 所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时而临时创建的一个未命名的对象C中把这个未命名对象叫做临时对象。 • C中的临时对象除了上述的 表达式求值类型转换还有以下两种 1. 函数返回值当你调用一个函数并且它的返回类型不是引用或指针时会生成一个临时对象来存储返回值。 int x getSomeValue(); // getSomeValue() 返回一个新的整数x 是对该临时对象的引用 2. 参数传递在函数参数列表中如果传递的是非引用类型的值也会创建临时对象来存储实际传入的数据。 void func(int temp) { // temp 是对一个临时变量的引用 } func(42); // 内部创建了一个临时变量来作为func的参数 int main() {const int a 10;// 编译报错error C2440: “初始化”: ⽆法从“const int”转换为“int ”// 这里的引用是对a访问权限的放⼤//int ra a;// 这样才可以const int ra a;// 编译报错error C3892: “ra”: 不能给常量赋值//ra;// 这里的引用是对b访问权限的缩⼩int b 20;const int rb b;// 编译报错error C3892: “rb”: 不能给常量赋值//rb;return 0; } #includeiostreamusing namespace std;int main() {int a 10;const int ra 30;// 编译报错: “初始化”: 无法从“int”转换为“int ”// 临时对象具有常性// int rb a * 3;const int rb a * 3;double d 12.34;// 编译报错“初始化”: ⽆法从“double”转换为“int ”// 临时对象具有常性// int rd d;const int rd d;return 0; } 10.5 指针和引用的关系(面试高频考查点) C中指针和引用就像两个性格迥异的亲兄弟指针是哥哥引用是弟弟在实践中相辅相成功能有重叠性但是各有特点互相不可替代(如在链表里的next如果用引用因为不能改变其指向所以不能改变next只能用指针)。 • 语法概念上引用是一个变量的取别名不开空间指针是存储一个变量地址要开空间。 • 引用在定义时必须初始化指针可以不初始化。 • C规定引用不能改变指向引用在初始化时引用一个对象后就不能再引用其他对象而指针可以在不断地改变指向对象。 • 引用可以直接访问指向对象指针需要解引用才是访问指向对象。 • sizeof中含义不同引用结果为引用类型的大小但指针始终是地址空间所占字节个数(32位平台下 占4个字节64位下是8byte) • 指针很容易出现空指针和野指针的问题引用很少出现相对更安全一些。 11、inline • inline修饰的函数叫做内联函数编译时C编译器会在调用的地方展开内联函数这样调用内联 函数就不需要建立栈帧了就可以提高效率。 • inline对于编译器而言只是一个建议也就是说你加了inline编译器也可以选择在调用的地方不展开不同编译器关于inline什么情况展开各不相同因为C标准没有规定这个。inline适用于频繁调用的短小函数对于递归函数代码相对多一些的函数加上inline也会被编译器忽略。 • C语言实现宏函数也会在预处理时替换展开但是宏函数实现很复杂很容易出错的且不方便调 试C设计了inline目的就是替代C的宏函数。 • vs编译器 debug版本下面默认是不展开inline的这样方便调试debug版本想展开需要设置⼀下 以下两个地方。 • inline不建议声明和定义分离到两个文件分离会导致链接错误。因为inline被展开就没有函数地址链接时会出现报错建议直接声明处定义。 #includeiostreamusing namespace std;inline int Add(int x, int y) {int ret x y;ret 1;ret 1;ret 1;return ret; } int main() {// 可以通过汇编观察程序是否展开// 有call Add语句就是没有展开没有就是展开了int ret Add(1, 2);cout Add(1, 2) * 5 endl;return 0; }// F.h #include iostreamusing namespace std;inline void f(int i);// F.cpp #include F.hvoid f(int i) {cout i endl; }// main.cpp #include F.hint main() {// 链接错误无法解析的外部符号 void __cdecl f(int) (?fYAXHZ)f(10);return 0; } 12、nullptr NULL实际是一个宏在传统的C头文件(stddef.h)中可以看到如下代码 #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif • C中NULL可能被定义为字面常量0或者C中被定义为无类型指针(void*)的常量。不论采取何种定义在使用空值的指针时都不可避免的会遇到一些麻烦如 在C语言中由于类型检查不严格类型都可以转换f(NULL)两个重载函数都可以调用报错 在C中本想通过f(NULL)调用指针版本的 f(int*)函数但是由于NULL被定义成0调用了f(int x)因此与程序的初衷相悖。f((void*)NULL); 调用会报错(类型检查严格)。 • C11中引入了nullptrnullptr是一个特殊的关键字nullptr是一种特殊类型的字面量它可以转换成任意其他类型的指针类型。 nullptr只能被隐式地转换为指针类型而不能被转换为整数类型。 #includeiostreamusing namespace std;void f(int x) {cout f(int x) endl; }void f(int* ptr) {cout f(int* ptr) endl; }int main() {f(0); // f(int x)f(NULL); // f(int x)f((int*)NULL); // 强制转换 f(int* ptr)// 编译报错error C2665: “f”: 2 个重载函数中没有一个匹配的参数类型// f((void*)NULL);f(nullptr); //f(int* ptr)return 0; }
http://www.w-s-a.com/news/736587/

相关文章:

  • wordpress多站共享授权码wordpress数据库缓存插件
  • 建一个购物网站多少钱上海商标注册
  • 琪觅公司网站开发面点培训学校哪里有
  • 北京建设工程信息网站江苏企业网站建设
  • php电子商务网站建设wordpress新建的页面如何加xml
  • 去百度建网站外贸业务推广
  • 百度seo 站长工具网络营销课程个人总结3000字
  • 设计品牌网站wordpress商城 中文站
  • 公司网站要备案吗百度售后电话人工服务
  • 北京移动网站建设制作一个购物网站
  • 网站优化排名如何做网络开发工程师
  • 域名已有服务器也有怎么做网站pc 手机网站 微站
  • 鞍山网站设计制作网站最好的外贸网站建设
  • 百度手机模板网站新变更营业执照注册号查了发现之前有备案过网站了
  • 群晖个人网站建设建设网站主机免费版
  • 下载好了网站模板怎么开始做网站阿克苏网站建设价格
  • 有谁做彩票网站学会了vue 能搭建一个网站平台
  • 描述对于营销型网站建设很重要飘红效果更佳教育培训排行榜前十名
  • 国外网站有哪些推荐的网站按关键词显示广告图片
  • 互联网招聘网站排名手机网站系统
  • 网站与云平台区别企业网站建设有什么要求
  • wordpress福利网站源码高端网站设计培训机构
  • 网站建设找客户招标网免费
  • 东莞食品网站建设扬州市住房建设局网站
  • 网站色彩心理建设网站的主要功能有哪些
  • 营销型网站建设运营企业宣传网页设计
  • 建设银行官方网站网址sem搜索
  • 简述建设网站的具体步骤网络建设方案ppt
  • 自建门户网站建设工程质量监理协会网站
  • 为企网站版面设计经历了哪几个阶段