临检中心网站建设,做cpc不做网站可以吗,免费的网站程序哪里好,抖音网站怎么做欢迎来到HarperLee的学习笔记#xff01; 博主主页传送门#xff1a; HarperLee的博客主页! 想要一起进步的uu来后台哦#xff01; 一、什么是C?
在此之前#xff0c;我们所学习的C语言是一种结构化和模块化的语言#xff0c;适合处理较小规模的程序。对于复杂的问题 博主主页传送门 Harper·Lee的博客主页! 想要一起进步的uu来后台哦 一、什么是C?
在此之前我们所学习的C语言是一种结构化和模块化的语言适合处理较小规模的程序。对于复杂的问题规模较大的程序需要高度的抽象和建模时C语言则不合适。为了解决软件危机 20世纪80年代 计算机界提出了面向对象思想OOP即object oriented programming支持面向对象的程序设计语言应运而生。1982年本贾尼·斯特劳斯特卢普Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念发明了一种新的程序语言。为了表达该语言与C语言的渊源关系命名为C。因此 C是基于C语言而产生的它既可以进行C语言的过程化程序设计又可以进行以抽象数据类型为特点的基于对象的程序设计还可以进行面向对象的程序设计。
二、C的发展史
1979年贝尔实验室的本贾尼等人试图分析unix内核的时候试图将内核模块化于是在C语言的基础上进行扩展增加了类的机制完成了一个可以运行的预处理程序称之为 C with classes。C的发展主要经历了以下几个阶段
阶段发展内容C with classes类及派生类、公有和私有成员、类的构造和析构、友元、内联函数、赋值运算符重载等C1.0添加虚函数概念函数和运算符重载引用、常量等C2.0更加完善支持面向对象新增保护成员、多重继承、对象的初始化、抽象类、静态成员以及const成员函数C3.0进一步完善引入模板解决多重继承产生的二义性问题和相应构造和析构的处理C98C标准第一个版本绝大多数编译器都支持得到了国际标准化组织(ISO)和美国标准化协会认可以模板方式重写C标准库引入了STL(标准模板库)C03C标准第二个版本语言特性无大改变主要修订错误、减少多异性C05C标准委员会发布了一份计数报告(Technical ReportTR1)正式更名C0x即计划在本世纪第一个10年的某个时间发布C11增加了许多特性使得C更像一种新语言比如正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等C14对C11的扩展主要是修复C11中漏洞以及改进比如泛型的lambda表达式auto的返回值类型推导二进制字面常量等C17在C11上做了一些小幅改进增加了19个新特性比如static_assert()的文本信息可选Fold表达式用于可变的模板if和switch语句中的初始化器等C20自C11以来最大的发行版引入了许多新的特性比如模块(Modules)、协程(Coroutines)、范围(Ranges)、概念(Constraints)等重大特性还有对已有特性的更新比如Lambda支持模板、范围for支持初始化等C23制定ing中间出现一些小插曲C26……
时间轴如下虽然C技术不断地在发展但是目前大多数的公司使用的是C98和C11标准。
三、C的就业方向涉及领域
根据上图最新的TIOBE调查结果可知C、C、python都是比较热门的编程语言发展前景比较好因此就业前景相对广阔一些自然也相对卷一些。在未来我们至少需要学习两门以上的编程语言因此不要走马观花的学习而是要精益求精实质性的精通掌握一两门语言。这样上手其他语言时也会比较的得心应手。注意排名不能说明哪个语言好哪个不好每门编程语言都有适应自己的应用场景。C的应用领域比较广阔主要包括以下几个领域
软件开发。包括大型系统软件开发例如编译器、数据库、操作系统、浏览器等还有小型软件开发像CAD软件开发、SDK应用开发、军工类软件开发 、数据库开发等。服务器端开发。例如一个美团接单环节商家是否开业是否接单、上架什么菜品、如何接单、如何分配骑手、对个别不合理的行为如何举报拉黑等。游戏开发。**游戏开发要掌握C基础和数据结构学习图形学知识掌握游戏引擎和框架了解引擎实现。**比如魔兽世界、传奇、CS、跑跑卡丁车等。嵌入式和物联网领域。嵌入式把具有计算能力的主控板嵌⼊到机器装置或者电子装置的内部通过软件能够控制这些装置。大致上嵌⼊式开发主要分为嵌入式应⽤和嵌入式驱动开发。常见的岗位有嵌入式开发工程师、驱动开发工程师、系统开发工程师、Linux开发工程师、固件开发工程师等。音视频与图形处理。**数字图像处理中涉及到大量数学矩阵方面的运算对CPU算力要求比较高主要的图像处理算法库和开源库等都是C/C写的⾳视频开发最主要的技术栈就是C。**例如OpenCV、OpenGL、Photoshop等。人工智能。人工智能机器学习的核心是机器学习、算法它们大多数都是C实现的不仅需要很强的数学能力同时一般都要求高学历。测试开发/测试。
校招都是公司需要什么技能自己就学习什么技能的因此要学会包装自己有方向地调衡自己。学习C的命名空间中所以要通过命名空间的使用方式去用他们。C语言中可以通过占位符控制浮点数的精度但是C比较复杂可直接使用C语言的方式C语言和C相辅相成。这⾥我们没有包含stdio.h也可以使用printf和scanf在包含间接包含了。vs系列编译器是这样的其他编译器可能会报错。
#include iostream
#include stdlib.husing namespace std;//全部展开std标准库int main()
{int a 0;double b 3.0;char c x;cout Harper·Lee endl;//cout标准输出对象控制台// 流插入运算符流提取运算符//endlend line相当于换行符std::cout a endl;//因为上面已经展开了就不需要指定了cout a b endl;//可以自动识别变量的类型cin a;cin b c;cout a endl;cout a endl;cout b c endl;//cin标准输入对象键盘return 0;
}运行结果、
#includeiostreamusing namespace std;int main()
{// 在io需求⽐较⾼的地⽅如部分⼤量输⼊的竞赛题中加上以下3⾏代码// 可以提⾼CIO效率ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);return 0;
}六、C参考文档
https://legacy.cplusplus.com/reference/?非C官方文档https://zh.cppreference.com/w/cpp?中文版https://en.cppreference.com/w/?英文官方版书籍参考CPrimer作为语法字典 / Effective C侯捷应用经验和坑 / STL源码剖析库底层、中后期。C学起来很难是必然的因为就语法而言C要解决C语言的一些问题也要追求效率此外历史发展比较早发展历程总会有些许坎坷。
七、命名空间 7.1 C中的域
C中域包括函数局部域全局域命名空间域类域。域影响的是编译时语法查找⼀个变量/函数/类型出处**(声明或定义)**的逻辑所以有了域隔离名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑还会影响变量的生命周期命名空间域和类域不影响变量生命周期。
请注意
在同一个域里面不能重复定义同一个名称的变量。在不同的域里面能定义同一个名称的变量。
7.2 域作用限定符::
**符号 :: **作用可以避开局部的直接访问全局的。:: 域作用限定符左边是空白就默认代表访问的是全局域。用法直接在变量前加上限定符即可。在 .cpp文件中才支持域作用限定符.c 文件中是不支持域作用限定符的。在C语言中当局部变量与全局变量冲突时优先使用局部变量。
//test.cpp
#include stdio.h
int a 10;//全局变量int main()
{int a 5;printf(%d\n, a);//通过局部域作用限定符访问指定命名空间的变量printf(%d\n,::a);//::符号前面是空白(有无空格都一样)默认代表访问的是全局域return 0;
}7.3 命名空间的由来 7.3.1 什么是命名空间
在C/C中变量、函数和后面要学到的类都是大量存在的这些变量、函数和类的名称将都存在于全局作用域中可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化以避免命名冲突或名字污染namespace关键字的出现就是针对这种问题的。
7.3.2 为什么会有命名空间
有如下的代码
#include stdio.h
#include stdlib.hint rand 10;int main()
{printf(%d\n, rand);return 0;
}//我们定义的变量名和库里面的名称冲突了报错首先我们分析一下为什么会有这样的错误报错原因 编译报错error C2365: “rand”: 重定义以前的定义是“函数”。rand在cpp文件里面是定义的一个变量但是rand在stdlib库中代表一个函数就出现了重定义的情况在这里就叫做命名冲突。注意rand作为函数时函数名默认是函数的地址。解决方法这种情况在C语言中可以通过重新修改变量的名字使其不再与关键字或者函数名重名即可在c中可以通过命名空间解决。
#include stdio.h
#include iostream
#include stdlib.hnamespace Harper//定义了一个命名空间域
{int rand 10;//在bit命名空间里面rand仍然是全局变量
}
void func()
{printf(%p\n, rand);//访问的是函数指针函数名默认是函数的地址%d改成%pprintf(%d\n,Harper::rand);//打印访问Harper命名空间中变量rand的值
}
int main()
{func();return 0;
}运行结果
7.4 命名空间的定义
namespace关键字定义全局命名空间域后面跟命名空间的名字然后接⼀对 {} 即可{}中即为命名空间的成员。
#include iostream
#include stdlib.hnamespace Harper
{int year 19;
}int main()
{printf(%d\n, Harper::year);return 0;
}运行结果
7.5 命名空间的性质
命名空间中可以定义变量/函数/类型等。
#include iostream
#include stdlib.h
namespace Harper
{// 命名空间中可以定义变量/函数/类型int rand 10;int Add(int left, int right){return left right;}struct Node{struct Node* next;int val;};
}
int main()
{//函数调用printf(%d\n, Harper::Add(1, 1));//结构体struct Harper::Node p1;//而不是Harper:: struct Node p1;//因为对象是Nodestruct是关键字return 0;
} 命名空间需要定义一个域命名空间域。命名空间域不会影响其中变量的生命周期。为了避免冲突c把标准库的内容定义到了官方的命名空间中这个命名空间叫做std。std是C官方库内容定义的命名空间。
7.6 命名空间的嵌套定义
namespace只能定义在全局但是它可以嵌套定义。就像多个项目组里会定义出一样的名称可以通过namespace解决但如果在一个项目组即同一个命名空间里面各个分工合并代码时就出现冲突了这样就可以通过在同一个命名空间里嵌套再次定义命名空间。
#include iostream
#include stdlib.hnamespace Harper
{namespace Lee{int rand 10;int Add(int left, int right){return left right;}}namespace Aururo{int Sub(int left, int right){return left * right;}}
}int main()
{printf(%d\n, Harper::Lee::Add(1, 1));printf(%d\n, Harper::Aururo::Sub(2, 3));return 0;
}运行结果
7.7 命名空间的合并
同一个工程中允许存在多个相同名称的命名空间编译器最后会将其合并在同一命名空间中。不同⽂件中可以定义同名namespace他们会默认合并到⼀起就像同⼀个namespace⼀样。
#include iostream
#include stdlib.h
namespace Harper
{int rand 5;
}
namespace Harper
{int ret 1;
}
int main()
{printf(%d\n, Harper::rand Harper::ret);return 0;
}//文件中的同理运行结果
7.8 命名空间的使用
编译查找⼀个变量的声明/定义时默认只会在局部或者全局查找不会到命名空间⾥⾯去查找。因此我我们可以通过三三种方式访问命名空间。
7.8.1 域作用限定符访问
指定命名空间访问项目中比较推荐这种方式。
#include stdio.h
#include stdlib.hnamespace Harper
{int rand 10;
}void func()
{printf(%d\n, Harper::rand);
}7.8.2 using部分展开
使用using展开命名空间中某个频繁使用的成员项目中经常访问的不存在冲突的成员可使用此法。
#include iostream
#include stdlib.hnamespace Harper
{int year 19;int a 6;
}using Harper::a;//展开常用的aint main()
{printf(%d\n, Harper::a);return 0;
}7.8.3 using namespace整个展开
使用using namespace展开整个命名空间在项目中并不推荐冲突的风险很大可在日常的小练习中使用全部展开将这个繁琐的指定命名空间过程化简。
#include iostream
#include stdlib.h
//展开整个命名空间
namespace Harper
{int year 19;
}using namespace Harper;int main()
{printf(%d\n, Harper::year);return 0;
}注意
展开命名空间编译器将命名空间的域拆开寻找相当于去掉域这个束缚展开头文件将头文件的内容拷贝过来using namespace相当于把命名变量的隔离墙给拆了就会有命名冲突的风险。
喜欢的uu记得三连支持一下哦