C++入门知识

目录

C++命名空间

命名空间的介绍

域作用限定符

命名空间的使用

C++的输入以及输出

C++中的缺省参数

缺省参数的介绍

缺省参数的使用

缺省参数的分类

全缺省参数

半缺省参数


在C++中,有63个关键字,而C语言只有32个关键字

cpp 复制代码
asm do if return try continue auto double inline short typedef for
bool dynamic_cast int signed typeid public break else long sizeof typename    
throw case enum mutable static union wchar_t catch explicit namespace         
static_cast unsigned default char export new struct using friend 
class extern operator switch virtual register const false private 
template void true const_cast float protected this volatile while delete goto reinterpret_cast

📌

这些关键字不需要死记硬背

C++命名空间

命名空间的介绍

在C++中,变量、函数和类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。而使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的,而定义一个命名空间就相当于定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

例如,在C语言中,对于下面的程序

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

int rand = 10;

int main()
{
    printf("%d\n", rand);
    return 0;
}
报错内容:
"rand": 重定义;以前的定义是"函数"

因为在C语言中,存在一个名为rand()的函数,此时若将变量名定义为rand会与标准库中rand()函数名产生冲突,而C语言能解决这个问题方法只有更改变量名,否则没有其他办法

但是在C++中,可以使用命名空间解决这个问题

所谓命名空间指当前命名的变量所处的空间,在命名空间中,可以声明变量/类型/函数,例如

cpp 复制代码
//命名空间1
namespace test1
{
    //变量
    int i = 0;

    //类型
    struct Student
    {
        int age;
        char name[20];
    };

    //函数
    int add(int x, int y)
    {
        return x + y;
    }
}

在C++中,使用namespace关键字创建命名空间,语法如下:

cpp 复制代码
namespace 命名空间名
{
    //变量/函数/类型
}//注意最后一行不需要分号,不同于结构体

在C++中,命名空间可以嵌套定义,例如:

cpp 复制代码
//命名空间2
namespace test2
{
    int num = 0;
    //命名空间3
    namespace test3
    {
        int num = 0;
    }
}

对于上面的代码,在命名空间test2中嵌套定义了一个命名空间test3

有了命名空间,就可以解决上面C语言出现的问题,解决方法如下:

cpp 复制代码
//头文件NameSpace.h中的命名空间4
//将rand变量放入命名空间test4中
namespace test4
{
    int rand = 10;
}

//测试文件
//C++主函数
#include <iostream>
#include <stdlib.h>
#include "NameSpace.h"

int main()
{
    //调用命名空间4中的rand变量,而不是标准库中的rand()函数
    printf("%d\n", test4::rand);
    return 0;
}
输出结果:
10

域作用限定符

在C++中,::表示域作用限定符,使用方法如下:

cpp 复制代码
空间 :: 变量/类型/对象名

::左侧空间为空时,默认在全局中寻找::右侧的内容,例如:

cpp 复制代码
//NameSpace.h文件中的命名空间2与嵌套的命名空间3
//命名空间2
namespace test2
{
    int num = 20;
    //命名空间3
    namespace test3
    {
        int num = 30;
    }
}

//C++主函数
#include <iostream>
#include <stdlib.h>
#include "NameSpace.h"

//全局变量
int num = 10;

int main()
{
    //域作用限定符
    //局部变量
    int num = 0;
    printf("%d\n", num);
    //全局变量
    printf("%d\n", ::num);
    //指定命名空间的变量
    printf("%d\n", test2::num);
    //嵌套的命名空间的变量
    printf("%d\n", test2::test3::num);
    return 0;
}
输出结果:
0
10
20
30

命名空间的使用

在C++中,有三种使用命名空间的方法:

  1. 加命名空间名称及作用域限定符,例如N::a
  2. 使用using将命名空间中某个成员引入,也称部分展开,例如using N::a
  3. 使用using将命名空间整体引入,也称全局展开,例如using namespace N

测试实例:

cpp 复制代码
//NameSpace.h中的命名空间1
namespace test1
{
    //变量
    int i = 10;

    //类型
    struct Student
    {
        int age;
        char name[20];
    };

    //函数
    int add(int x, int y)
    {
        return x + y;
    }
}

//加命名空间名称及作用域限定符
#include <iostream>
#include "NameSpace.h"

int main()
{
    printf("%d", test1::i);

    return 0;
}
输出结果:
10

//部分展开
#include <iostream>
#include "NameSpace.h"
using test1::i;

int main()
{
    printf("%d", i);
    return 0;
}
输出结果:
10

//全局展开
#include <iostream>
#include "NameSpace.h"
using namespace test1;

int main()
{
    printf("%d\n", i);
    return 0;
}
输出结果:
10

💡

