【C++】命名空间&缺省参数&函数重载&引用&内联函数(一)

简介: 【C++】命名空间&缺省参数&函数重载&引用&内联函数

1.C++兼容C的语法

//C++兼容C的语法
//C语言版本hello world
#include<stdio.h>
int main()
{
  printf("hello world\n");
  return 0;
}
//C++版本hello world
#include<iostream>
using namespace std;
int main()
{
  cout << "hello world" << endl;
  return 0;
}

2.using namespace std的作用:解决C语言中变量命名冲突的问题

2-1namespace的由来

#include<stdio.h>
int main()
{
  int scanf = 10;//对
  int strlen = 20;//对
  //C语言中标识符命名的两个点:1.不能以数字,下划线开头 2.不能和关键字名字一样(但可以是函数名)
  printf("%d", scanf);//对
  printf("%d\n", strlen);//对
  scanf("%d", &scanf);//错
  //本意是第一个scanf用stdio.h里的库函数,第二个scanf用int类型的变量
  //但是C语言的局部优先原则,这里的两个scanf都是int类型的变量,所以出错
  //小结:如果我就是想要达成我的本意的这个目的,C语言明显做不到(有命名冲突的问题),所以C++就使用namespace命名空间域来完善C
}

这是将int scanf=10;放在了局部,定义int scanf的时候还是可以的,但是在使用scanf("%d",&scanf);时出现错误;

但是如果将scanf放在全局,连定义 都不被允许。namespace的使用:

2-2namespace的使用:

#include<iostream>
//定义的是一个命名空间域:(变量和函数构成)
namespace song
{
  //变量
  int scanf = 1;
  int strlen = 2;
  //函数
  int add(int a, int b)
  {
    return a + b;
  }
}
int main()
{
  //默认访问的是先局部后全局(局部没有则采用局部的)
  printf("%x\n", scanf);
  printf("%x\n", strlen);
  //指定访问song命名空间域
  printf("%x\n", song::scanf);
  printf("%x\n", song::strlen);
  printf("%d\n", song::add(10,20));
}

874500c95e674a7f9f29e2b369448553.png

::是域作用限定符,限定是属于哪一个域的变量或者函数

常见的域有:局部域,全局域,命名空间域,类域

#include<iostream>
//全局域
int a = 10;
//命名空间域可以嵌套
namespace song
{
  int a = 20;
  namespace huang
  {
    int a = 30;
  }
  namespace chen
  {
    int a = 40;
  }
}
//类域
class stu
{
public:
  int a = 50;
};
int main()
{
  printf("默认先局部后全局(局部没有,全局有):a=%d\n", a);
  printf("指定song命名空间域:a=%d\n", song::a);
  printf("指定song命名空间域里的haung命名空间域:%d\n", song::huang::a);
  printf("指定song命名空间域里的chen命名空间域:%d\n", song::chen::a);
  stu s;
  printf("类域:%d\n", s.a);
  return 0;
}

b6c130d093a6481cb03fa854fce43585.png

备注:

  • 同一个项目的不同文件里 可以使用相同名称的命名空间域,编译链接时会自动合并

89a9538fc1e34579bce4e161835cebb7.png

  • 但是在同一个域中不能定义相同的标识符

3.使用标准库或自己定义的命名空间里的东西的三种方式:

#include<iostream>
int main()
{
  //要使用标准库里的东西,有三种方式:
  //方式1:每一个都指定命名空间
  //麻烦但是最标准
  std::cout << "hello world1" << std::endl;
  //方式2:整个东西都在全局展开,一夜回到解放前
  //方便,但是当我们自己定义的和标准库里的东西名字相同,发生命名冲突的时候就没办法解决了
  using namespace std;
  cout << "hello world2" << endl;
  //方式3:折中办法,对于标准库中的部分常用进行展开
  using std::cout;
  using std::endl;
  cout << "hello world3" << endl;
  return 0;
}

给大家看看使用自己定义的东西也是有三种方式 :


443810c99d0c4d0a90f27971ae6b40f9.png

