【c++篇】:初始c++--编程新手的快速入门之道(一)

文章目录

前言

在之前的文章中,我们学完了初阶数据结构的线性表,栈和队列,堆,二叉树以及排序(详细可以看我之前的几篇文章),在接下来的一段时间内将重点学习c++,c++是在c的基础上,容纳进去了面向对象编程的思想,并且增加了许多有用的库,以及编程范式等。学习c++之前要有一定的C语言基础。本篇文章将讲解c++入门知识,也是对C语言不足的补充,为后序类和对象的学习打好基础。

一.c++关键字

在学习C语言中我们知道关键字之一概念,而在c++中同样也有关键字,甚至数量要比C语言的多,因为c++兼容C语言,所以C语言有的关键字,c++也有。

C语言共有32个关键字,而c++共有64个关键字。如图所示

二.命名空间

在之前c语言中,我们一定遇到过以下这种情况

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

int rand = 10;
int main() {
	printf("%d", rand);
	return 0;
}

上面这种情况就是rand重定义,rand在库函数中是一个函数名,但是在这里我们将它定义为一个变量名,所以产生错误也就是命名冲突 ,而c++为了解决这一问题,引入了命名空间(namespace)这一概念,而命名空间所在的区域又叫命名空间域

1.命名空间的定义

定义命名空间,需要使用到namespace关键字,后面加命名空间的名字,然后接一对{ },{ }中就是命名空间的成员。

命名空间的成员可以是变量,函数或结构体。

cpp 复制代码
namespace N{
    //变量
    int rand;
    //函数
    int Add(int a,int b){
        return a+b;
    }
    //结构体
    struct ListNode{
        int data;
        struct ListNode*next;
    };
}

命名空间也可以嵌套使用

cpp 复制代码
namespace A1{
    int a;
    int b;
    int Add(int left,int right){
        return left+right;
    }
    //命名空间A1嵌套命名空间A2
    namespace A2{
        int c;
        int d;
        int Sub(int left,int right){
            return left-right;
        }
    }
}

在同一个工程中允许存在多个同名的命名空间(成员不同),编译器最后都会合成到同一个命名空间中。

比如下面的test.h文件中的命名空间A1和test.cpp文件中的命名空间A1最后会合并成一个。

cpp 复制代码
//test.h文件中有namespace A1
namespace A1{
    int a;
    int b;
    int Add(int left,int right){
        return left+right;
    }
}
//test.cpp文件中也有namespace A1
namespace A1{
    int c;
        int d;
        int Sub(int left,int right){
            return left-right;
        }
}

2.命名空间的使用

在c语言中如果我们直接定义一个变量并初始化,当我们想要打印这个变量的值时,我们可以直接访问

cpp 复制代码
int main(){
    int a=10;
    printf("a=%d\n",a);
    return 0;
}
//输出结果a=10

而在c++中,当我们将变量定义到命名空间中,再像C语言一样直接访问就会报错

cpp 复制代码
namespace A{
    int a=10;
    int b=0;
}
int main(){
    printf("a=%d\n",a);
    return 0;
}

这时候我们就要使用::域作用限定符

在C语言中我们知道局部变量所在的为局部域 ,全局变量所在的叫全局域 ,在c++中还有命名空间域类域;域影响的是编译时语法查找一个变量或函数或类型出处的逻辑,有了域隔离,就能解决命名冲突。

访问顺序:局部域>全局域>展开命名空间域or指定访问命名空间域

命名空间域展开会暴漏在全局域中,所以不能和全局域同时访问。因此命名空间只能定义在全局中。

当我们要展开命名空间域or指定访问命名空间域时就要用到::

命名空间的使用方法有三种

  • 指定访问某个成员

    cpp 复制代码
    int main(){
        //指定访问命名空间A的变量a成员
        printf("a=%d\n",A::a);
        return 0;
    }
  • 使用using全部展开命名空间

    cpp 复制代码
    using namespace A;
    int main(){
        printf("a=%d\n",a);
        printf("b=%d\n",b);
        return 0;
    }
  • 使用using部分展开

    cpp 复制代码
    //注意:这里部分展开不带namespace
    using A::b;
    int main(){
        printf("a=%d\n",A::a);
        printf("b=%d\n",b);
        return 0;
    }

三.c++输入&输出

在C语言中我们学过输入和输出函数scanf,printf,在c++中,同样也有输入输出。在这之前我们先来了解一下什么是std

前面我们学过c++为了解决命名冲突而引入了命名空间,std就是c++标准库命名空间,c++将标准库的定义实现都放在了这个命名空间中,所以在使用c++标准库函数时,我们要展开命名空间或者指定访问。

cpp 复制代码
//和C语言不同的是,c++的头文件不需要加.h
include<iostream>
using namespace std;
int main(){
    //打印输出hello world
    cout<<"hello world"<<endl;
    //输入x,d的值
    cin>>x>>d;
    //输出x,d的值
    cout<<x<<" "<<d<<endl;
    return 0;
}
  • cout标准输出对象(控制台,可以理解为vs中的黑框),cin标准输入对象(键盘),使用时,必须包含头文件,并且正确使用命名空间std
  • <<流插入运算符,<<流提取运算符。
  • coutcin是全局流对象,endl是特殊的c++符号,相当于C语言中的'\n'换行符号。
  • 相比于C语言中的scanfprintf需要手动控制变量类型,c++的输入输出可以自动识别变量类型,更加方便。