在实际使用过程中,更推荐指定以及部分展开,如果只是自己练习时,更推荐使用全局展开

注意,使用 using namespace N并不代表在函数中不可以指定,部分展开和全局展开都只是改变寻找方式,并不是使用了其中一种方式其他方式不可以再使用,只是大范围会包括小范围,而如果已经全局展开,那么再指定将直接去指定的命名空间找,而不是在全局展开的命名空间中找

当存在两个相同的命名空间时,会被合并成一个命名空间,而不是直接覆盖,例如

cpp 复制代码
//NameSpace.h中的两个重名的命名空间
//两个同名的命名空间
namespace test5
{
    int num1 = 10;
}

namespace test5
{
    int num2 = 20;
}

//测试文件
//同名命名空间合并
#include <iostream>
#include "NameSpace.h"
using namespace std;
using namespace test5;

int main()
{
    cout << test5::num1 << endl;
    cout << test5::num2 << endl;
    return 0;
}
输出结果:
10
20

C++的输入以及输出

在C++中,可以使用coutcin配合流插入运算符<<和流提取运算符>>使用,例如:

💡

使用coutcin时需要包含头文件iostream,注意C++的标准库头文件不包含不带有.h,并且需要引入命名空间std(C++中的标准命名空间)或者直接指定。因此推荐使用<iostream>+std的方式

cpp 复制代码
//C++的输入和输出
#include <iostream>
using namespace std;

int main()
{
    int num = 0;
    cout << "请输入数值:";
    cin >> num;
    cout << num << endl;

    return 0;
}
输入:
10
输出结果:
请输入数值:10
10

在上面的代码中,定义了一个num变量,通过标准输入对象cin和流提取运算符>>控制变量num的输入,不同于C语言,此处输入可以不需要取地址运算符&,对变量内容的输出使用标准输出对象cout和流插入运算符<<控制内容的输出,而endl表示换行符,作用效果类似'\n'

在C++中,输入和输出可以自动识别变量类型,故输出和输入不需要占位符

cpp 复制代码
#include <iostream>
using namespace std;

int main()
{
    //int num = 0;
    //cout << "请输入数值:";
    //cin >> num;
    //cout << num << endl;

    int num = 0;
    double num1 = 0;
    char c = 0;
    cin >> num >> num1 >> c;//多组内容的输入,相当于scanf("%d%lf%c", &num, &num1, &c);
    cout << num << ' ' << num1 << ' ' << c;//多组内容输出,相当于printf("%d %f %c", num, num1, c);

    return 0;
}
输入:
1 2.5 c
输出结果:
1 2.5 c

📌

scanf一样,cin会自动忽略空白字符

  • 也可以使用指定的方式使用coutcin
cpp 复制代码
//C++的输入和输出
#include <iostream>

int main()
{
    int num = 0;
    std::cin >> num;
    std::cout << num << std::endl;

    return 0;
}
输入:
10
输出:
10

C++中的缺省参数

缺省参数的介绍

在C++中,缺省参数是指在函数的定义以及声明中可以为形式参数赋值,例如

cpp 复制代码
int add(int x = 0, int y = 0)
{
    return (x + y);
}

在上面的代码中,变量x和变量y赋值为0,称xy为缺省参数,两个0为两个缺省参数的缺省值,缺省值必须是常量或者全局变量

如果调用add函数时不传入实际参数或者同类型数值时,则add函数直接使用缺省参数的数值进行计算,例如

cpp 复制代码
#include <iostream>
using namespace std;

int add(int x = 0, int y = 0)
{
    return (x + y);
}

int main()
{
    //调用add函数不传参数
    cout << add() << endl;
    //调用add函数传一个参数
    cout << add(1) << endl;
    //调用addd函数传两个参数
    cout << add(1, 2) << endl;

    return 0;
}
输出结果:
0
1
3

缺省参数的使用

在C++中,缺省参数有两种,第一种是全缺省参数,第二种是半缺省参数

在使用缺省参数时,必须遵循从右往左连续使用,不可以跳跃式使用,例如对于下面的函数:

cpp 复制代码
int add(int x = 0, int y = 0, int z = 0)
{
    return (x + y);
}

使用时满足从右往左使用

cpp 复制代码
//缺省参数
#include <iostream>
using namespace std;

int add1(int x = 0, int y = 0, int z = 0)
{
    return (x + y);
}

int main()
{
    //使用缺省参数时必须从右往左连续使用

    //正确使用方法
    add1(1, 2);//使用第三个缺省参数
    add1(1);//使用第二个和第三个缺省参数
    add1();//使用全部缺省参数
    add1(1, 2, 3);//不使用缺省参数

    //错误使用方法
    add1(1, , 2);//不可以直接使用第二个缺省参数
    add1(, 1, 2);//不可以直接使用第一个缺省参数
    add1(, , 1);//不可以直接使用第一个和第二个缺省参数
    add1(, 1, );//不可以直接使用第一个和第三个缺省参数

    return 0;
}

