南阳商城站,站长之家app,制作链接的步骤,淘宝这种网站怎么做的目录 一、C参考文档
二、C在工作领域的应用
三、C学习书籍
四、C的第一个程序
五、命名空间
#xff08;1#xff09;namespace的定义
(2)命名空间的使用
六、C的输入和输出
七、缺省函数
八、函数重载
九、写在最后 一、C参考文档
#xff08;1#xff09;虽…目录 一、C参考文档
二、C在工作领域的应用
三、C学习书籍
四、C的第一个程序
五、命名空间
1namespace的定义
(2)命名空间的使用
六、C的输入和输出
七、缺省函数
八、函数重载
九、写在最后 一、C参考文档
1虽然不是C官方文档且标准只更新到C11但是以头文件的形式呈现内容易看好懂
https://legacy.cplusplus.com/reference/
2C官方文档的中文版和英文版信息很全更新到了最新的C标准但是相比第一个不是那么易看。
https://zh.cppreference.com/w/cpp
https://en.cppreference.com/w/
二、C在工作领域的应用
1大型软件开发。如编译器、数据库、操作系统、浏览器等。
2音视频处理。
3PC客户端开发。⼀般是开发Windows上的桌面软件比如WPS之类的技术栈的话一般是C和 QTQT是⼀个跨平台的C图形用户界面Graphical User InterfaceGUI程序。
4服务端开发。各种大型应⽤网络连接的高并发后台服务。这块Java也比较多C主要用于⼀些对性能要求比较高的地方。如游戏服务、流媒体服务、量化高频交易服务等。
5游戏引擎开发。很多游戏引擎就都是使⽤C开发的游戏开发要掌握C基础和数据结构学习图形学知识掌握游戏引擎和框架了解引擎实现引擎源代码可以学习UE4、Cocos2d-x等开源引擎实现。
6嵌入式开发。嵌入式把具有计算能力的主控板嵌入到机器装置或者电子装置的内部通过软件能够控制这些装置。比如智能手环、摄像头、扫地机器人、智能音响、门禁系统、车载系统等等粗略⼀点嵌入式开发主要分为嵌⼊式应⽤和嵌⼊式驱动开发。
7测试开发/测试。
8机器学习引擎。机器学习引擎。机器学习底层的很多算法都是用C实现的上层用python封装起来。如果你只想准备数据训练模型那么学会Python基本上就够了如果你想做机器学习系统的开发那么需要学会C。
三、C学习书籍 1C Primer主要讲解语法经典的语法书籍前后中期都可以看前期如果自学看可能会有点晦涩难懂中后期作为语法字典非常好用。
2STL源码剖析主要从底层实现的角度结合STL源码庖丁解牛式剖析STL的实现是侯捷老师的经典之作。可以很好的帮助我们学习别人用语法是如何实现出高效简洁的数据结构和算法代码如何使用泛型封装等。
3Effctive C本书也是侯捷老师翻译的本书有的⼀句评价把C程序员分为看过此书的和没看过此书的。本书主要讲了55个如何正确高效使用C的条款。
四、C的第一个程序
C兼容C语言绝大多数的语法所以C语言实现的hello world依旧可以运行
#include stdio.hint main()
{printf(Hello world\n);return 0;
}
当然C有⼀套自己的输入输出C中需要把定义文件代码后缀改为.cppvs编译器看到是.cpp就会调用C编译器编译linux下要用g编译不再是gcc。
严格说C版本的hello world应该是这样写的
#include iostream
using namespace std;int main()
{cout Hello world\n endl;return 0;
}五、命名空间
1namespace的定义
①定义命名空间需要用到namespace关键字后面跟着命名空间的名字然后用一对{}连接{}中为命名空间的成员。命名空间可以定义变量/函数/类型等。
与结构体的区别是{}后面没有分号
namespace zfy
{//变量int rand 10;//函数int Add(int a, int b){return a b;}//类型struct Node{struct Node* next;int val;}
}
②namespace本质是定义出一个域这个域跟全局域各自独立。
③不同的域可以定义同名变量因此下面的两个rand不会冲突。
#include stdio.h
#include stdlib.hnamespace zfy
{int rand 10;int Add(int a, int b){return a b;}struct Node{struct Node* next;int val;}
}int main()
{printf(%p\n,rand);//这里默认访问的是全局的rand函数指针即头文件stdlib.h中的printf(%d\n,zfy::rand);//这里访问的是命名空间中的randreturn 0;
}
④C中域有函数局部域、全局域、命名空间域、类域
域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑所有有了域隔离名字冲突就解决了。
局部域和全局域除了会影响编译查找逻辑还会影响变量的生命周期命名空间域和类域不影响变量生命周期。
//全局域
int rand 10;//命名空间域
namespace zfy
{int rand 10;int Add(int a, int b){return a b;}struct Node{struct Node* next;int val;}
}//函数局部域
int Add(int a, int b)
{return a b;
}int main()
{//函数局部域int rand 10;return 0;
}
⑤namespace只能定义在全局即不能在main函数或者其他函数中定义当然他还可以嵌套定义。
//命名空间的嵌套
namespace zfy
{namespace z{int rand 1;int Add(int left, int right){return left right;}}namespace f{int rand 2;int Add(int left, int right){return (left right)*10;}}
}//调用
int main()
{printf(%d\n, zfy::z::rand);printf(%d\n, zfy::f::rand);printf(%d\n, zfy::z::Add(1, 2));printf(%d\n, zfy::f::Add(1, 2));return 0;
}
⑥项目工程中多文件中定义的同名namespace会认为是⼀个namespace不会冲突。
// Stack.h
#pragma once
#includestdio.h
#includestdlib.h
#includestdbool.h
#includeassert.hnamespace zfy
{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 zfy
{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;}}
比如说我们在Stack.h和Stack.cpp中都定义了名为zfy的命名空间但在使用时会被认为是一个命名空间不会冲突
// test.cpp
#includeQueue.h
#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));// 调⽤zfy namespace的 zfy::ST st2;bzfy::STInit(st2);zfy::STPush(st2, 1);zfy::STPush(st2, 2);printf(%d\n, sizeof(st2));return 0;
}⑦C标准库都放在⼀个叫std(standard)的命名空间中。
(2)命名空间的使用
编译查找⼀个变量的声明/定义时默认只会在局部或者全局查找不会到命名空间里面去查找。所以下面程序会编译报错。
#includestdio.h
namespace zfy
{int a 0;int b 1;
}int main()
{// 编译报错error C2065: “a”: 未声明的标识符 printf(%d\n, a);return 0;
}因此我们要想使用命名空间中定义的变量/函数有三种方式
①指定命名空间访问。项目中推荐这种方式。
// 指定命名空间访问
int main()
{printf(%d\n, zfy::a);return 0;
}②using将命名空间中某个成员展开。项目中经常访问的不存在冲突的成员推荐这种方式。
// using将命名空间中某个成员展开
using zfy::b;int main()
{printf(%d\n, zfy::a);printf(%d\n, b);return 0;
}③展开命名空间中全部成员。项目不推荐冲突风险很大因为可能会与全局中的变量冲突导致编译报错但在日常小练习时较方便推荐使用。
// 展开命名空间中全部成员
using namespce zfy;int main()
{printf(%d\n, a);printf(%d\n, b);return 0;
}六、C的输入和输出
①iostream是Input Output Stream的缩写是标准的输入、输出流库定义了标准的输入、输 出对象。
②std::cin是 istream类的对象它主要面向窄字符narrow characters (of type char)的标准输输入流。
③std::cout 是ostream类的对象它主要面向窄字符的标准输出流。
④std::endl是⼀个函数流插入输出时相当于插入⼀个换行字符加刷新缓冲区。
⑤是流提取运算符。C语言还用这两个运算符做位运算左移/右移)。
⑥使用C输入输出更方便不需要像printf/scanf输入输出时那样需要手动指定格式C的输入输出可以自动识别变量类型(本质是通过函数重载实现的)其实最重要的是 C的流能更好的支持自定义类型对象的输入输出。
#include iostream
using namespace stdint main()
{int a 0;double b 0.1;char c a;printf(%d %lf %c\n,a, b, c);//输出整型std::cout a std::endl;//输出浮点型std::cout b std::endl;//输出字符std::cout c std::endl;//还可以连接使用std::cout a b c std::endl;//输出0 0.1 a//输出换行符std::cout Hello\n;std::cout a \n;std::cout b \n;std::cout c std::endl;//在前面可以使用using namespace std;那么std::cout、std::endl可以写成cout、endl//输入时可以自动识别类型cin a;cin b c;//输出std::cout a std::endl;std::cout b c std::endl;return 0;
}
⑦ cout/cin/endl等都属于C标准库C标准库都放在⼀个叫std(standard)的命名空间中所以要通过命名空间的使用方式去用他们。
⑧⼀般日常练习中我们可以using namespace std实际项目开发中不建议using namespace std。
这里我们没有包含stdio.h仍可以使用printf和scanf其实是在包含stdio.h时间接包含了。vs系列编译器是这样的其他编译器可能会报错。
#includeiostream
using namespace std;int main()
{// 在io需求⽐较⾼的地⽅如部分⼤量输⼊的竞赛题中加上以下3⾏代码可以提⾼CIO效率 ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);return 0;
}七、缺省函数
①缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调用该函数时如果没有指定实参则采用该形参的缺省值否则使用指定的实参缺省参数分为全缺省和半缺省参数。有些地方把缺省参数也叫默认参数
#include iostream
#include assert.h
using namespace std;//全缺省
void Func(int a 0)
{cout a endl;
}int main()
{Func(); // 没有传参时使⽤参数的默认值 Func(10); // 传参时使⽤指定的实参 return 0;
}②全缺省就是全部形参给缺省值半缺省就是部分形参给缺省值。
③C规定半缺省参数必须从右往左依次连续缺省不能间隔跳跃给缺省值。
④带缺省参数的函数调用C规定必须从左到右依次给实参不能跳跃给实参。
#include iostream
using 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 Fun2(int a 10, int b , int c 20)
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);//传参必须从左到右不能跳跃给实参//错误写法Fun1(,2,3);Func2(100);Func2(100, 200);Func2(100, 200, 300);return 0;
}⑤函数声明和定义分离时缺省参数不能在函数声明和定义中同时出现规定必须函数声明给缺省 值。
// Stack.h
#include iostream
#include assert.h
using 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.h
int main()
{ST s1;STInit(s1);//如果不确定大小默认为4//如果确定知道要插⼊1000个数据初始化时⼀把开好避免扩容 ST s2;STInit(s2, 1000);return 0;
}八、函数重载
①C支持在同⼀作用域中出现同名函数但是要求这些同名函数的形参不同可以是参数个数不同或者类型不同。返回值不同不能作为重载条件
#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;
}//返回值不同不能作为重载条件因为调⽤时也⽆法区分
//void fxx()
//{}//int fxx()
//{
// return 0;
//}②这样C函数调用就表现出了多态行为使用更灵活。而C语言是不支持同⼀作用域中出现同名函数的。
// 下⾯两个函数构成重载
// 但是调⽤f()时会报错存在歧义因为编译器不知道调⽤谁
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;
}九、写在最后 我们刚接触C需要一定的知识储备才能进行学习。
敬请期待“入门基础下”~