1.命名空间+输入输出+缺省参数+函数重载

一、命名空间
二、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)返回值并没有进入函数名修饰规则          具体的修饰规则可以在网上搜索,上面说的就是简单的形容




 


 

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值