C++区别于C语言的提拔用法(万字总结)

打印 上一主题 下一主题

主题 1522|帖子 1522|积分 4566

1.namespace产生缘故原由

在C语言中,变量,函数,以至于类都是大量存在的,因此会产生大量的名称存在于全局作用域中,可能产生很多冲突,至此c++的祖师爷为避免命名冲突和名字的污染,造出来了关键字namespace来办理这种题目
1.2查找规则

   c/c++规定用任何变量范例的函数都要向上访问,在向上的过程中去找到他的出处在编译时候查找没有在去全局中找。
  比方;


在c语言中rand是包含在头文件#include<stdlib,h>中的函数,因此编译器无法判断是函数还是变量。但事实上用c++可以完美办理。
2.namespace的特点

2.1用namespace来定义命名空间

后加名字加{成员},可定义变量/函数/范例。

   1.在命名空间中定义的变量。
  2.定义函数。
  3.定义布局体范例。
  2.2本质是定义一个全局域各自独立

如2.1中的a在不同的域中可以定义同名且不冲突。
2.3 c++中的域

函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/ 范例出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就办理了。局部域和全局域除了会影响 编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期。
 局部域

局部域是指在函数、代码块(如if、for、while语句块)内部定义的变量所处的作用域。在局部域中定义的变量,其生命周期从定义的位置开始,到地点的代码块竣事时停止。当步伐执行脱离该代码块时,局部变量所占用的内存会被自动开释。
  
  1. #include <iostream>
  2. void testLocalScope() {
  3.     // 局部变量 a,生命周期从这里开始
  4.     int a = 10;
  5.     std::cout << "Local variable a: " << a << std::endl;
  6.     // 代码块结束,局部变量 a 的生命周期结束
  7. }
  8. int main() {
  9.     testLocalScope();
  10.     // 这里无法访问局部变量 a
  11.     return 0;
  12. }
复制代码
 全局域

全局域是指在所有函数、类和命名空间之外定义的变量所处的作用域。全局变量的生命周期从步伐开始执行时就已经分配内存,直到步伐竣事时才会开释内存。
  
  1. #include <iostream>
  2. // 全局变量 b,生命周期从程序开始
  3. int b = 20;
  4. void testGlobalScope() {
  5.     std::cout << "Global variable b: " << b << std::endl;
  6. }
  7. int main() {
  8.     testGlobalScope();
  9.     // 全局变量 b 仍然可以访问
  10.     std::cout << "Global variable b in main: " << b << std::endl;
  11.     // 程序结束,全局变量 b 的生命周期结束
  12.     return 0;
  13. }
复制代码
  命名空间域

命名空间域重要用于办理命名冲突的题目,它只是对标识符进行逻辑上的分组,并不影响变量的生命周期。在命名空间中定义的变量,其生命周期取决于它是全局变量还是局部变量。
  
  1. #include <iostream>
  2. // 全局命名空间
  3. namespace GlobalNS {
  4.     int globalVar = 10;
  5.     void globalFunction() {
  6.         std::cout << "This is a function in the global namespace. globalVar = " << globalVar << std::endl;
  7.     }
  8. }
  9. void testLocalNamespace() {
  10.     // 局部命名空间
  11.     namespace LocalNS {
  12.         int localVar = 20;
  13.         void localFunction() {
  14.             std::cout << "This is a function in the local namespace. localVar = " << localVar << std::endl;
  15.         }
  16.     }
  17.     // 使用局部命名空间中的变量和函数
  18.     std::cout << "Value of localVar in LocalNS: " << LocalNS::localVar << std::endl;
  19.     LocalNS::localFunction();
  20.     // 也可以使用全局命名空间中的变量和函数
  21.     std::cout << "Value of globalVar in GlobalNS: " << GlobalNS::globalVar << std::endl;
  22.     GlobalNS::globalFunction();
  23. }
  24. int main() {
  25.     // 可以直接在 main 函数中使用全局命名空间
  26.     std::cout << "Value of globalVar in GlobalNS (from main): " << GlobalNS::globalVar << std::endl;
  27.     GlobalNS::globalFunction();
  28.     // 调用包含局部命名空间的函数
  29.     testLocalNamespace();
  30.     // 尝试在 main 函数中使用局部命名空间(这是错误的,因为局部命名空间超出了作用域)
  31.     // 下面这行代码会导致编译错误
  32.     // std::cout << LocalNS::localVar << std::endl;
  33.     return 0;
  34. }
