【C++入门(上)】—— 我与C++的不解之缘(一)

简介: 【C++入门(上)】—— 我与C++的不解之缘(一)

前言:

      学完C语言和初阶数据结构,感觉自己又行了?

接下来进入C++的学习,准备好接受头脑风暴吧。

一、第一个C++程序

       C++ 的第一个程序,梦回出学C语言,第一次使用C语言写代码;这里使用C++写第一个C++代码。

#include<stdio.h>
 
int main()
{
  printf("Hello,World ! ! !\n");
  return 0;
}

看到这里,很疑惑?不是第一个C++程序代码吗?怎么使用C语言来写呢?

       这里C++兼容C语⾔绝⼤多数的语法,所以C语⾔代码也可以运行,C++文件后缀为.cpp,vs编译器对后缀为 .cpp的文件就会调⽤C++编译器编译;linux下要⽤g++编译,不再是gcc。

当然呢,C++ 也有自己的输入输出,来看使用C++代码实现第一个C++程序:

#include<iostream>
 
int main()
{
  cout << "Hello World!!!" << endl;
  return 0;
}

在接下来的学习中,一一来学习C++这些知识。

二、命名空间

       2.1、命名空间的作用

       在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称都存在于全局作用域中,可能会导致很多冲突。

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

在C语言中,类似与下面程序这样的命名冲突,是一个普遍存在的问题,C++引入namespace就是为了更好的解决这样的问题。

#include<stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
  // 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”
  printf("%d\n", rand);
  return 0;
}

       2.2、namespace的定义

  1. 定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等等。
  2. namespace本质上是定义出一个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下面的rand就不存在冲突(可以解决如上图所示命名冲突问题)。
  3. C++ 中域有函数局部域、全局域、命名空间与和类域;域影响的编译时语法查找一个变量/函数/类型出处(声明和定义)的编辑,所以有了域的隔离,名字冲突问题就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的生命周期,命名空间域和类域不影响变量的生命周期。
  4. namespace只能定义在全局,当然,也可以嵌套定义。
  5. 项目工程中多文件中定义的同名namespace会认为是一个namespace,不会冲突。
  6. C++ 标准库都放在一个叫 std(standard)的命名空间里。

定义命名空间:

#include<stdlib.h>
 
namespace HL
{
  int rand = 0;
 
  int Add(int x, int y)
  {
    return x + y;
  }
}
 
 
int main()
{
  printf("%p\n", rand);
  printf("%d\n", HL::rand);
  printf("%d\n", HL::Add(1, 2));
  return 0;
}

嵌套定义:

namespace HL
{
  namespace H
  {
    int rand = 0;
 
    int Add(int x, int y)
    {
      return x + y;
    }
  };
  namespace L
  {
    int rand = 1;
    int Add(int x, int y)
    {
      return (x + y) * 10;
    }
  }
}
int main()
{
  printf("%d\n", HL::H::rand);
  printf("%d\n", HL::L::rand);
  printf("%d\n", HL::H::Add(1,2));
  printf("%d\n", HL::L::Add(1,2));
  return 0;
}

多文件定义命名空间:

      多个文件定义同名的namespace,它们会默认合并到一起,就像同一个namespace一样。

       2.3、命名空间的使用

       编译查找一个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找。所以下面程序会编译报错。我们要使用命名空间中定义的变量或者函数是,有以下三方式:

  • 指定命名空间访问,(在项目实践中推荐)。
  • using将命名空间中某个成员展开,(项目中经常访问的不存在冲突的成员推荐这种方式)。
  • 展开命名空间中的全部成员(项目实现中不推荐,冲突风险大)。

不会主动到命名空间去查找变量/函数

指定命名空间访问

namespace HL
{
  int a = 1;
  int b = 0;
}
 
int main()
{
  printf("%d\n", HL::a);
  printf("%d\n", HL::b);
  return 0;
}

展开某个成员

namespace HL
{
  int a = 1;
  int b = 0;
}
using HL::a;
int main()
{
  printf("%d\n", HL::a);
  //printf("%d\n", HL::b); 这里会提示未定义的标识符‘b’
  return 0;
}

展开全部成员

namespace HL
{
  int a = 1;
  int b = 0;
}
using namespace HL;
int main()
{
  printf("%d\n", HL::a);
  printf("%d\n", HL::b);
  return 0;
}

三、C++输入输出

  1. <iostream> 是Input Output Stream 的缩写,是标准的输入、输出流库,定义了标准的输入、输出对象。
  2. std::cin 是istream类的对象,它主要面向窄字符(narrow character(of type char))的标准输入流。
  3. std::cout 是ostream类的对象,它主要面向窄字符的标准输出流。
  4. std::endl 是一个函数,流插入输出时,相当于一个换行字符刷新缓冲区。
  5. << 是流插入运算符, >> 是流提取运算符。(C语言中为位运算左移和右移)
  6. 使用C++输入输出更方便,不需要像 printf和scanf那样手动指定格式,C++的输入输出可以自动识别变量类型(本质上是通过函数重载实现的),更重要的是C++的流能更好的支持自定义类型对象的输入输出。
  7. IO流涉及类和对象,运算符重载,继承等很多方面的知识,这些知识在接下来C++的学习中都会学到(这里简单了解一下)
  8. cout/cin/endl 等都属于C++标准库,C++标准库都放在一个叫std 的命名空间中,所以,我们需要通过命名空间的使用方式来使用它们。
  9. 这里没有包含<stdio.h>,也能够使用printf 和 scanf,在包含<iostream>间接包含了。使用VS编译器是这样的,其他的编译器可能会报错。
