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语句块)内部定义的变量所处的作用域。在局部域中定义的变量,其生命周期从定义的位置开始,到地点的代码块竣事时停止。当步伐执行脱离该代码块时,局部变量所占用的内存会被自动开释。
- #include <iostream>
- void testLocalScope() {
- // 局部变量 a,生命周期从这里开始
- int a = 10;
- std::cout << "Local variable a: " << a << std::endl;
- // 代码块结束,局部变量 a 的生命周期结束
- }
- int main() {
- testLocalScope();
- // 这里无法访问局部变量 a
- return 0;
- }
复制代码 全局域
全局域是指在所有函数、类和命名空间之外定义的变量所处的作用域。全局变量的生命周期从步伐开始执行时就已经分配内存,直到步伐竣事时才会开释内存。
- #include <iostream>
- // 全局变量 b,生命周期从程序开始
- int b = 20;
- void testGlobalScope() {
- std::cout << "Global variable b: " << b << std::endl;
- }
- int main() {
- testGlobalScope();
- // 全局变量 b 仍然可以访问
- std::cout << "Global variable b in main: " << b << std::endl;
- // 程序结束,全局变量 b 的生命周期结束
- return 0;
- }
复制代码 命名空间域
命名空间域重要用于办理命名冲突的题目,它只是对标识符进行逻辑上的分组,并不影响变量的生命周期。在命名空间中定义的变量,其生命周期取决于它是全局变量还是局部变量。
- #include <iostream>
- // 全局命名空间
- namespace GlobalNS {
- int globalVar = 10;
- void globalFunction() {
- std::cout << "This is a function in the global namespace. globalVar = " << globalVar << std::endl;
- }
- }
- void testLocalNamespace() {
- // 局部命名空间
- namespace LocalNS {
- int localVar = 20;
- void localFunction() {
- std::cout << "This is a function in the local namespace. localVar = " << localVar << std::endl;
- }
- }
- // 使用局部命名空间中的变量和函数
- std::cout << "Value of localVar in LocalNS: " << LocalNS::localVar << std::endl;
- LocalNS::localFunction();
- // 也可以使用全局命名空间中的变量和函数
- std::cout << "Value of globalVar in GlobalNS: " << GlobalNS::globalVar << std::endl;
- GlobalNS::globalFunction();
- }
- int main() {
- // 可以直接在 main 函数中使用全局命名空间
- std::cout << "Value of globalVar in GlobalNS (from main): " << GlobalNS::globalVar << std::endl;
- GlobalNS::globalFunction();
- // 调用包含局部命名空间的函数
- testLocalNamespace();
- // 尝试在 main 函数中使用局部命名空间(这是错误的,因为局部命名空间超出了作用域)
- // 下面这行代码会导致编译错误
- // std::cout << LocalNS::localVar << std::endl;
- return 0;
- }
复制代码 域的名字在本身内部只能用一次,同一个域名字不能重复,但不同的域可以
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类的对象,它重要⾯向窄字符的尺度输出流。
- #include <iostream>
- int main()
- {
- int a = 0;
- double b = 0.1;
- char c = 'x';
- //自动识别变量类型
- std::cout << a << std::endl;
- std::cout << b << " " << c << std::endl;
- return 0;
- }
复制代码
利益:1.连续输出并且与printf可以一起使用2.可自动识别所输出的范例
坏处:此用法控制输出的小数繁琐相比用printf更好用些
3输入
std::cin是istream类的对象,它重要⾯向窄字符的尺度输⼊流。
- #include <iostream>
- int main()
- {
- int a = 0;
- double b = 0.1;
- char c = 'x';
- std::cin >> a;
- std::cin >> b >> c;
- std::cout << "输出"<<std::endl;
- std::cout << a << std::endl;
- std::cout << b << " " << c << std::endl;
- return 0;
- }
复制代码
注:cout/cin/endl等都属于C++尺度库,C++尺度库都放在⼀个叫std(standard)的命名空间中,所以要 通过命名空间的使⽤⽅式去⽤他们。
4.换行
std::endl是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加革新缓冲区。
相比与在C语言中学到的“/n”在c++中std::endl在不同平台上都可以运行
上述图片有其应用
缺省函数
1.缺省参数说明
将声明或定义函数时的参数指定一个值(该值即为缺省值)
注:当实参没有指定命值就采用缺省值否则采用实参。
- #include <iostream>
- #include <assert.h>
- using namespace std;
- void Func(int a = 0)//在形参后面加个值
- {
- cout << a << endl;
- }
- int main()
- {
- Func(); // 没有传参时,使⽤参数的默认值
- Func(10); // 传参时,使⽤指定的实参
- return 0;
- }
复制代码
2.缺省参数的分类
全缺省就是全部形参给缺省值
半缺省就是部分形参给缺省值
注 :C++规定半缺省参数必须从右往左 依次连续缺省,不能间隔跳跃给缺省值。
3.应用
比方,在栈构建空间时会动态开辟通常以二的倍速增加一定就会亏损,因此控制空间大小显得尤为重要。
- // 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
- #include"Stack.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
- #include"Stack.h"
- int main()
- {
- ST s1;
- STInit(&s1);
- // 确定知道要插⼊1000个数据,初始化时⼀把开好,避免扩容
- ST s2;
- STInit(&s2, 1000);
- return 0;
- }
复制代码 在初始化中确定知道要插⼊1000个数据,初始化时⼀把开好,避免扩容
注:当文件中声明与定义分开时,缺省参数只等在声明中给缺省值。
由于:在定义中只有在编译的时候才会调用。
c++函数重载
C++⽀持在同⼀作⽤域中出现同名函数
但是分为参数范例不同,参数个数不同,参数次序不同
1.参数范例不同
- int Add(int left, int right)
- {
- cout << "int Add(int left, int right)" << endl;
- return 0;
- }
- double Add(double left, double right)
- {
- cout << "double Add(double left, double right)" << endl;
- return 0;
- }
- int main()
- {
- Add(10, 20);
- Add(10.1, 20.2);
- return 0;
- }
复制代码
2、参数个数不同
- #include <iostream>
- using namespace std;
- void f()
- {
- cout << "f()" << endl;
- }
- void f(int a)
- {
- cout << "f(int a)" << endl;
- }
- int main()
- {
- f();
- f(10);
- return 0;
复制代码
3、参数范例次序不同(范例不同)
- #include <iostream>
- using namespace std;
- 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;
- }
- int main()
- {
- f(10, 'a');
- f('a', 10);
- return 0;
- }
复制代码
特殊的
1.返回值不同
不能作为重载条件,由于调⽤时也⽆法区分
- void fxx()
- {
- }
- int fxx()
- {
- return 0;
- }
复制代码 2.一个参数题目
f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
- void f1()
- {
- cout << "f()" << endl;
- }
- void f1(int a = 10)
- {
- cout << "f(int a)" << endl;
- }
复制代码 引用
一,概念
是对已知的变量取别名,并与它引用的对象共用同一块空间。
范例& 引⽤别名 = 引⽤对象;
- int a = 0;
- // 引⽤:b和c是a的别名
- int& b = a;
复制代码 就像在《西游记》中孙悟空(变量)可以叫孙大圣,悟空,猴哥。这里指的全是他一个人(空间)。
但是,不得不 |