4.C++中的输入和输出

cout现在讲不清楚,我们的储备知识还不够,先记住使用即可


//ostream 类型全局对象 cout
//istream 类型全局变量 cin
//endl 全局的换行符号
#include<iostream>
using namespace std;
int main()
{
  int a = 0;
  cin >> a;
  //自动识别类型:原理就是函数重载和运算符重载
  cout << a<< endl<< &a << endl;
  return 0;
}

5.缺省参数(缺省==不省==写上==默认)

缺省参数是指在声明和定义函数的时候为函数的参数设定一个默认值,在函数调用的时候,如果没有指定实参则采用该默认值.(备胎)


bb77cd5d4a5d40e8877dac1ab6e261ad.png

5-1缺省参数的分类

#include<iostream>
using namespace std;
//缺省参数的分类
//1:全缺省
void test1(int a=10, int b=20, int c=30)
{
  cout << a << endl;
  cout << b << endl;
  cout << c << endl << endl;
}
//2:半缺省
//部分缺省-必须从右往左连续缺省
void test2(int a , int b , int c =10)
{
  cout << a << endl;
  cout << b << endl;
  cout << c << endl;
}
int main()
{
  test1(1, 2, 3);
  test2(1, 2);//实参个数>=没缺省的参数个数
  return 0;
}

aa86305b1f94489798a05fd3cfe4e2d9.png

#include<iostream>
typedef struct Stack
{
  int* a;
  int size;
  int capacity;
}Stack;
//老版本:
//void InitStack(Stack* ps)
//{
//  ps->a = (int*)malloc(sizeof(int) * 4);
//  ps->size = 0;
//  ps->capacity = 4;
//}
//新版本:
void InitStack(Stack* ps, int capacity=4)
{
  ps->a = (int*)malloc(sizeof(int) * capacity);
  ps->size = 0;
  ps->capacity = capacity;
}
int main()
 {
  //假设我知道栈内至少需要存100个数据
  //如果现在将上面的capacity写成100,下面我ST2就没办法使用了
  //如果现在将上面的capacity写成10,在这里就要扩容,扩容是有时间成本的
  Stack ST1;
  //老版本:InitStack(&ST1);
  //新版本:
  InitStack(&ST1, 100);//传了,使用传的100
  //假设我知道栈内至少需要存10个数据
  Stack ST2;
  //老版本:InitStack(&ST2);
  InitStack(&ST2, 10);//传了,使用传的10
  //假设我不知道栈内至少需要存多少个数据
  Stack ST3;
  InitStack(&ST3);//不传,使用备用的4
  return 0;
}

备注: 缺省参数不能在函数声明和定义中同时出现,否则就会报错

最好是在声明时写缺省,也就是下面这样

void InitStack(Stack* ps, int capacity = 4);//声明缺省
int main()
 {
    //业务需求;
  return 0;
}
//新版本:
void InitStack(Stack* ps, int capacity)//定义不缺省
{
  ps->a = (int*)malloc(sizeof(int) * capacity);
  ps->size = 0;
  ps->capacity = capacity;
}

6. 函数重载

函数重载的定义:C++中支持两个函数名相同,但是函数的参数(参数的个数或者类型)要不同

  1. C语言中一个项目中不允许出现同名函数
  2. C++中的函数重载允许一个项目中出现同名函数
#include<iostream>
using namespace std;
int Add(int a, int b)
{
  return a + b;
}
char Add(char a, char b)
{
  return a + b;
}
double Add(double a, double b)
{
  return a + b;
}
float Add(float a, float b)
{
  return a + b;
}
int Add(int a, int b, int c)
{
  return a + b + c;
}
int main()
{
  cout << Add(1, 1) << endl;
  cout << Add('1', '1') << endl;//函数参数的类型构成重载
  cout << Add(1.1, 1.1)<< endl;//函数参数的类型构成重载//!!!备注:如果没强转或者备注,1.1默认就是double类型
  cout << Add((float)1.1, (float)1.1)<< endl;//函数参数的类型构成重载//强转
  //cout << Add(1.1f, 1.1f)<< endl;//函数参数的类型构成重载//备注
  cout << Add(1, 1, 1) << endl;//函数参数的个数构成重载
  return 0;
}