using namespace std;
int main()
{
  int a = 0;
  double d = 1.1;
 
  cout << a << endl;
  cout << d << endl;
 
  //输入
  cin >> a;
  cin >> d;
 
  cout << a << " " << d << endl;
 
 
  //C输入
  scanf("%d%lf", &a, &d);
  printf("%d %lf\n", a, d);
 
  return 0;
}

C++是兼容C语言的,也可以加上以下代码让C++不在兼容C语言,提高C++ IO效率

#include<iostream>
using namespace std;
int main()
{
  // 在io需求⽐较⾼的地⽅,如部分⼤量输⼊的竞赛题中,加上以下3⾏代码
  // 可以提⾼C++IO效率
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  return 0;
}

四、缺省参数

  1.        缺省参数是声明或定义函数时为函数的参数指定了一个缺省值。再调用该函数时,如果没有指定实参则采用该形参的缺省值,否则就使用指定的实参,缺省参数分为全缺省和半缺省参数(有些地方把缺省参数也叫做默认参数)。
  2.        全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。
  3.        带缺省参数的函数调用,C++规定必须从左到右依次给实参,不能跳跃给实参。
  4.        函数声明和定义分离时,缺省参数不能在函数声明和定义中重复出现,规定函数声明给缺省参数。

缺省参数:

using namespace std;
 
void test1(int a = 0)
{
  cout << a << endl;
}
 
int main()
{
  test1();
  test1(9);
  return 0;
}

全缺省参数:

//全省参数
void test2(int a = 0, int b = 1, int c = 2)
{
  cout << "a= " << a << endl;
  cout << "b= " << b << endl;
  cout << "c= " << c << endl;
  cout << endl;
 
}
 
int main()
{
  test2();
  test2(11);
  test2(11, 22);
  test2(11, 22, 33);
  return 0;
}

半缺省参数:

//半缺省参数
void test3(int a, int b = 1, int c = 2)
{
  cout << "a= " << a << endl;
  cout << "b= " << b << endl;
  cout << "c= " << c << endl;
  cout << endl;
}
 
int main()
{
  test3(11);
  test3(11, 22);
  test3(11, 22, 33);
  return 0;
}

五、函数重载

       C++支持在同一作用域中出现同名函数,但是要求这些函数的形参不同,可以是参数个数不同或者参数类型不同;这样C++函数调用就表现了多态行为,使用更加灵活。(C语言是不支持同一作用域中出现同名函数的)

函数参数类型不同:

//参数类型不同
int Add(int x, int y)
{
  cout << "Add(int x,int y)" << endl;
  return x + y;
}
double Add(double x, double y)
{
  cout << "Add(double x,double y)" << endl;
  return x + y;
}
 
int main()
{
  cout << Add(1, 2) << endl;
  cout << Add(1.1, 2.2) << endl;
  return 0;
}

函数参数个数不同:

void fun()
{
  cout << "If you never leave." << endl;
}
void fun(int a)
{
  cout << "I will live and die together." << endl;
}
int main()
{
  fun();
  fun(1);
  return 0;
}

       这里有一个需要注意的点,如果只有参数,而且给了缺省参数,(如果这是还有一个与其命名相同的函数(没有参数),调用时就会报错)

参数类型顺序不同:

//参数的类型顺序不同
void Test(int a, char c)
{
  cout << "If you never leave." << endl;
}
 
void Test(char c, int a)
{
  cout << "I will live and die together." << endl;
}
 
int main()
{
  Test('x', 1);
  Test(1, 'x');
  return 0;
}//参数的类型顺序不同
void Test(int a, char c)
{
  cout << "If you never leave." << endl;
}
 
void Test(char c, int a)
{
  cout << "I will live and die together." << endl;
}
 
int main()
{
  Test(1, 'x');
  Test('x', 1);
  return 0;
}


相关文章
|
2月前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
47 2
C++入门12——详解多态1
|
2月前
|
算法 安全 Linux
【C++STL简介】——我与C++的不解之缘(八)
【C++STL简介】——我与C++的不解之缘(八)
|
2月前
|
存储 C语言 C++
【C/C++内存管理】——我与C++的不解之缘(六)
【C/C++内存管理】——我与C++的不解之缘(六)
|
2月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
2月前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)
|
2月前
|
存储 编译器 C语言
【C++类和对象(上)】—— 我与C++的不解之缘(三)
【C++类和对象(上)】—— 我与C++的不解之缘(三)
|
2月前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
88 1
|
2月前
|
存储 安全 编译器
【C++打怪之路Lv1】-- 入门二级
【C++打怪之路Lv1】-- 入门二级
28 0
|
2月前
|
自然语言处理 编译器 C语言
【C++打怪之路Lv1】-- C++开篇(入门)
【C++打怪之路Lv1】-- C++开篇(入门)
38 0
|
2月前
|
存储 编译器 C++
【C++模版初阶】——我与C++的不解之缘(七)
【C++模版初阶】——我与C++的不解之缘(七)