复制代码
   域的名字在本身内部只能用一次,同一个域名字不能重复,但不同的域可以
  2.4 namespace只能定义在全局,固然他还可以嵌套定义


   

    图1;嵌套后要区别调用
  图二注:当库很大或项目大还可以套中套来办理命名冲突 
   2.5项⽬⼯程中多⽂件
项⽬⼯程中多⽂件中定义的同名namespace会以为是⼀个namespace,不会冲突。
多⽂件中可以定义同名namespace,他们会默认合并到⼀起,就像同⼀个namespace⼀样
   定个文件一个命名空间都会封在一起 
  比方:当同时定义栈与队列 会产生多个文件
3.命名空间使用

 编译查找⼀个变量的声明/定义时,默认只会在局部大概全局查找,不会到命名空间⾥⾯去查找。所以 下⾯步伐会编译报错。所以我们要使⽤命名空间中定义的变量/函数,有三种⽅式:
3.1指定命名空间访问


   不易堕落,保举使用
  3.2 睁开命名空间中全部成员(睁开头文件与命名空间的区别)


睁开命名空间中全部成员--》变成全局变量因此可能造成命名冲突
睁开头文件是将头文件在预处理阶段将头文件的代码拷贝过来
   不保举,冲突风险大,但是在小训练中为方便保举使用。
  3.3折中using将命名空间中某个成员睁开


 当a用的不多但是b用的多是将b解开变成全局;
   项⽬中经常访问的不存在冲突的成员保举这种⽅式
   前提了解
   <<是流插入运算符,>>是流提取运算符。(C语⾔还⽤这两个运算符做位运算左移/右移)
  cout/cin/endl等都属于C++尺度库,C++尺度库都放在⼀个叫std(standard)的命名空间中
  C++输⼊&&输出&&换行 

1包含文件#include<iostream> 

是Input Output Stream 的缩写,是尺度的输⼊、输出流库,定义了尺度的输⼊、输出对象。
2输出 

std::cout是iostream类的对象,它重要⾯向窄字符的尺度输出流。
  
  1. #include <iostream>
  2. int main()
  3. {
  4.         int a = 0;
  5.         double b = 0.1;
  6.         char c = 'x';
  7. //自动识别变量类型
  8.         std::cout << a << std::endl;
  9.         std::cout << b << " " << c << std::endl;
  10.         return 0;
  11. }
复制代码

   利益:1.连续输出并且与printf可以一起使用2.可自动识别所输出的范例
  坏处:此用法控制输出的小数繁琐相比用printf更好用些
  3输入

std::cin是istream类的对象,它重要⾯向窄字符的尺度输⼊流。
  
  1. #include <iostream>
  2. int main()
  3. {
  4.         int a = 0;
  5.         double b = 0.1;
  6.         char c = 'x';
  7.         std::cin >> a;
  8.         std::cin >> b >> c;
  9.         std::cout << "输出"<<std::endl;
  10.         std::cout << a << std::endl;
  11.         std::cout << b << " " << c << std::endl;
  12.         return 0;
  13. }
复制代码

   注:cout/cin/endl等都属于C++尺度库,C++尺度库都放在⼀个叫std(standard)的命名空间中,所以要 通过命名空间的使⽤⽅式去⽤他们。
  4.换行

std::endl是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加革新缓冲区。
   相比与在C语言中学到的“/n”在c++中std::endl在不同平台上都可以运行
  上述图片有其应用
  缺省函数

1.缺省参数说明

   将声明或定义函数时的参数指定一个值(该值即为缺省值)
  注:当实参没有指定命值就采用缺省值否则采用实参。
   
  1. #include <iostream>
  2. #include <assert.h>
  3. using namespace std;
  4. void Func(int a = 0)//在形参后面加个值
  5. {
  6.         cout << a << endl;
  7. }
  8. int main()
  9. {
  10.         Func(); // 没有传参时,使⽤参数的默认值
  11.         Func(10); // 传参时,使⽤指定的实参
  12.         return 0;
  13. }