9bb94150f3b74b3c819cf44630204809.png

这样写简直是为难编译器了!!哈哈🐼

459a2d59ac3542efab95c71dbb3e9829.png


思考:难怪C语言为什么不写交换函数和排序函数的库函数,那是因为C语言不支持函数重载,要还得像qsort一样,一个一个字节地交换,但是这样很不方便。


目录
相关文章
|
1月前
|
编译器 程序员 C语言
C++函数重载
在实际开发中,有时候我们需要实现几个功能类似的函数,只是有些细节不同。例如希望交换两个变量的值,这两个变量有多种类型,可以是 int、float、char、bool 等,我们需要通过参数把变量的地址传入函数内部。在C语言中,程序员往往需要分别设计出三个不同名的函数,其函数原型与下面类似: void swap1(int *a, int *b); //交换 int 变量的值 void swap2(float *a, float *b); //交换 float 变量的值 void swap3(char *a, char *b); //交换 char 变量的
17 4
C++函数重载
|
14天前
|
程序员 C++ 容器
C++编程基础:命名空间、输入输出与默认参数
命名空间、输入输出和函数默认参数是C++编程中的基础概念。合理地使用这些特性能够使代码更加清晰、模块化和易于管理。理解并掌握这些基础知识,对于每一个C++程序员来说都是非常重要的。通过上述介绍和示例,希望能够帮助你更好地理解和运用这些C++的基础特性。
31 0
|
1月前
|
程序员 C++ 开发者
C++命名空间揭秘:一招解决全局冲突,让你的代码模块化战斗值飙升!
【8月更文挑战第22天】在C++中,命名空间是解决命名冲突的关键机制,它帮助开发者组织代码并提升可维护性。本文通过一个图形库开发案例,展示了如何利用命名空间避免圆形和矩形类间的命名冲突。通过定义和实现这些类,并在主函数中使用命名空间创建对象及调用方法,我们不仅解决了冲突问题,还提高了代码的模块化程度和组织结构。这为实际项目开发提供了宝贵的参考经验。
47 2
|
1月前
|
编译器 Linux C语言
【C++小知识】为什么C语言不支持函数重载,而C++支持
【C++小知识】为什么C语言不支持函数重载,而C++支持
|
24天前
|
C语言 C++
C++(六)Namespace 命名空间
命名空间(Namespace)是为了解决大型项目中命名冲突而引入的机制。在多库集成时,不同类库可能包含同名函数或变量,导致冲突。C++通过语法形式定义了全局无名命名空间,并允许对全局函数和变量进行作用域划分。命名空间支持嵌套与合并,便于协同开发。其使用需谨慎处理同名冲突。
|
24天前
|
C语言 C++
C++(三)内联函数
本文介绍了C++中的内联函数概念及其与宏函数的区别。通过对比宏函数和普通函数,展示了内联函数在提高程序执行效率方面的优势。同时,详细解释了如何在C++中声明内联函数以及其适用场景,并给出了示例代码。内联函数能够减少函数调用开销,但在使用时需谨慎评估其对代码体积的影响。
|
10天前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
56 30
|
24天前
|
存储 编译器 C++
C ++初阶:类和对象(中)
C ++初阶:类和对象(中)
|
1月前
|
存储 安全 编译器
【C++】类和对象(下)
【C++】类和对象(下)
【C++】类和对象(下)
|
24天前
|
C++
C++(十六)类之间转化
在C++中,类之间的转换可以通过转换构造函数和操作符函数实现。转换构造函数是一种单参数构造函数,用于将其他类型转换为本类类型。为了防止不必要的隐式转换,可以使用`explicit`关键字来禁止这种自动转换。此外,还可以通过定义`operator`函数来进行类型转换,该函数无参数且无返回值。下面展示了如何使用这两种方式实现自定义类型的相互转换,并通过示例代码说明了`explicit`关键字的作用。