【C++基础】初识C++(1)

目录

一、认识C++

[1.1 C++ 相关概念](#1.1 C++ 相关概念)

[1.2 C++的发展](#1.2 C++的发展)

[1.3 C++的关键字](#1.3 C++的关键字)

[1.4 第一个程序](#1.4 第一个程序)

二、命名空间

[2.1 namespace的定义](#2.1 namespace的定义)

[2.2 命名空间的使用](#2.2 命名空间的使用)

三、C++输入和输出

四、缺省函数

五、函数重载


一、认识C++

1.1 C++ 相关概念

1983年,Bjarne Stroustrup在C语⾔的基础上添加了⾯向对象编程的特性,设计出了C++语⾔的雏形,此时的C++已经有了类、封装、继承等核⼼概念,为后来的⾯向对象编程奠定了基础。这⼀年该语⾔被正式命名为C++。

C++是基于C语言而产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计

1.2 C++的发展

1.3 C++的关键字

C语言32个关键字,C++总计63个关键字。
后期学习慢慢了解

1.4 第一个程序

C++兼容C语⾔绝⼤多数的语法,所以C语⾔实现的hello world依旧可以运⾏

cpp 复制代码
#include<stdio.h>
int main()
{
    printf("hello world\n");
    return 0;
}

当然C++有⼀套⾃⼰的输⼊输出,严格说C++版本的helloworld应该是这样写的

cpp 复制代码
#include<iostream>
using namespace std;
int main()
{
    cout << "hello world\n" << endl;
    return 0;
}  //这⾥的std cout等我们都看不懂,没关系,下⾯我们会依次讲解

二、命名空间

在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的
举个栗子:

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

这里会报错, 因为rand已经在<stdlib.h>头文件中定义过, 所以再次定义全局变量rand, 作用域都是全局, 会导致名称重复, C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决

2.1 namespace的定义

定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中
即为命名空间的成员。命名空间中可以定义变量/函数/类型等。

++注意: 这里和结构体的区别在于结构体{}后有 ; 而命名空间没有++

namespace本质是定义出⼀个域,这个域跟全局域各自独⽴,不同的域可以定义同名变量,所以下⾯的rand不在冲突了

(1)定义命名空间

命名空间可以定义变量/函数/类型

cpp 复制代码
namespace Myname
{
// 命名空间中可以定义变量/函数/类型
    int rand = 10;

    int Add(int left, int right)
    {
        return left + right;
    } 

    struct Node
    {
        struct Node* next;
        int val;
    };
}

int main()
{
// 这⾥默认是访问的是全局的rand函数指针
    printf("%p\n", rand);
// 这⾥指定bit命名空间中的rand
    printf("%d\n", Myname::rand);
    return 0;
}

通过 :: 使用命名空间中的成员

作用域运算符 :: :在C++中用于访问命名空间的成员和限定类的成员函数的定义位置。
可以理解为访问操作符,用于访问变量和函数。

(2)命名空间可以嵌套

cpp 复制代码
namespace N1
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}

	namespace N2
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}

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

2.2 命名空间的使用

编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。我们要使⽤命名空间中定义的变量/函数,有三种⽅式:

  • 指定命名空间访问
  • using将命名空间中某个成员展开
  • 展开命名空间中全部成员
cpp 复制代码
// 指定命名空间访问
int main()
{
    printf("%d\n", N::a);
    return 0;
}
cpp 复制代码
//using将命名空间中某个成员展开
using N::b;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    return 0;
}
cpp 复制代码
// 展开命名空间中全部成员
using namespce N;
int main()
{
    printf("%d\n", a);
    printf("%d\n", b);
    return 0;
}

using和using namespace两者区别:

using 声明:通过using 命名空间::成员的方式,可以将命名空间中的特定成员引入当前作用域,只能引入命名空间中的指定成员,不会引入整个命名空间。
using namespace指令:通过using namespace 命名空间的方式,可以将整个命名空间的所有成员引入当前作用域,可以直接访问整个命名空间中的成员,但可能会引入命名空间中的不必要成员,增加命名冲突的可能。

三、C++输入和输出

  • <iostream>是Input Output Stream的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输出对象。
  • std::cin是 istream 类的对象,它主要⾯向窄字符(narrow characters (of type char))的标准输⼊流
  • std::cout 是 ostream 类的对象,它主要⾯向窄字符的标准输出流
  • std::endl 是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区
  • <<是流插⼊运算符,>>是流提取运算符。(C语⾔还⽤这两个运算符做位运算左移/右移)
  • 使⽤C++输⼊输出更⽅便,不需要像printf/scanf输⼊输出时那样,需要⼿动指定格式,C++的输⼊输出可以⾃动识别变量类型,其实最重要的是C++的流能更好的⽀持⾃定义类型对象的输⼊输出。
  • cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要通过命名空间的使⽤⽅式去⽤他们
cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
    int a = 0;
    double b = 0.1;
    char c = 'x';
    cout << a << " " << b << " " << c << endl;
    std::cout << a << " " << b << " " << c << std::endl;
    scanf("%d%lf", &a, &b);
    printf("%d %lf\n", a, b);
    // 可以⾃动识别变量的类型
    cin >> a;
    cin >> b >> c;
    cout << a << endl;
    cout << b << " " << c << endl;
    return 0;
}

注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用+std的方式。

四、缺省函数

  • 缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时,如果没有指定实参则采⽤该形参的缺省值,否则使⽤指定的实参,缺省参数分为全缺省和半缺省参数。(有些地⽅把缺省参数也叫默认参数
  • 带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参。
  • 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值

举个栗子:

cpp 复制代码
#include <iostream>
using namespace std;
void Func(int a = 0)
{
    cout << a << endl;
} 
int main()
{
    Func(); // 没有传参时,使⽤参数的默认值
    Func(10); // 传参时,使⽤指定的实参
    return 0;
}

全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。

举个栗子:

cpp 复制代码
#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl << endl;
} 
int main()
{
    Func1();
    Func1(1);
    Func1(1,2);
    Func1(1,2,3);
  
    return 0;
}
cpp 复制代码
#include <iostream>
using namespace std;
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl << endl;
} 
int main()
{
    Func2(100);
    Func2(100, 200);
    Func2(100, 200, 300);
    return 0;
}

五、函数重载

C++⽀持在同⼀作⽤域中出现同名函数 ,但是要求这些同名函数的形参不同 ,可以是++参数个数不同或者类型不同++。这样C++函数调⽤就表现出了多态⾏为,使⽤更灵活。

举个栗子:

cpp 复制代码
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
    cout << "int Add(int left, int right)" << endl;
    return left + right;
}
    double Add(double left, double right)
{
    cout << "double Add(double left, double right)" << endl;
    return left + right;
}
// 2、参数个数不同
    void f()
{
    cout << "f()" << endl;
}
    void f(int a)
{
    cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
    cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
    cout << "f(char b, int a)" << endl;
}
int main()
{
    Add(10, 20);
    Add(10.1, 20.2);
    f();
    f(10);
    f(10, 'a');
    f('a', 10);
    return 0;
}

返回值不同不能作为重载条件,因为调⽤时会⽆法区分

举个栗子:

cpp 复制代码
void fxx()
{}

int fxx()
{
 return 0;
}

下⾯两个函数构成重载
但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁

cpp 复制代码
void f1()
{
    cout << "f()" << endl;
} 
void f1(int a = 10)
{
    cout << "f(int a)" << endl;
}

本篇完,带大家简单认识一下c++,如有问题欢迎指正交流!感谢!下篇见!

相关推荐
UestcXiye8 分钟前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
Chrikk8 分钟前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*11 分钟前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue11 分钟前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man14 分钟前
【go从零单排】go语言中的指针
开发语言·后端·golang
霁月风1 小时前
设计模式——适配器模式
c++·适配器模式
萧鼎2 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸2 小时前
【一些关于Python的信息和帮助】
开发语言·python
疯一样的码农2 小时前
Python 继承、多态、封装、抽象
开发语言·python
^velpro^2 小时前
数据库连接池的创建
java·开发语言·数据库