std命名空间的使用惯例:

std是c++标准库的命名空间,如何展开std使用更合理:

  • 日常练习中,直接展开using namespace std即可。
  • using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对 象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模 大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 + using std::cout展开常用的库对象/类型等方式。

四.缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在函数调用时,如果没有指定实参则采用形参的缺省值,否则使用指定实参。

cpp 复制代码
void Fun(int a=0){
    cout<<a<<endl;
}
int main(){
    //没有传参数时,使用参数默认值0
    Fun();
    //传参数时,使用指定的实参1
    Fun(1);
    return 0;
}
  • 全缺省参数

    cpp 复制代码
    using namespace std;
    void Fun(int a=0,int b=1,int c=2){
        cout<<"a="<<a<<" ";
        cout<<"b="<<b<<" ";
        cout<<"c="<<c<<" ";
        cout<<endl;
    }
    int main(){
        Fun();         
        Fun(10);
        Fun(10,20);
        Fun(10,20,30);
        return 0;
    }
  • 半缺省参数

    cpp 复制代码
    using namespace std;
    void Fun(int a,int b=10,int c=20){
        cout<<"a="<<a<<" ";
        cout<<"b="<<b<<" ";
        cout<<"c="<<c<<" ";
        cout<<endl;
    }
    int main(){
        Fun(1);
        Fun(1,2);
        Fun(1,2,3);
        return 0;
    }

注意:

  • 半缺省参数必须从右往左依次来给出,不能间隔着给。
  • 缺省参数不能在函数声明和定义中同时出现,要在声明中给。
  • 缺省参数必须是常量或全局变量
  • c++支持缺省参数,C语言不支持

五.函数重载

在我们的日常生活中,我们经常遇到一词多义的情况,也就是多义词,即该词被重载了,在不同的场景下会有不同的含义。而在c++同样也有这一情况,也就是函数重载。

1.函数重载的概念

函数重载是一种特殊的函数情况,c++允许在同一作用域中声明几个功能相似的同名函数,函数的形参列表(参数个数,参数类型以及参数类型的顺序)不同,常用来处理功能类似但数据类型不同的问题。

  • 参数个数不同

    void f( ){
        cout<<"f()"<<endl;
    }
    void f(int a){
        cout<<"f(int a)"<<endl;
    }
    
  • 参数类型不同

    cpp 复制代码
    int Add(int a,int b){
        return a+b;
    }
    int Add(double a,double b){
        return a+b;
    }
  • 参数类型的顺序不同

    cpp 复制代码
    void f(int a,char b){
        cout<<"f(int a,char b)"<<endl;
    }
    void f(char a,int b){
        cout<<"f(char a,int b)"<<endl;
    }
  • 特殊情况

    cpp 复制代码
    void F(){
        cout<<"F()"<<endl;
    }
    void F(int a=0){
        cout<<"F()"<<endl;
    }
    int main(){
        F();
        return 0;
    }
    //构成重载
    //无参调用时存在歧义,调用不明确

2.编译链接和函数名修饰规则

为什么C语言不支持函数重载,c++支持函数重载,这涉及到编译链接过程 以及函数名修饰规则

编译链接 需要进行以下几个阶段:预处理编译汇编链接

c++在编译期间链接前会对函数名进行更复杂的修饰,编译器会生成一个包含函数名,返回类型,参数类型等信息的字符串作为修饰名,用于在链接阶段定位函数的正确位置。从而区分同名但参数不同的函数。(注意:不同的编译器函数名修饰格式不一样,以linux系统为例)

cpp 复制代码
//函数名修饰为Addii
void Add(int a,int b)

//函数名修饰为Adddd
void Add(double a,double b)

而C语言的函数名修饰相对简单,通常只是加上一个下划线或者保持不变,所以当出现同名函数时,在链接阶段就会无法正确找到函数位置

以上就是关于c++入门部分的讲解,如果哪里有错的话,可以在评论区指正,也欢迎大家一起讨论学习,如果对你的学习有帮助的话,点点赞关注支持一下吧!!!

相关推荐
转世成为计算机大神16 分钟前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
机器视觉知识推荐、就业指导26 分钟前
C++设计模式:建造者模式(Builder) 房屋建造案例
c++
宅小海35 分钟前
scala String
大数据·开发语言·scala
qq_3273427338 分钟前
Java实现离线身份证号码OCR识别
java·开发语言
锅包肉的九珍39 分钟前
Scala的Array数组
开发语言·后端·scala
心仪悦悦42 分钟前
Scala的Array(2)
开发语言·后端·scala
yqcoder1 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
baivfhpwxf20231 小时前
C# 5000 转16进制 字节(激光器串口通讯生成指定格式命令)
开发语言·c#
许嵩661 小时前
IC脚本之perl
开发语言·perl
长亭外的少年1 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin