【C++】C++ 入门 — 命名空间,输入输出,函数新特性

简介: 本文章是我对C++学习的开始,很荣幸与大家一同进步。首先我先介绍一下C++,C++是上个世纪为了解决软件危机所创立 的一项面向对象的编程语言(OOP思想)。

1 前言

本文章是我对C++学习的开始,很荣幸与大家一同进步。

首先我先介绍一下C++,C++是上个世纪为了解决软件危机所创立 的一项面向对象的编程语言(OOP思想)。

1982年,Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了一种新的程序语言。为了表达该语言与C语言的渊源关系,命名为C++。因此:C++是基于C语言而产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计

根据今年一月TIOBE公布的排行榜,C++依然稳居前三,可见这是一款非常优秀的编程语言

2 命名空间

2.1 概念引入

在C语言中我们时常遇见这样的冲突:

重定义!!!总是不小心定义相同变量,多人操作的时候很难避免这个问题。

于是C++为了避免这类问题,引入了“命名空间”的概念;

使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的

2.2 开始使用

如活动定义一个命名空间呢?这里需要使用namespace关键字

namespace name
{
    // 命名空间中可以定义变量/函数/类型
  int a = 0;
  
  double add(double a,double b){
    return a + b;
  }

  struct node{
    int val ;
    int size;
  }
  
}

并且可以做到嵌套定义:

namespace name1{
  namespace name2{
    //...
  }
}

注意:

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

2.3 投入应用

使用命名空间主要有三种使用方法:

1 加命名空间名称及作用域限定符;

2 使用using将命名空间中某个成员引入;

3 使用using namespace 命名空间名称 引入.

来看第一种:

命名空间名称及作用域限定符

#include<iostream>
//定义两个命名空间
namespace name1 {
  int a = 0;
}
namespace name2 {
  int a = 0;
}

int main() {
//使用 作用域限定符 ::
  name1::a = 1;
  name2::a = 1;

  return 0;
}

使用using将命名空间中某个成员引入

#include<iostream>
//定义两个命名空间
namespace name1 {
  int a = 0;
  int b = 0;
}
//只有引入的变量才可以省略 命名空间和 作用域符号;
using namespace name1::a;

int main() {
//使用 作用域限定符 ::
  a = 1;
  name :: b = 2;

  return 0;
}

使用using namespace 命名空间名称 引入

#include<iostream>
//定义两个命名空间
namespace name1 {
  int a = 0;
  int b = 0;
}
//引入命名空间后,其中的变量/函数/结构体 
//可以直接使用
using namespace name1;

int main() {

  a = 1;
  b = 2;
  return 0;
}

3 输入与输出

c++中的输入输出与C语言略有不同。来看样例

#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
  cout<<"Hello world!!!"<<endl;
  return 0;
}

运行效果

3.1 基础知识

  1. 使用cout标准输出对象(控制台)和cin 标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含头文件中。
  3. <<是流插入运算符,>>是流提取运算符。
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型
  5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这些知识后续才会学习,所以这里只是简单学习如何使用。后面我们更深入的学习IO流用法及原理。

3.2 开始使用

我们来看样例:

#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
  char a = 0;
  int b;
  float c = 0;
  cin >> a;
  //支持连续输入,并自动识别类型。
  cin >> b >> c;
  cout << "输出\n" << a << '\n' << b << '\n' << c << '\n' << endl;
  return 0;
}

运行效果:

这方面就比C语言的printf scanf等函数方便许多。

3.3 注意局限

大家也一定注意到了一点,c++中既然直接使用了变量名输出,那如何控制输出格式呢?答案是有办法实现的,就是比较复杂。所以我们直接使用C语言中的printf函数即可,毕竟c++兼容绝大部分的C语言。

4 函数新特性

4.1 缺省参数

4.1.1 开始使用

缺省参数的概念十分好理解,就是在函数定义中加入参数的默认值,并且在没有传入对应参数时,使用默认值。

来看样例:

// 全缺省
using namespace std;

void Func(int a = 10, int b = 20, int c = 30)
{
  cout << "a = " << a << endl;
  cout << "b = " << b << endl;
  cout << "c = " << c << endl << endl;
}

int main()
{
  //半缺省 
  Func(1, 2, 3) ;
  Func(1, 2);
  Func(1);
  //全缺省
  Func();

  return 0;
}

来看运行效果:

4.1.2 注意事项

  1. 一定注意缺省参数是从左向右传入参数,无法做到传入指定参数。
  2. 缺省参数不能在函数声明和定义中同时出现(如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。所以我们一般在声明中给入默认值,这样方便使用、检查错误等操作)
  3. 缺省值必须是常量或者全局变量
  1. C语言不支持(编译器不支持)

4.2 函数重载

4.2.1 开始使用

在C语言中我们无法实现同一个函数名返回不同类型值或者使用不同类型参数。

所以就导致简单的加和函数Add 如果要实现不同类型的加和不免会出现:

AddInt

AddFloat

AddChar

···

不仅繁琐,而且调用的时候也不方便。


在自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了

c++ 于是就引入了函数重载的概念。

来看样例:

#include<iostream>

using namespace std;
int Add(int a = 0, int b = 0) {
   return a + b;
}
double Add(double a = 0.0, int b = 0) {
   return a + b;
}
int main() 
{
   cout << Add(1, 2) << endl;
   cout << Add(3.14, 2) << endl;

   return 0;
}

来看运行效果:

4.2.2 如何实现

那么这么强大的函数重载是如何实现的呢???

答案就在汇编代码中

在c++中,对于一个函数的储存与C语言不同,C++使用了更加具体命名方式(具体要看编译器);我个人非常喜欢g++的形式。上面两个函数分别为:

_Z3Addii

_Z3Adddi

目前我还没有能力深入讲解其中的道理。

Thanks♪(・ω・)ノ谢谢阅读

下一篇文章见!!!

相关文章
|
2月前
|
编译器 程序员 定位技术
C++ 20新特性之Concepts
在C++ 20之前,我们在编写泛型代码时,模板参数的约束往往通过复杂的SFINAE(Substitution Failure Is Not An Error)策略或繁琐的Traits类来实现。这不仅难以阅读,也非常容易出错,导致很多程序员在提及泛型编程时,总是心有余悸、脊背发凉。 在没有引入Concepts之前,我们只能依靠经验和技巧来解读编译器给出的错误信息,很容易陷入“类型迷路”。这就好比在没有GPS导航的年代,我们依靠复杂的地图和模糊的方向指示去一个陌生的地点,很容易迷路。而Concepts的引入,就像是给C++的模板系统安装了一个GPS导航仪
111 59
|
2月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
2月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
52 6
|
2月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
25 0
C++ 多线程之线程管理函数
|
2月前
|
C++
C++ 20新特性之结构化绑定
在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。
37 0
|
2月前
|
存储 安全 编译器
【C++打怪之路Lv1】-- 入门二级
【C++打怪之路Lv1】-- 入门二级
23 0
|
2月前
|
自然语言处理 编译器 C语言
【C++打怪之路Lv1】-- C++开篇(入门)
【C++打怪之路Lv1】-- C++开篇(入门)
28 0
|
2月前
|
分布式计算 Java 编译器
【C++入门(下)】—— 我与C++的不解之缘(二)
【C++入门(下)】—— 我与C++的不解之缘(二)
|
6天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
21 2
|
12天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
40 5