复制代码

2.缺省参数的分类

   全缺省就是全部形参给缺省值

   

    半缺省就是部分形参给缺省值

  
 

   注 :C++规定半缺省参数必须从右往左 依次连续缺省,不能间隔跳跃给缺省值。
   

 

3.应用

比方,在栈构建空间时会动态开辟通常以二的倍速增加一定就会亏损,因此控制空间大小显得尤为重要。
  
  1. // Stack.h
  2. #include <iostream>
  3. #include <assert.h>
  4. using namespace std;
  5. typedef int STDataType;
  6. typedef struct Stack
  7. {
  8. STDataType* a;
  9. int top;
  10. int capacity;
  11. }ST;
  12. void STInit(ST* ps, int n = 4);
  13. // Stack.cpp
  14. #include"Stack.h"
  15. // 缺省参数不能声明和定义同时给
  16. void STInit(ST* ps, int n)
  17. {
  18. assert(ps && n > 0);
  19. ps->a = (STDataType*)malloc(n * sizeof(STDataType));
  20. ps->top = 0;
  21. ps->capacity = n;
  22. }
  23. // test.cpp
  24. #include"Stack.h"
  25. int main()
  26. {
  27. ST s1;
  28. STInit(&s1);
  29. // 确定知道要插⼊1000个数据,初始化时⼀把开好,避免扩容
  30. ST s2;
  31. STInit(&s2, 1000);
  32. return 0;
  33. }
复制代码
   在初始化中确定知道要插⼊1000个数据,初始化时⼀把开好,避免扩容
  注:当文件中声明与定义分开时,缺省参数只等在声明中给缺省值。
由于:在定义中只有在编译的时候才会调用。 
c++函数重载

 C++⽀持在同⼀作⽤域中出现同名函数

但是分为参数范例不同,参数个数不同,参数次序不同
1.参数范例不同

  
  1. int Add(int left, int right)
  2. {
  3.         cout << "int Add(int left, int right)" << endl;
  4.         return 0;
  5. }
  6. double Add(double left, double right)
  7. {
  8.         cout << "double Add(double left, double right)" << endl;
  9.         return 0;
  10. }
  11. int main()
  12. {
  13.         Add(10, 20);
  14.         Add(10.1, 20.2);
  15.         return 0;
  16. }
复制代码

2、参数个数不同  

  
  1. #include <iostream>
  2. using namespace std;
  3. void f()
  4. {
  5.         cout << "f()" << endl;
  6. }
  7. void f(int a)
  8. {
  9.         cout << "f(int a)" << endl;
  10. }
  11. int main()
  12. {
  13.         f();
  14.         f(10);
  15.         return 0;
复制代码

3、参数范例次序不同(范例不同)

  
  1. #include <iostream>
  2. using namespace std;
  3. void f(int a, char b)
  4. {
  5.         cout << "f(int a,char b)" << endl;
  6. }
  7. void f(char b, int a)
  8. {
  9.         cout << "f(char b, int a)" << endl;
  10. }
  11. int main()
  12. {
  13.         f(10, 'a');
  14.         f('a', 10);
  15.         return 0;
  16. }
复制代码

特殊的 

   1.返回值不同

  不能作为重载条件,由于调⽤时也⽆法区分
   
  1. void fxx()
  2. {
  3. }
  4. int fxx()
  5. {
  6. return 0;
  7. }
复制代码
   2.一个参数题目

  f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
   
  1. void f1()
  2. {
  3. cout << "f()" << endl;
  4. }
  5. void f1(int a = 10)
  6. {
  7. cout << "f(int a)" << endl;
  8. }
复制代码
引用


 一,概念

   是对已知的变量取别名,并与它引用的对象共用同一块空间
  范例& 引⽤别名 = 引⽤对象;
   
  1. int a = 0;
  2. // 引⽤:b和c是a的别名
  3. int& b = a;
复制代码
   就像在《西游记》中孙悟空(变量)可以叫孙大圣悟空猴哥。这里指的全是他一个人(空间)。

 但是,不得不

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表