我是靠谱客的博主 听话小松鼠,最近开发中收集的这篇文章主要介绍C++入门超详解(1)???? 一、关键字???? 二、命名空间????三、输入&输出???? 四、缺省参数????五、函数重载???? 六、引用???? 七、内联函数???? 八、C++11,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

---

???? ???? 努力到无能为力,拼搏到感动自己。


???? ???? 今天要向各位小伙伴们介绍的是 c++入门语法
在这里插入图片描述

文章目录

  • ???? 一、关键字
  • ???? 二、命名空间
    • ???? 1、命名空间定义
    • ???? 2、命名空间的使用
  • ????三、输入&输出
  • ???? 四、缺省参数
    • ???? 1、缺省参数定义
    • ???? 2、参数缺省的场景
      • ???? (1)全缺省参数
      • ???? (2)半缺省参数
  • ????五、函数重载
    • ???? 1、函数重载概念
    • ???? 2、函数重载实例
  • ???? 六、引用
    • ???? 1、引用的概念
    • ???? 2、引用的特点
    • ???? 3、引用的场景
      • ???? (1)做参数
      • ???? (2)做返回值
    • ???? 4、传值和传引用
    • ???? 5、引用和指针
  • ???? 七、内联函数
    • ???? 1、内联函数的概念
    • ???? 2、内联函数的特点
  • ???? 八、C++11
    • ???? 1、auto关键字
      • ???? (1)简介
      • ???? (2)auto的使用场景
    • ???? 2、范围for循环
    • ???? 3、nullptr

???? 一、关键字

⚓️简介:关键字属于保留字,是整个语言范围内预先保留的标识符。每个C++关键字都有特殊的含义。经过预处理后,关键字从预处理记号中区别出来,剩下的标识符作为记号,用于声明对象、函数、类型、命名空间等

???? 注意❗️ ❗️
???? 不能声明与关键字同名的标识符。

在这里插入图片描述


???? 二、命名空间

⚓️ 目的:对标识符的名称进行本地化,以避免命名冲突名字污染

???? 1、命名空间定义

???? <1>直接命名 (namespace 自定义名称 {})
???? <2>命名空间可以嵌套(可以多个嵌套)

???? 代码⬇️ ⬇️ :

//命名空间的定义和嵌套
namespace N
{
	int a = 10;
	namespace N1
	{
		int a = 20;
		namespace N2
		{
			int a = 30;
		}
	}
}

???? 注意❗️ ❗️
???? 当同一个工程中存在多个相同名称的命名空间,相同名称的命名空间会合并到一起

???? 2、命名空间的使用

???? <1>命名空间名称加作用域限定符

???? 代码⬇️ ⬇️ :

int main() {
	int a = 0;
	cout << a << endl;
	cout << N::a << endl;
	cout << N::N1::a << endl;
	cout << N::N1::N2::a << endl;
	return 0 ;
}

???? <2>using加命名空间成员

???? 代码⬇️ ⬇️ :

using std::cout;
using std::cin;
using std::endl;

???? <3>using namespace加命名空间

???? 代码⬇️ ⬇️ :

using namespace std;

????三、输入&输出

⚓️ cin:标准输入流
⚓️ cout:标准输入流

???? (1)使用cin输入或cout输出时要包含头文件 (没有“.h”,旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用 +std的方式。)。

???? (2)cin和cout都存在于std标准命名空间中,“::”是作用域限定符

???? 注意❗️ ❗️
???? (1)输入和输出都不需要去增加数据格式控制如%d,%c,其可以自动识别
???? (2)在C++中是兼容C的,C中的语法内容在C++中一样可以使用。
???? (3)C中的标准输入函数scanf,标准输出函数printf与C++中的cin,cout各有优劣,使用时应该视情况而定。


???? 四、缺省参数

⚓️ 大家知道备胎是什么吗?
在这里插入图片描述

???? 1、缺省参数定义

⚓️ C++中,在相较于C的基础上引入了缺省参数。缺省数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参。

???? 2、参数缺省的场景

???? (1)全缺省参数

???? 代码⬇️ ⬇️ :

void DatePrint(int year = 0, int month = 1, int day = 1)
{
	cout << year <<"年" <<month<<"月" <<day<< "日" << endl;

}

???? 注意❗️ ❗️
???? 当我们需要进行函数的声明和定义时,在进行声明的时候就给参数指定默认值,后面的定义就不需要指定默认值了。

???? (2)半缺省参数

???? 代码⬇️ ⬇️ :

void TestFun1(int a, int b = 3, int c = 4)
{
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;
}

???? 注意❗️ ❗️
???? 1.半缺省参数必须从右往左依次来给出,不能间隔着给。
???? 2. 缺省参数不能在函数声明和定义中同时出现(一般在进行声明时就给参数指定默认值)。


????五、函数重载

???? 1、函数重载概念

⚓️ 重载:自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。

⚓️ 函数重载的概念:重载函数是函数的一种特殊情况,为使用方便,C++允许在同一作用域中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个函数完成不同的功能。重载函数常用来实现功能类似而所处理的数据类型不同的问题。

???? 2、函数重载实例

???? 代码⬇️ ⬇️ :

int TestFun(int a, int b, int c)
{
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;
	return 0;
}
//(1)参数的类型不同
int TestFun(double a, int b, double c)
{
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;
	return 0;
}
//(2)参数的类型顺序不同
int TestFun(double a, double b, int  c)
{
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;
	return 0;
}
//(3)参数个数不同
int TestFun(int a, int b)
{
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	return 0;
}

???? 注意❗️ ❗️
???? 当函数只有返回值类型不同的时候,不构成函数重载。

在这里插入图片描述

????思考(面试题):为什么C++中支持函数重载,而C语言中不支持?

????思考(面试题):C++能否将一个函数按照C的风格进行编译?


???? 六、引用

???? 1、引用的概念

⚓️ 引用(reference)是C++对C语言的重要扩充。引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。

???? 2、引用的特点

???? (1)引用在定义时必须要初始化
???? (2)一个变量可以有多个引用
???? (3)在作用域内同一个引用不能对多个对象使用。
???? (4) 引用是一种独立的类型

???? 代码⬇️ ⬇️ :

void Test(int& a)
{
	cout << a << endl;
}

void Test(int a)
{
	cout << a << endl;
}

???? 注意❗️ ❗️
???? 这两个函数的定义构成了重载

???? (5)常引用

???? 代码⬇️ ⬇️ :

void Test()
{
	 const int a = 10;
	 //int& ra = a; // 该语句编译时会出错,a为常量
	 const int& ra = a;
	 // int& b = 10; // 该语句编译时会出错,b为常量
	 const int& b = 10;
	 double d = 12.34;
	 //int& rd = d; // 该语句编译时会出错,类型不同
	 const int& rd = d; 
 }

???? 3、引用的场景

传引用的优点:

???? (1)函数形参和实参是同一个对象,也就不存在对象复制,减少调用函数的开销

???? (2)可以在修改形参的同时对实参的修改.

???? (1)做参数

???? 代码⬇️ ⬇️ :

int cp(int& a, int& b)
{
	if (a > b)
		return a;
	else 
		return b;
}

???? (2)做返回值

???? 代码⬇️ ⬇️ :

int& Count()
{
 static int n = 0;
 n++;
 // ...
 return n; }

???? 注意❗️ ❗️
???? 当使用函数返回值引用,返回值不能是局部变量,因为局部变量离开自己的作用域后,会被自动销毁

???? 4、传值和传引用

⚓️ 比较:在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时拷贝,因此用值作为参数或者返回值类型,效率较低,尤其是当参数或者返回值类型非常大时,效率就更低。

⚓️ 通过测试,我们可以得到更加直观的对比。

???? <1>作为参数

???? 代码⬇️ ⬇️ :

#include <time.h>
struct A{ int a[10000]; };
void TestFunc1(A a){}
void TestFunc2(A& a){}
void TestRefAndValue()
{
 A a;
 // 以值作为函数参数
 size_t begin1 = clock();
 for (size_t i = 0; i < 10000; ++i)
 TestFunc1(a);
 size_t end1 = clock();
 // 以引用作为函数参数
 size_t begin2 = clock();
 for (size_t i = 0; i < 10000; ++i)
 TestFunc2(a);
 size_t end2 = clock();
 // 分别计算两个函数运行结束后的时间
 cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
 cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;

???? <2>作为返回值

???? 代码⬇️ ⬇️ :

#include <time.h>
struct A{ int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a;}
// 引用返回
A& TestFunc2(){ return a;}
void TestReturnByRefOrValue()
{
 // 以值作为函数的返回值类型
 size_t begin1 = clock();
 for (size_t i = 0; i < 100000; ++i)
 TestFunc1();
 size_t end1 = clock();
 // 以引用作为函数的返回值类型
 size_t begin2 = clock();
 for (size_t i = 0; i < 100000; ++i)
 TestFunc2();
 size_t end2 = clock();
 // 计算两个函数运算完成之后的时间
 cout << "TestFunc1 time:" << end1 - begin1 << endl;
 cout << "TestFunc2 time:" << end2 - begin2 << endl; }

???? 总结:通过上面两个代码,我们可以发现,在某些场景下选用传引用有着更大的优势

???? 5、引用和指针

???? ???? 相同点:

⏳ (1)通过引用和指针,我们都可以实现在函数的调用过程中,完成对实参的改变。

⏳ (2)引用和指针的本质都是地址,初始化的汇编代码一模一样(如图)

在这里插入图片描述

???? ???? 不同点:

⌛️ (1)引用在其作用域内在被初始化后,不可改变。而指针指向的地址可以发生改变。

⌛️ (2)指针是一种变量,在定义指针时会开辟空间。而引用是对原对象取别名,不会开辟额外的空间。

⌛️ (3)指针和引用的自增自减运算不一样。

⌛️ (4)sizeof(指针)和sizeof(引用)不一样,前者获得的是存放指针变量的空间大小,而后者是原对象的大小。

⌛️ (5)没有NULL引用,有NULL指针。

⌛️ (6)没有多级引用的说法,存在多级指针

⌛️ (7)访问实体方式不同.。指针需要显式解引用,引用则编译器自己处理。

⌛️ (8)引用比指针使用起来相对更安全

⌛️ (9)引用在定义时要求必须初始化,而指针没有要求。

???? 总结:C++中的引用相比与指针而言,在概念上更好理解,一定程度上避免了野指针越界问题,有着更加良好的安全性

????思考(面试题):请说明指针和引用的区别与联系


???? 七、内联函数

???? 1、内联函数的概念

⚓️ 内联函数:以inline修饰的函数叫做内联函数。编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率

???? 2、内联函数的特点

???? (1)内联函数每次调用时直接展开,避免了函数额外开销。但是代码复杂的函数以及递归循环就不适合写成内联函数,内联函数的本质是以时间换空间。(通过反汇编可以观察)

???? (2)当我们写成的内联函数内部有递归循环时,编译器会自动忽略内联,因为inline对编译器而言只是一种建议,编译器会自动优化

???? (3)内联函数不建议将声明和定义分离,因为当内联函数展开之后,就没有函数地址了,链接会找不到。

???? 代码⬇️ ⬇️ :

//Swap.h
#pragma once
#include<iostream>
using std::cout;
using std::endl;
using std::cin;
inline void Swap(int& a, int& b);
//Swap.cpp
#include"Swap.h"
void Swap(int& ra, int& rb)
{
	int tmp = ra;
	ra = rb;
	rb = tmp;
}
//test.cpp
#include"Swap.h"
int main() {
	int a = 1;
	int b = 2;
	Swap(a, b);
	cout << a << "  " << b << endl;
	return 0;
}
//错误链接 	LNK2019	无法解析的外部符号 "void __cdecl Swap(int &,int &)" (?Swap@@YAXAEAH0@Z),函数 main 中引用了该符号

???? 注意❗️ ❗️
???? 当我们把声明和定义分开后,程序就会报错如上(链接错误)。

???? 总结:当函数代码比较简单并且没有递归和循环时,我们可以将它写成内联函数来提高效率。同时内联函数的声明和定义最好不要分离

????思考(面试题):C++中为什么不推荐使用宏?并采用了什么手段来代替宏


???? 八、C++11

???? 1、auto关键字

???? (1)简介

⚓️ 在早期C/C++中,auto修饰变量是具有自动存储类型的局部变量(遗憾没人使用)。在C++11中,标准委员会废除了auto原本的意义(避免混淆),同时把它作为一个新的类型指示符来指示编译器。auto的变量类型必须由编译器在编译时推导获得。

???? 注意❗️ ❗️
???? (1)使用auto定义变量时必须进行初始化,因为编译器在编译时会根据初始化的内容来判断auto定义变量的类型
???? (2)auto不是类型的声明,而是一种类型的“占用符”,在编译器进行编译时会自动将auto替换成对应的类型。

???? (2)auto的使用场景

???? <1>auto和指针、引用进行配合。

???? 代码⬇️ ⬇️ :

#include<iostream>
using std::cin;
using std::cout;
using std::endl;

int main() {
	int a = 1;
	//使用auto定义指针类型时
	//auto和auto*没有区别
	auto b = &a;
	auto* c = &a;
	auto& d = a;
	//typeid().name()是用来打印类型的
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;
	return 0;
}

???? 注意❗️ ❗️
???? 使用auto定义指针类型时,auto和auto*没有区别。

???? <2>同一行可以定义多个变量。

???? 代码⬇️ ⬇️ :

#include<iostream>
using std::cin;
using std::cout;
using std::endl;

int main() {
	int a = 0;
	auto& ra = a, & rra = a, & rrra = a;
	//此代码会报错无法推导类型
	//auto& ra = a, *pa=a;
	return 0;
}

???? 注意❗️ ❗️
???? 使用auto在同一行定义多个变量时,同一行变量的类型要相同。因为编译器会推导的第一个类型,并用推导出的类型去定义其他的变量。

???? <3>auto不能成为函数的参数

???? 代码⬇️ ⬇️ :

void TestFun(auto x);
void TestFun(auto x)
{

}
//报错:此处不能使用auto

???? 注意❗️ ❗️
???? 报错:此处不能使用auto

???? <4>auto不能定义数组

???? 代码⬇️ ⬇️ :

#include<iostream>
using std::cin;
using std::cout;
using std::endl;

int main()
{
	int a[10] = { 0 };
	auto b[10] = { 0 };
	//报错:auto类型不能出现在顶级数组中
	cout << b << endl;
	return 0;
}

???? 注意❗️ ❗️
???? 报错:auto类型不能出现在顶级数组中

???? 2、范围for循环

⚓️ 对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。

???? 代码⬇️ ⬇️ :

#include<iostream>
using std::cin;
using std::cout;
using std::endl;

int main()
{
	//在C++11中,使用初始化列表对数组、枚举等类型进行初始化时,
	//可以省略等号。
	int arr[10]{0,1,2,3};
	for (auto e : arr)
		cout << e << "   ";
	return 0;
}

???? 注意❗️ ❗️
???? continuebreak在范围for中仍然适用。

???? 3、nullptr

⚓️ 在C/C++,我们要养成良好的习惯,即定义变量的时候,同时给变量初始化,避免引发糟糕的结果。例如指针:如果没有初始化,就会引发野指针问题,可能会干扰到其他正在运行的程序。
而对指针初始化的方式就是给它置成空

???? 代码⬇️ ⬇️ :

#include<iostream>
using std::cin;
using std::cout;
using std::endl;

int main()
{
	int* p1 = 0;
	int* p2 = NULL;
	return 0;
}

⚓️ 其中NULL实际是一个,在传统的C头文件(stddef.h)中,我们可以看到如下:

???? 代码⬇️ ⬇️ :

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

⚓️ 但是在使用空指针时,不可避免的会有一定麻烦。
???? 代码⬇️ ⬇️ :

#include<iostream>
using std::cin;
using std::cout;
using std::endl;
//当我们我传递空指针时
void Fun(int x)
{
	cout <<"int" << endl;
}
void Fun(int* x)
{
	cout << "int*" << endl;
}
int main() {
	Fun(0);
	Fun(NULL);
	//强制转换成int*类型
	Fun((int*)NULL);
	Fun(nullptr);
	return 0;
}
//结果为:int int int* int*

⚓️ 原程序中本是想要传递空指针,但是NULL被替换成了0,输出的就是int。除非将NULL强制转换成(int*)类型才能输出(int*)。

⚓️ 在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。

???? 注意❗️ ❗️
???? (1)为了避免上述情况,C++11中引入了nullptr关键字,作为关键字,不需要引用头文件。
???? (2)为了提高代码的健壮性,建议表示空指针时使用nullptr


今天的内容到这里就结束了,关于本期提出的思考题,希望老铁们可以仔细想想,我们下期再谈 。???? ????

在这里插入图片描述


在这里插入图片描述

???? ???? 每天早上叫我们起床的不是闹钟,而是梦想。


???? ???? 愿与诸君共勉!

最后

以上就是听话小松鼠为你收集整理的C++入门超详解(1)???? 一、关键字???? 二、命名空间????三、输入&输出???? 四、缺省参数????五、函数重载???? 六、引用???? 七、内联函数???? 八、C++11的全部内容,希望文章能够帮你解决C++入门超详解(1)???? 一、关键字???? 二、命名空间????三、输入&输出???? 四、缺省参数????五、函数重载???? 六、引用???? 七、内联函数???? 八、C++11所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部