目录
[0. 前言](#0. 前言)
[1. C++的第一个程序](#1. C++的第一个程序)
[2. 域](#2. 域)
[2.1 分类](#2.1 分类)
[2.2 作用](#2.2 作用)
[2.3 命名空间](#2.3 命名空间)
[2.3.1 定义](#2.3.1 定义)
[2.3.2 namespace概念](#2.3.2 namespace概念)
[2.3.3 使用](#2.3.3 使用)
[3. 输入和输出](#3. 输入和输出)
[3.2 cin](#3.2 cin)
[3.3 cout](#3.3 cout)
[3.4 endl](#3.4 endl)
[4. 缺省参数](#4. 缺省参数)
[4.1 定义](#4.1 定义)
[4.2 分类](#4.2 分类)
[4.3 特点](#4.3 特点)
[5. 函数重载](#5. 函数重载)
[5.1 定义](#5.1 定义)
[5.2 类型分类](#5.2 类型分类)
[5.2.2. 参数个数不同](#5.2.2. 参数个数不同)
[6. 引用](#6. 引用)
[6.1 概念](#6.1 概念)
[6.2 特点](#6.2 特点)
[6.3 简单使用](#6.3 简单使用)
[6.4 const引用](#6.4 const引用)
[6.4.1 概念](#6.4.1 概念)
[6.5 指针和引用](#6.5 指针和引用)
[9. 总结](#9. 总结)
0. 前言
今天,咱儿,来学习一名新的语言C++。在正式敲代码之前,我们先来熟悉一下一些入门的基础知识。👇👇👇
1. C++的第一个程序
cpp
#include<iostream>
using namespace std;
int main()
{
cout<<"Hello world\n"<<endl;
return 0;
}
2. 域
2.1 分类
局部域、全局域、命名空间域、类域。
2.2 作用
影响编译查找逻辑(当发生冲突时:类域>局部域>全局域),局部域和全局域还可能会影响变量的生命周期。
2.3 命名空间
2.3.1 定义
在C/C++中,变量、函数和后面要学到的类都是大量存在的。如果将这些变量、函数和类的名称都存放于全局作用域中,可能会导致很多冲突。这时,我们就需要使用命名空间,它目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,而namespace就是针对这种问题的一个关键字。
形式:namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等。eg: namespace xiaodenger { int a=0;}
2.3.2 namespace概念
1.它的本质是定义一个域,与全局域相互独立,来避免命名冲突。
2.只能定义在全局,不过,可以嵌套调用哦🤭🤭🤭
cpp
namespace xiaodenger
{
namespace nam1 //这里将nam1嵌套在xiaodenger中
{
int a=1;
return a+1;
}
namespace nam2 //这里将nam2嵌套在xiaodenger中
{
int a=1; // 这里的a与nam1中的a在两个不同的域中,不会冲突
return a+2; // 但是,如果没有 nam1和nam2,直接写,就会发生冲突
}
}
3.多文件中定义的同名namespace,会合并到一起,就像同一个namespace一样,不会冲突。
4.C++标准库都放在⼀个叫std(standard)的命名空间中。
2.3.3 使用
咱们要使用命名空间中定义的变量/函数,有三种方式:
• 指定命名空间访问,项目中推荐。
cpp
#include<iostream>
namespace xiaodenger
{
int a = 1;
int b = 2;
}
int main()
{
std::cout << a << std::endl; // 编译报错:error C2065:"a":未声明的标识符
std::cout << xiaodenger::a <<std:: endl; //输出 1
return 0;
}
• using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员时推荐。
cpp
#include<iostream>
namespace xiaodenger
{
int a = 1;
int b = 2;
}
using namespace std; //展开C++标准库
using xiaodenger::b ;// 展开命名空间中部分成员
int main()
{
cout << xiaodenger::a << endl;//输出1
cout << b << endl; //输出2
return 0;
}
• 展开命名空间中全部成员,项目中不推荐,冲突风险大,日常练习可以适当使用😄。
eg:⼀般日常练习中我们可以using namespace std,实际项目开发中不建议使用。
cpp
#include<iostream>
namespace xiaodenger
{
int a = 1;
int b = 2;
}
// 展开命名空间中全部成员
using namespace xiaodenger;
using namespace std; //展开C++标准库
int main()
{
cout<<xiaodenger::a<<endl; //输出1
cout<<xiaodenger::b<<endl; //输出2
return 0;
}
3. 输入和输出
3.1<iostream>
定义:<iostream>是Input Output Stream的缩写,是标准的输入、输出流库(IO流),定义了标准的输入、输出对象。
tip: vs系列编译器,也可以在<iostream>中使用printf 和scanf。其他编译器可能会报错。
3.2 cin
1.std::cin 是istream类的对象,它主要面向窄字符(narrowcharacters(oftypechar))的标准输入流。
2.cin搭配'>>'使用。'>>'称为"提取运算符"。eg:cin>>a;//输入a的值。
3.3 cout
1.std::cout 是ostream类的对象,它主要⾯向窄字符的标准输出流。
2.cout搭配'<<'使用。'<<'称为"插入运算符"。eg:cout<<a;//输出a的值。
3.4 endl
std::endl 是⼀个函数,流插入输出时,相当于插入一个"\n" + 刷新缓冲区。
4. 缺省参数
4.1 定义
缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。
若调用该函数时,没有指定实参 ,则采该形参的缺省值;否则使用指定的实参。
cpp
#include <iostream>
#include <assert.h>
using namespace std;
void Fun(int a = 0)
{
cout << a << endl;
}
int main()
{
Fun();// 没有传参时,使⽤参数的默认值
Fun(8); // 传参时,使⽤指定的实参
return 0;
}
4.2 分类
缺省参数分为全缺省和半缺省参数。(有时, "缺省参数"也叫"默认参数")
4.3 特点
1.C++规定,半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。
2.函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省 值。
cpp
#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 1, int b = 2, int c = 3)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 1, int c = 2)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
int main()
{
Func1(); //输出 a=1 b=2 c=3
Func1(4); //输出 a=4 b=2 c=3
Func1(4, 5); //输出 a=4 b=5 c=3
Func1(4, 5, 6); //输出 a=4 b=5 c=6
Func2(10); //输出 a=10 b=1 c=2
Func2(10, 20); //输出 a=10 b=20 c=2
//Func1(10, , 30); //不能间断赋缺省值
return 0;
}
5. 函数重载
5.1 定义
C++支持持在同⼀作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者类型不同。此时,同名函数就是重载。
5.2 类型分类
5.2.1.参数类型不同
eg : int Add(int a, int b); 和 int Add(float a, float b);
5.2.2. 参数个数不同
eg : int f(int n); 和 int f();
5.2.3.参数l类型顺序不同
eg: void f(int a, char b); 和 void f( char a,int b);
tip:
返回值不同不能作为重载条件,因为调用时可能无法区分(有时不需要返回值,有时候只要看看返回值是否大于0)。
eg: void f() ; 和 int f();
6. 引用
6.1 概念
1.引用不是新定义⼀个变量,只是给已存在变量取了⼀个别名,编译器不会为引用变量开辟内存空间, 它和它引用的变量共用同⼀块内存空间。
2.形式:
类型& 引用别名=引用对象;
eg:
int a = 0;
int & b = a; // 引用: b 是 a 的别名
tip:C++中&既可以代表引用,也可以代表取地址。(有点小坑😔)一般情况下,类型& 引用别名=引用对象; 时为引用,其他情况下为取地址。
6.2 特点
1.引用在定义时必须初始化;
2.⼀个变量可以有多个引用;
3.引用⼀旦引用⼀个实体,再不能引用其他实体。
【这里小邓儿,给咱举个形象的例子:🤭🤭🤭引用就像是爱上一个人。一旦我爱上你(我是你的引用),就不会再去爱别人(我不能是其他人的引用)。即使有很多人爱上我,(我可以有其它引用)但是,我始终只爱你一人。(我一直都只是你的引用)❤❤❤】
6.3 简单使用
1.引用传参和引用做返回值中减少拷贝,提高效率;
2.改变引用对象时,同时改变被引用对象。
cpp
#include <iostream>
using namespace std;
void Swap(int& rx, int& ry) //rx是x的别名;ry是y的别名
{
int tmp = rx;
rx = ry;
ry = tmp;
}
int main()
{
int x = 0, y = 1;
cout << x << " " << y << endl; //输出0 1
Swap(x, y);
cout << x << " " << y << endl; //输出1 0
return 0;
}
6.4 const引用
6.4.1 概念
当对象被const修饰(具有'常性'---不能直接修改,可以间接修改 vs '常量'---不能修改)时,必须用const引用才能引用该对象。而引用普通对象,也可以用const引用。
6.4.2用法
以下的权限是从右向左看(●'◡'●)
1.权限不能放大
1.❌错误
const int a = 10;
int& b = a; //error 右边a不能被修改,而左边int是可修改的
2.❌错误
int a = 10;
double & b = a; //error 右边是double类型,而左边是int类型
2.权限可以平移
const int a = 10;
const int& b = a; //此时b是a的别名,左右两边都是const int 均不能修改
3.权限可以缩小
int a = 10;
const int& b = a; //此时b是a的别名,右边是可修改变量,左边是不能修改的
tip:区别引用和赋值
const int a=1;
const int &b=a; //引用
int c=a; //赋值
6.5 指针和引用
1.指针要开辟空间,引用不开辟;
2.引用必须初始化,指针建议初始化;
3.引用在初始化时引用⼀个对象后,不能再引用其他对象; 而指针可以在不断地改变指向对象。(从这里儿,我们可以将"引用"堪称一个"好男人",而"指针"更像是一个"渣男")。
4.引用可以直接访问指向对象,指针需要解引用才是访问指向对象。
7.inline相关概念
1.用inline修饰的函数叫做内联函数;
2.编译器会在调用的地方展开内联函数,会建立栈帧,可以提高效率;
3.C++设计了inline目的就是替代C的宏函数(define);
4.inline不能将声明和定义分离到两个文件,分离会导致链接错误。
8.nullptr相关概念
1.C++11中引入nullptr,nullptr是⼀个特殊的关键字,它可以转换成任意其他类型的指针类型。
2.使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,而不能被转换为整数类型。
3.C++中NULL可能被定义为字面常量0,或者C中被定义为无类型指针(void*)的常量。这也是为什么咱们要引入nullprt。
9. 总结
今天,咱对C++入门的相关概念进行了梳理,希望小邓儿可以和大家一起学习进步学习💪💪💪
都看这么久了,顺带一键三连呗(●'◡'●)
