C++基础篇之C++入门(1)

目录

命名空间

命名空间的定义

命名空间的使用

 C++输入&输出

 缺省参数

缺省参数的定义

缺省参数的分类

函数重载

函数重载的概念

函数重载的原理

扫描二维码关注公众号,回复: 13716384 查看本文章

命名空间

       C++存在大量的变量、函数和类的名称等标识符,可能会导致很多冲突,使用命名空间对标识符的名称进行本地化,防止命名冲突或名字污染。

例如我们有一下的使用场景:

int rand = 0;

此时单独定义rand变量时,不存在问题。但是在下面情况下便会出现命名冲突:

#include <stdlib.h>

int rand = 0;

        由于stdlib库中有rand函数,因此与全局作用域下的rand变量发生命名冲突!因此引入了命名空间的概况,便于我们对变量等标识符更好的处理。

命名空间的定义

        定义命名空间,需要使用namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中为命名空间的成员。例如:

namespace name
{
    //命名空间成员变量
}

命名空间的使用情况:

1.普通的命名空间

namespace N1
{
    int a;
    int Add(int x, int y)
    {
        return x + y;
    }
}

2.命名空间的嵌套

namespace N2
{
	int a;
    int Add(int x, int y)
    {
        return x + y;
    }
	namespace N3
	{
		int a;
        int Sub(int x, int y)
        {
            return x - y;
        }
	}
}

3.同一个工程中允许存在多个相同的命名空间,编译器最后会合成在同一个命名空间中

namespace N1
{
    int b;      //ok
    int c = 10; //ok
    //c = 20;   //error
}

注意:(1)一个命名空间定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

           (2)命名空间中只允许声明和初始化,不对赋值(如上图所示)

命名空间的使用

命名空间我们该如何使用呢?

通常我们使用作用域限定符::来取某个命名空间中的成员

namespace N
{
    int a = 10;
    int b = 20;
    int Add(int x, int y)
    {
        return x + y;
    }
}

命名空间的使用有三种方式:

  • 加命名空间名称及作用域限定符(指定作用域,可以最好的隔离,但使用麻烦)
