一、命名空间
二、c语言中的命名冲突问题
//#include<stdio.h>
//1.我们定义的函数名、变量名可能会和库函数里面的相同
例如:
//#include<stdlib.h>
//int main(void)
//{
// int rand=0;//此处的rand编译就不会通过,因为stdlib.h的头文件里面包含着随机函数就是这个名字
//}
//2.以后的项目中,需要很多人来同时完成一个项目,一个项目被划分成不同的模块,会有人在不同的模块中使用了相同的变量名字或者函数名字。
//也就是说c语言中并没有很好的办法解决这个问题
三、关键字:namespace ----该关键字是用来定义命名空间的
//1.这个关键字就是用来解决,命名冲突问题的
//例如:
//#include<stdlib.h>//这个头文件里面包含着rand随机函数
//
//namespace llk //定义了一个名为llk的命名空间,看见llk也就是说这个命名空间的名字是自定义的 -----但是这个命名空间只能在函数外面定义,本质是定义了域
//{
// int rand=6;//虽然调用了stdlib.h头文件,但是还是能成功自定义和库函数名相同的自定义变量
//}
//
//int main(void)
//{
// printf("%d ",rand);//这样普通的方式去访问访问的是头文件里面的函数的地址
//}
//2.补充
//定义的命名空间就是一个----域
//这个域的意思就是例如全局变量的作用域是文件,局部变量的作用域啥是这个函数
//函数使用变量的规则是:优先在局部变量中查找使用的变量,如果没有,再去全局变量中查找、再接着是引用的头文件中
四、访问命名空间中的变量(访问自定义域中的变量) ----使用符号 ::
//1.例如;
//#include<stdlib.h>
//
//namespace llk
//{
// int rand =9;//此处定义的变量其性质还是全局变量,放在静态区里面
//
// int add(int x,int y)//除了在自定义空间中定义变量,还能定义函数
// {
// return x+y;
// }
//
// typedef struct test//也能定义各种类型,还能定义的有很多,枚举、联合、等等等
// {
// int a=9;
// int arr[8]={0};
// }test;
//
// struct test1
// {
// int a=9;
// };
//}
//
//int test=99;//这个地方test的名字可以和主函数里面的test相同是因为所在的域不同,这个test变量所在的地方是全局域
int rand=999;//局部变量里面能够定义rand,因为库函数包括的rand函数算作在全局变量中
//int main(void)
//{
// int test=10086;//这个test在的是局部域
// printf("%d\n",rand);//这样直接访问是访问的库函数里面的函数名字
// printf("%d\n",llk::rand);//这样才是访问自定义域中的变量
// printf("%d\n",test);//优先访问的这个名字肯定局部的
// printf("%d\n",::test);//::左边是空白的,空白的意思就是去全局域中去查找。
//}
//2.如何使用命名空间中的变量 用的1的llk
//int main(void)
//{
// llk::rand=10086;
// llk::test t1={1,{1,2,3,4,5}};//里面递重命名后的结构体可以这样用
// struct llk::test1 t2={2};
// int add=llk::add(5,6);
// printf("%d\n",llk::rand);
// printf("%d\n",t1.a);
// printf("%d\n",t2.a);
// printf("%d\n",add);
//}
//3.命名空间的循环嵌套
//namespace llk1
//{
// namespace llk2
// {
// int a=9;
// }
//}
//int main(void)
//{
// printf("%d",llk1::llk2::a);
//}
//4.命名空间的名字相同
//命名空间相同的情况下会合并在一起,
// 比如一个test.h头文件中,命名空间包含了函数声明
//namespace llk
//{
// int add(int x,int y);
// int sub(int x,int y);
//}
另外的test.cpp文件中包含着声明函数的实现
//namespace llk
//{
// int add(int x,int y)
// {
// return x+y;
// }
//
// int sub(int x,int y)
// {
// return x-y;
// }
//}
//然后test.cpp调用test.h头文件之后,就会合并成
//namespace llk
//{
// int add(int x,int y);
// int sub(int x,int y);
//
// int add(int x,int y)
// {
// return x+y;
// }
//
// int sub(int x,int y)
// {
// return x-y;
// }
//}
五、命名空间的三种使用方式
//1.使用域限定符::进行操作 -----也就是上面的那些使用的方式
//2.使用using将命名空间全部展开
//#include<stdlib.h>
//namespace llk
//{
// int rand=9;
// int a=1;
// int b=2;
//}
using namespace llk;//这就相当于将里面的变量放在全局域当中
//
//int main(void)
//{
// printf("%d",b);
//}
//3.展开常用的个别变量
//using llk::a;
//这样输出a的时候,就可以直接输出a了
二、常用的输入输出
一、c++常用的输出方法
//#include<iostream>
//1.c++的头文件<iostream>和c的<stdio.h>性质上是一样的,包含着一些输入输出函数 具体的输入输出函数
using namespace std;//看完1_的命名空间就知道这里是什么意思了 ----c++库的实现定义都封装在std这个命名空间内
//
//int main(void)
//{
// std::cout<<"hello world"<<std::endl;
cout<<"hello world"<<endl;//这样是将命名空间展开了之后才能这样使用
所以可将常用的std::out展开
//}
二、cout解释
//<< 官方给的名字叫流插入运算符
//1. i---in o---out stream流动,也就是流的意思
//using std::cout;
//using std::endl;
//int main(void)
//{
// cout<<"hello world";//<<在这里可以当做流向的符号,将后面的字符串流进cout 所以<<在这里也叫流插入运算符 cout就相当于控制台,流向控制台就是输出
// cout<<endl;//这个东西就像相当于换行符 '\n'
// printf("\n");//这样写和上面的endl效果是一样的
// cout<<'\n';
//}
//2.自动识别类型
//int main(void)
//{
// int a=3;
// double d=3.14;
// cout<<a<<"\n"<<d<<endl;//还能这样的连续使用,并且cout输出的时候并不用去指定格式 %d %lf....之类的
//}
三、cin解释
//>> 官方的名字叫做流提取运算符
//2.//using std::cin;
//int main(void)
//{
// //首先cin就相当于scanf从键盘上获取流
// int a;
// float b;
// cin>>a>>b;//这样就相当于scanf对a,b从键盘上赋值 看好<< >> 箭头指向的就是流入的方向
// cout<<a<<'\n'<<b<<endl;//但是指定输出小数点后的小数位的时候可以使用printf,cout输出比较麻烦
//}
四、输出输出缓冲区是和printf scanf一样的
//1.c语言的输入输出比c++的输入输出快,因为c++要兼容c语言
//2.因为io都是有缓冲区的,但是c的输入输出和c++的输入输出的缓冲区是各自独立的。c++的缓冲区进行输出的时候需要对c语言的缓冲区进行检查。
//C++输入输出的同步是指在程序中使用C语言风格的输入输出时,需要调用stdio.h头文件中的函数,这些函数会自动刷新缓冲区,以保证数据的及时输出。而在C++中,可以使用cin和cout进行输入输出,它们会自动刷新缓冲区,以保证数据的及时输出。
//补充:>> 流提取运算符 <<流插入运算符
三、缺省参数
一、缺省参数 (又叫默认参数) --字面意思
//using namespace std;
单个缺省参数
//void test(int a=5)//缺省参数就是函数在调用的时候可以不输入参数进行调用
//{
// cout<<a<<endl;
//}
//
全缺省
//void test1(int a=3,int b=2,int c=3)//这种也叫全缺省,也就是所有参数都给了缺省值
//{
// cout<<a<<endl;
// cout<<b<<endl;
// cout<<c<<endl;
//
//}
//
//
半缺省
//void test2(int a,int b=2,int c=3)//这样的半缺省参数必须是从a开始,并且是连续的才能缺省。也就是可以int a,int b,int c=2; 但是不能int a=1;int b,int c=2;
//
//{
// cout<<a<<endl;
// cout<<b<<endl;
// cout<<c<<endl;
//}
//
//
//int main(void)
//{
// test(10086);//在传实参的时候,诶调用函数会按照实参的值执行程序
// test();//如果没有传参,提前定义的5就会当做实参进行执行
//
// test1();//多个缺省值也是一样的
// test1(1,2);//多个缺省值传参的时候是从左往右传的 但是穿参的时候不能跳着传参,也就是不能指定传参
//
// test2(1);//a没有缺省参数所以最少要有一个参数
//}
二、缺省参数函数的定义和声明
//如果一个缺省参数函数在test.c中定义,如;
//int test(int a=1,int b=2)
//{
// return a+b;
//}
//那么函数的声明就不能在有参数缺省的情况 假设这个声明在test.h中
//int test(int a,int b);//声明的时候不能再进行缺省参数
//函数的声明和函数的定义在同一个文件中也是这样要求的 也就要么定义的时候缺省,要么声明的时候缺省
四、函数重载
//1.函数重载概念:是函数的一种特殊情况,c++允许在 同一作用域 中, 声明 几个功能类似的同名函数,这些同名函数的形参列表,(参数个数,或者参数类型,再或者参数顺序)不同
//常用来处理实现功能类似,但数据类型不同的问题 参数个数,参数类型,参数顺序有一个不算就算重载
//但是返回值不同,不构成重载
//参数个数不同
//int add(int a,int b,int c)
//{
// return a+b+c;
//}
//int add(int a,int b)
//{
// return a+b;
//}
//参数类型不同
//int add(int a,int b)
//{
// return a+b;
//}
//
//double add(double a,double b)
//{
// return a+b;
//}
//参数顺序不同
//int add(char a,int b)//并且注意,这个顺序不同前提是里面的形参是不同类型的。否则不能构成重载
//{
// return a+b;
//}
//
//int add(int b,char a)
//{
// return a+b;
//}
//补充:严格把握三个要求。参数个数、类型、顺序
//但是也要避免缺省参数带来的歧义
//int add()
//{
// return 3;
//}
//
//int add(int a=3)
//{
// return a;
//}
//上面的两个函数肯定是构成重载的,但是像这样的调用就会出现问题 add(); 这样就不知道编译器调用的add(),还是缺省参数add(int a=3);使用默认参数
//五、c++函数重载的原理(为什么c不支持,c++支持,c++支持重载的原理是什么)
//linux下gcc编译器是c的编译器 g++是c++的编译器,但是向下支持
//windows系统下面是根据文件的后缀来调用相应的编译器 .c调用的就是c编译器 .cpp调用的就是c++的编译器
//这个地方在学完linux时必须拐回来看一遍,还有函数栈帧的创建和销毁
//所有的自动类型识别都是函数重载
//1.这个涉及到 函数名修饰规则 编译链接过程
//2.编译链接规则
//(1)编译连接的过程是 预处理->编译->汇编->链接
//(2)如果有三个文件 add.c add.h test.c 预处理后add.h test.c形成一个.i文件 add.c add.h 会形成一个.i文件 。两两互不干扰形成 .s .o文件 。最后链接形成可执行程序
//(3)在test.c和add.h文件中形成的,并没有add里面函数的定义,只是有里面函数的声明。 就是对编译器的一个承诺
//(4)链接就是找到函数定义的过程。 找函数的定义也就是找到函数地址的过程。 因为.o文件中存在一个符号表,符号表中表明了函数以及函数对应的地址
//(5)链接错误其实就是没找到定义的函数地址什么的错误
//3.c语言不支持重载的原因
// (1)因为c语言的符号表中,汇编代码中,函数的名字就是自己定义的函数的名字,但是重载的函数的名字是一样的,在符号表中查找的时候就会出现错误。太直接了
// (2)也就是说,如果出现同名函数,则会在汇编阶段就出现错误
//4.c++支持的原因
// (1)在Linux中打开汇编文件,能看见两个同名的函数在汇编代码中显示的并不相同,会用参数来修饰函数
// (2)如果其中一个函数的参数是int,double 函数名就会被修饰成 addid 如果两个参数是int int 函数名就会被修饰成addii
// (3)返回值并没有进入函数名修饰规则 具体的修饰规则可以在网上搜索,上面说的就是简单的形容