这里我就不过多的进行描述了有兴趣的可以去网络搜索一番。总而言之从名称上面我们也可以看得出来C是在C的基础上进行不断地优化发展。事实上确实是这样C语言中90以上的语法在C中都适用。同时我们还要知道C作为众多编程语言中的一种它的排名始终是位于前列的并且涉及到的领域也是非常的多就比如以下几个领域操作系统以及大型系统软件开发、.....由此我们可见C的重要性。接下来我们话不多说进入正题。命名空间首先我们来看C语言中的下面这一段代码代码语言javascriptAI代码解释#includestdio.h #includestdlib.h int rand 10; int main() { printf(%d , rand); return 0; } //运行后会报错error C2365 : “rand”: 重定义以前的定义是“函数”这里报错是因为我们定义的变量rand它与库函数里的rand函数名称发生了冲突在C语言中对于此类问题是无法得到有效解决的除非就是自己换一个名称但是在C中针对此类问题是可以通过命名空间关键字namespace得到解决的。域在了解命名空间之前我们先来了解一下域这个概念我们目前所知的域就是全局作用域以及局部作用域局部域与全局域的使用以及生命周期都是不同局部域作用于局部只能在局部使用一般都是自己所在的{}内生命周期出了作用域就会自动销毁。而全局域则是作用于整个工程生命周期也是随着工程的结束而结束。 并且当局部与全局冲突时局部优先。就比如下面这段代码代码语言javascriptAI代码解释#includestdio.h int a 10;//作用于全局 void test() { int a 20;//只能在{}内使用 printf(%d , a);//局部与全局冲突时局部优先这里的a优先在局部域内查找 //如果找不到再去全局查找a进行匹配如果全局还是没找到则报错 //这里优先在局部匹配到了20所以打印结果为20 } int main() { test(); return 0; }但是假如一定要在test中打印的a是位于全局的a而不是局部a应如何做呢这里就涉及到了作用域限定符如下代码语言javascriptAI代码解释#includestdio.h int a 10;//作用于全局 void test() { int a 20;//只能在{}内使用 printf(%d , a);//局部与全局冲突时局部优先这里的a优先在局部域内查找 //如果找不到再去全局查找a进行匹配如果全局还是没找到则报错 //这里优先在局部匹配到了20所以打印结果为20 printf(%d , ::a); // ::前面有个空格意思为在全局域中查找a进行匹配这里的印出来的是10 } int main() { test(); return 0; }命名空间了解域后接下来我们来讲一下命名空间它的关键字为namespace具体使用namespace{}花括号内为命名空间的成员。它的作用是命名空间域也就是说将命名空间内的所有成员作为一个域但是注意一点就是命名空间域只影响成员的使用但是不影响生命周期。如下代码语言javascriptAI代码解释namespace qdy { // 命名空间中可以定义变量/函数/类型 int rand 10; int Add(int x, int y) { return x y; } struct Node { struct Node* next; int val; }; }了解它的用法后接下来我们该怎么使用命名空间呢具体有三种方法用using将命名空间全局展开在做项目时不建议使用做练习时可以利用指定命名空间 一般做项目时使用此方式用using 将命名空间常用展开代码语言javascriptAI代码解释//命名空间全局展开 using namespace std;//std为C标准库 //指定命名空间 std::cout hellow world\n std::endl; //命名空间常用展开 using std::cout; using std::endl;举个例子还是上面的rand假如我想自己使用自己的rand避免和库函数中的rand发生命名冲突可以这么来用代码语言javascriptAI代码解释#includeiostream #includestdlib.h namespace qdy { int rand 10; } int main() { qdy::rand;//这里的rand与qdy域里的rand进行匹配也就是10即11 printf(%d , qdy::rand);//打印结果为11 return 0; }同样假如我们在与他人同时进行某一项工程时最后为了避免与他人发生命名冲突我们就可以利用命名空间来完美解决这个问题但是假如放在C语言的环境下这个问题是解决不了的只能有一方主动服软改成不一样的名字才行。如下代码语言javascriptAI代码解释#includeiostream struct Node { struct Node* left; struct Node* right; int val; }; namespace qdy { struct Node { struct Node* next; int val; }; } int main() { struct qdy::Node Q;//这里上面两个结构体命名发生冲突都是叫Node //但是我们想要用下面的Node就可以利用命名空间 //这里的 Q就是指下面的结构体 return 0; }C输入/输出相信在我们入门C语言时的hello world是梦开始的地方在C语言中的输入输出为scanf与printf接下来我们看下面这样一段简单的代码代码语言javascriptAI代码解释#includeiostream using namespace std; int main() { int n 0; cin n; for (int i 0; i n; i) { cout hello world endl; } return 0; }这段代码执行后的结果是这样的在这里我们要知道cout标准输出对象写到控制台以及cin标准输入对象从键盘中读取它们两个的作用正是对应着C语言里的printf以及scanf。而endl的作用就相当于C语言里的\n换行符是流插入运算符是流提取运算符在C语言中我们使用scanf与printf时要手动加上固定的格式比如输入一个字符串要加上%s输入一个整形要加%d浮点型%f等。但是C中的输入输出则不需要手动输入格式C中的输入输出会自动识别类型。在使用cout以及cin与endl时需要包含头文件iostream,并且要按照命名空间的使用方式来使用stdstd为C标准库。缺省参数概念缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时如果没有指定实参则采用该形参的缺省值否则使用指定的实参。(C语言不支持缺省参数)具体是咋回事呢我们通过一段代码即可理解代码语言javascriptAI代码解释#includeiostream using namespace std; void test(int a 10) { cout a endl; } int main() { test();//10这里我没有传参数但是函数形参里定义了int a10,所以输出的就是10 test(20);//20这里我们传送参数20虽然形参里定义了a10但是由于我们传了参数所以a10就相当于形同虚设 //因此这里打印的是20 }是不是很好理解举个不起恰当的例子缺省参数有点类似生活中的”备胎“当没有别的选择时才用的到你但是只要有人出现你就gg了另外缺省参数还分为全缺省参数以及半缺省参数所谓全缺省参数就是函数的形参全都有指定的值而半缺省参数则是只有一部分的形参有指定值。如下代码语言javascriptAI代码解释//全缺省参数 void Func(int a 10, int b 20, int c 30); //半缺省参数 void Func(int a,int b10, int c20); //这里需要注意半缺省参数必须从右往左依次来给出不能间隔着给即不可以写成int a10,int b,int c30这种形式 //另外缺省参数不能在函数声明和定义中同时出现切记函数重载首先我们先了解一下什么是重载中国语言博大精深往往同一个词在不同的情况下有不同的意义就比如说我们在夸赞一个人时对他说你可真行但是当一个人把事情搞砸时我们再对他说你可真行。这里同样的语句却截然不同的意义这就是重载。函数重载则是函数的一种特殊情况C允许在同一作用域中声明几个功能类似的同名函数这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同常用来处理实现功能类似数据类型不同的问题。就比如下面的代码参数类型不同代码语言javascriptAI代码解释// 1、参数类型不同 //都为int int Add(int left, int right) { cout int Add(int left, int right) endl; return left right; } //都为double double Add(double left, double right) { cout double Add(double left, double right) endl; return left right; } int main() { Add(1,2);//3 Add(1.1.2.2);//3.3 //不会报错但如果是在C语言的环境下则会报错Add重定义具体原因后面会讲 return 0; }参数个数不同代码语言javascriptAI代码解释// 2、参数个数不同 void f() { cout f() endl; } void f(int a) { cout f(int a) endl; } int main() { f();//f() f(1);//f(int a) }形参的类型顺序不同代码语言javascriptAI代码解释//int 在前char在后 void f(int a, char b) { cout f(int a,char b) endl; } //char在前int 在后 void f(char b, int a) { cout f(char b, int a) endl; }可能我们会有个疑问为什么C语言不支持而C却支持呢这里涉及到了函数名修饰规则这里由于windows下的命名规则太过繁杂我们在Linux环境下进行演示。我们知道一个程序要运行起来要经历以下几个阶段预处理、编译、汇编、链接而在链接阶段链接器是如何来寻找我们调用的Add函数呢答案是通过编译器的函数名修饰规则这里我们分别演示C和C两种环境下链接器是如何查找Add的。因此我们得出结论在linux下采用gcc编译完成后函数名字的修饰没有发生改变。接下来我们观察C环境下通过这里就理解了C语言没办法支持重载因为同名函数没办法区分。而C是通过函数修饰规则来区分只要参数不同修饰出来的名字就不一样就支持了重载。另外如果两个函数函数名和参数是一样的返回值不同是不构成重载的因为调用时编译器没办法区分。