int main()
{
    printf("%d
",N::a);
    return 0;
}
  •  使用using将命名空间中的成员引入(展开常用的)
using N::d;
int main()
{
    printf("%d
",N::a);
    printf("%d
",b);
    return 0;
}
  • 使用using namespace命名空间名称引入(全部展开,隔离失效)
using namespace N;
int main()
{
    printf("%d
",a);
    printf("%d
",b);
    Add(10, 20);
    return 0;
}

 C++输入&输出

#include<iostream>
using namespace std;

int main()
{
	cout<<"hello world!"<<endl;
	return 0;
}

以上程序是利用C++的输出函数cout打印hello world。

C++的特有输入输出:cin & cout

  • cin >>:>>为流提取运算符,将键盘输入的变量从缓冲区提取到cin中
  • cout <<:<<为流插入运算符,将所有你需要输出的变量或者字符串流入到cout中,让cout负责输出
  • cin和cout与scanf和printf不同的是,可以自动识别变量的类型,不用再指定变量类型(%d、%c、%f等)

缺省参数

缺省参数的定义

缺省参数表示在声明或定义函数时,为函数的参数指定一个默认值

int Function(int a = 10)//这里为a指定了一个默认值10
{
	return a + 1;
}

如果在调用时没有指定实参,则采用默认值;如果在调用时有传入实参,则使用指定实参。

// 没有传参,使用参数的默认值
Function();
// 传参时,使用实参
Function(20);

缺省参数的分类

  • 全缺省参数
void TestFunc(int a = 10, int b = 20, int c = 30) 
{
     cout << "a = " << a << endl;
     cout << "b = " << b << endl;
     cout << "c = " << c << endl; 
}

 以下的调用都是有意义的:

TestFunc();
TestFunc(3);
TestFunc(2, 3);
TestFunc(1, 2, 3);

但是不能用以下方法调用:

TestFunc(, 2, );

 注意:传进去的实参是从右往左依次传入,必须连续

  • 半缺省参数
void TestFunc(int a, int b = 20, int c = 30) 
{
     cout << "a = " << a << endl;
     cout << "b = " << b << endl;
     cout << "c = " << c << endl; 
}

注意:(1)半缺省参数必须从右往左来给出,不能间隔给出

           (2)缺省参数不能在函数声明和定义中同时出现

           (3)缺省值必须是常量或者全局变量

           (4)C语言不支持缺省参数

函数重载

函数重载的概念

函数重载 是函数的一种特殊情况,C++允许在 同一作用域中声明几个功能类似 的同名函数,这些同名函数的 形参列表 ( 参数个数 或 类型 或 顺序 ) 必须不同,常用来处理实现功能类似数据类型不同的问题。
举例说明:
int Add(int left, int right) 
{
     return left+right; 
}
double Add(double left, double right) 
{
     return left+right; 
}
long Add(long left, long right) 
{
     return left+right; 
}
int main()
{
     Add(10, 20);
     Add(10.0, 20.0);
     Add(10, 20);
 
     return 0; 
}

但下面两个函数不属于函数重载:

short Add(short left, short right) 
{
     return left+right; 
}
int Add(short left, short right) 
{
     return left+right; 
}

因为他们参数个数、类型、顺序相同,函数的返回类型不同,不能说明函数重载!!!

函数重载的原理

为什么c++支持函数重载而c语言却不支持呢?

我们知道,c++程序运行,需要经过以下几个阶段:预处理,编译,汇编,链接

阶段 工作内容 生产的文件类型
预处理 头文件展开、宏替换、条件编译、去掉注释 *.i

编译

检查语法、生产汇编代码 *.s
汇编 汇编代码转换成二进制的机器码 *.o
链接 合并段表、符号表的合并和重定位 *.out

而这里的重点在链接阶段,

通过我们C语言阶段学习的编译链接,我们可以知道,如果我们在a.cpp中调用了某个函数(Add函数),但是函数(Add函数)是在b.cpp中定义的,所以函数(Add函数)的地址就会在b.obj中。在a中就无法找到,那么怎么办呢?

链接阶段就是专门处理这种问题,链接器看到a.o调用函数,但是没有Add的地址,就会到b.o的符号表中找函数的地址,然后链接到一起。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGVpLi4=,size_20,color_FFFFFF,t_70,g_se,x_16

那么在链接的时候,面对Add函数,链接器该使用什么名字取找呢?

此时由于windows下的visual stdio编译器下的命名规则特别复杂且繁琐,我们在linux环境下进行验证。

(1)验证C语言是否支持重载

首先在Linux环境下创建test.c、func.c、func.h三个文件

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGVpLi4=,size_20,color_FFFFFF,t_70,g_se,x_16

使用C语言编译器gcc运行test.c和func.c会出现错误:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGVpLi4=,size_20,color_FFFFFF,t_70,g_se,x_16

  • 因为C语言在编译的时候,两个重载函数的函数名相同,在func.o的符号表中存在歧义和冲突。
  • 其次在链接的时候也存在歧义和冲突,因为他们是直接使用函数名在标识和查找,而重载函数的函数名相同。

因此C语言不支持重载函数!!!

(2)验证C++是否支持重载

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGVpLi4=,size_20,color_FFFFFF,t_70,g_se,x_16

 使用C++编译器g++运行test.c和func.c

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGVpLi4=,size_18,color_FFFFFF,t_70,g_se,x_16

 因此C++支持重载函数!!!

那么思考缺省参数是否为重载函数?

int F(int a);
int F(int a = 10);

当然不构成,因为他们的参数类型一致!

猜你喜欢

转载自blog.csdn.net/weixin_42301369/article/details/122983979