📌

"从右往左使用"意思是,当调用函数给函数传递实际参数时,第一个实参对应着第一个第一个形参,第二个实参对应着第二个形参,第三个实参对应着第三个形参,使用缺省参数时,当只传递一个实际参数时,该实际参数对应着第一个形参,此时使用第二个和第三个缺省参数,同理,当传递两个实际参数时,两个实际参数对应的前两个形参,使用第三个缺省参数,即总是满足最右边的缺省参数是第一个使用的

"连续使用"意思是,给函数传递实际参数到形参时,不能出现类似于第一个实际参数传给第一个形参,第二个实际参数不传内容,第三个实际参数传递给形参等间隔性的传递

缺省参数的分类

在C++中,缺省参数分为

  1. 全缺省参数
  2. 半缺省参数

全缺省参数

全缺省参数是指在函数声明或定义时,所有变量都是缺省参数,例如

cpp 复制代码
int add1(int x = 0, int y = 0, int z = 0)
{
    return (x + y);
}

半缺省参数

半缺省参数是指在函数声明或定义中,部分变量是缺省参数,例如

cpp 复制代码
int add1(int x, int y = 0, int z = 0)//只有y和z是缺省变量
{
    return (x + y);
}

半缺省参数中,必须满足从右往左依次连续给出,不可以跳跃式给缺省参数(由于从右往左使用的原则),不是缺省变量的需要在调用时传递实际参数,例如

cpp 复制代码
//半缺省参数
int add2(int x, int y = 0, int z = 0)
{
    return (x + y);
}

int add3(int x, int y, int z = 0)
{
    return (x + y);
}

//不可以跳跃式给缺省值
int add4(int x = 0, int y, int z)
{
    return (x + y);
}

int add5(int x, int y = 0, int z)
{
    return (x + y);
}

int main()
{
    add2(1);//只有一个不是缺省参数时,必须为该形参传递实参
    add3(1, 2);//有两个不是缺省参数时,必须为两个形参传递实参

    add4(, 2, 3);//不可以使用,需要满足从右往左使用缺省参数的原则
    add5(1, , 3);//不可以使用,需要满足从右往左使用缺省参数的原则
    return 0;
}

声明和定义函数缺省参数时一定要保证二者的缺省参数以及缺省值一致,否则编译器无法确定该使用哪个缺省值

cpp 复制代码
//NameSpace.h中的函数声明
int add6(int a = 20);

//测试文件
int add6(int a = 20)
{
    return a;
}

#include <iostream>
using namespace std;

int main()
{
    cout<<add6(2)<<' ';
    cout<<add6()<<'\n';
    return 0;
}
输出结果:
2 20

如果使用函数定义和声明不同的缺省参数,在VS中,若定义在使用之前,会默认使用函数定义(因为此时的定义也充当了声明)中的缺省值

cpp 复制代码
//NameSpace.h中的函数声明
int add7(int a = 10, int b = 20);
//测试文件
//缺省参数a的缺省值,声明和定义不同
int add7(int a = 0, int b = 20)
{
    return a + b;
}

#include <iostream>
#include "NameSpace.h"
using namespace std;

int main()
{
    cout << add7() << endl;
    return 0;
}
输出结果:
20

//但是下面的代码将会报错,因为编译器找不到函数定义
//NameSpace.h中的函数声明
int add7(int a = 10, int b = 20);
//测试文件

#include <iostream>
#include "NameSpace.h"
using namespace std;

int main()
{
    cout << add7() << endl;
    return 0;
}

//缺省参数a的缺省值,声明和定义不同
int add7(int a = 0, int b = 20)
{
    return a + b;
}
//编译器找不到add7的定义
相关推荐
蜀黍@猿19 分钟前
【C++ 基础】从C到C++有哪些变化
c++
Am心若依旧40920 分钟前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
zh路西法30 分钟前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(一):从电梯出发的状态模式State Pattern
c++·决策树·状态模式
轩辰~44 分钟前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
lxyzcm1 小时前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
蜀黍@猿1 小时前
C/C++基础错题归纳
c++
雨中rain2 小时前
Linux -- 从抢票逻辑理解线程互斥
linux·运维·c++
ALISHENGYA3 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(实战项目二)
数据结构·c++·算法
arong_xu3 小时前
现代C++锁介绍
c++·多线程·mutex
汤姆和杰瑞在瑞士吃糯米粑粑3 小时前
【C++学习篇】AVL树
开发语言·c++·学习