C++入门必看知识点详解

C++入门

前言:本篇博客主要叙述了C++中一些关键字和函数的规则和用法,知识比较零碎,较为冗余。

1.C++关键字

C++关键字(C++98):
例子:
小学生写作文:识字—>造句—>写作文
大学生写代码:关键字—>语句—>实现算法逻辑
由于C++中关键字较多,就不一一解释了,后面用到再说:
在这里插入图片描述

2.命名空间

在C/C++中,变量、函数、类都大量存在,都存在于全局作用域中,可能会发生冲突。使用命名空间的目的是对标识符的名称进行本地化管理namespace关键字来实现
代码举例:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
namespace ZLJ
{
	int a = 10;
	int b = 20;
	int Add(int left, int right)
	{
		return left + right;
	}
}
int main()
{
	printf("%d\n", a);
	printf("%d\n", Add(1,2));
	system("pause");
	return 0;
}

在这里插入图片描述
这是命名空间就起作用了,这也是一个封装思想(不能为所欲为)
命名空间的三种使用方式:
1.加命名空间及作用域限定符

int main()
{
	printf("%d\n", ZLJ::a);
	printf("%d\n", ZLJ::Add(1,2));
	system("pause");
	return 0;
}

2.使用using将命名空间引入

using ZLJ::a;
using ZLJ::Add;
int main()
{
	printf("%d\n", a);
	printf("%d\n", Add(1, 2));
	system("pause");
	return 0;
}

3.使用using namespace 命名空间名称引入

using namespace ZLJ;
int main()
{
	printf("%d\n", a);
	printf("%d\n", Add(1, 2));
	system("pause");
	return 0;
}

3.C++输入&输出

有没有想到刚学习C语言时printf输出的"Hello world";
使用cout标准输出和cin标准输入,必须包换#include<iostream>std标准命名空间
注意:
1.C++编译时头文件不需要<…h>格式
2.C++输入输出更加方便,不需要增加数据格式控制。例:%d,%c,%f

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int main()
{
	int n;
	cin >> n;
	cout << n << endl;
	cout << "Hello World" << endl;
	system("pause");
	return 0;
}

在这里插入图片描述

4.缺省参数

概念:缺省参数是函数声明或定义时为函数的参数提供一个默认值,在调用函数时,如果没有指定实参则采用默认值,否则使用实参
理解:备胎思想,有了就不要你,没有才找你
在这里插入图片描述

4.1全缺省参数:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int Add(int n1 = 1, int n2 = 2,int n3 = 3)
{
	return n1 + n2 + n3;
}

int main()
{
	printf("%d\n", Add());
	system("pause");
	return 0;
}

在这里插入图片描述

4.2半缺省参数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int Add(int n1  , int n2 ,int n3 = 3)
{
	return n1 + n2 + n3;
}

int main()
{
	printf("%d\n", Add(1,2));
	system("pause");
	return 0;
}

在这里插入图片描述
注意:
1.半缺省参数必须从右向左依次给出,不能间隔给。
2.缺省参数不能同时出现在函数声明和定义中
在这里插入图片描述
3.缺省值必须是常亮或全区变量
4.C语言不支持缺省参数

5.函数重载

5.1函数重载的用法

概念:函数名相同,但是其作用和解决的问题不同(自己总结了一下…)
举例:中国奥运会上,乒乓球比赛打完后,我们会佩服的说“谁都赢不了”,看完中国足球比赛后,我们会生气的说“谁都赢不了”,一句话有多种含义。
要求:
相同:
1.函数名相同
2.函数的返回值相同
不同:
1.函数参数的类型或顺序或个数必须不同

2.返回值的参数不同
举例:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int Add(int n1, int n2)
{
	return n1 + n2;
}
double Add(double n1, double n2 )
{
	return n1 + n2;
}

int main()
{
	cout<< Add(1,2)<<endl;
	cout << Add(1.0, 2.0) << endl;
	system("pause");
	return 0;
}

通过调试就可以看到他们调用的函数不同,注意重载必须要满足要求
在这里插入图片描述
比如以上函数参数的类型和个数都相同则无法重载。

5.2 extern关键字

基本理解
extern放在变量或者函数之前,表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。

5.2.1extern有两个作用

1.当它与"C"一起连用时,如: extern “C” void fun(int a, int b);告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的(不同编译器不同),因为C++支持函数的重载。
2…在头文件中: extern int g_Int; 它的作用就是声明全局变量或函数的作用范围的关键。

5.2.2extern和static

static的全局变量作用域只在本文件中,所以extern和static不能同时修饰一个变量;
extern 表明该变量在别的地方已经定义过了,在这里要使用那个变量.
static 表示静态的变量,分配内存的时候, 存储在静态区,不存储在栈上面.
extern可以被其他的对象用extern 引用,而static 不可以,只允许对象本身用它.
static修饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义.
static修饰全局变量的作用域只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,不会影响到其他的单元.

6.引用(重点)

6.1引用概念:

引用不新定义一个变量,而是给已存在变量取了个别名,编译器不会为引用变量开辟空间,它和它所引用的变量共用同一块内存空间
比如:孙悟空,在天上叫“齐天大圣”,成佛后叫"斗战胜佛"
在这里插入图片描述
用法:
在这里插入图片描述

6.2引用特性

1.引用在定义时必须初始化
2.一个变量可以有多个引用
3.引用一旦引用一个实体,再不能引用其他实体

void TestRef()
{
	int  a = 10;
	//int& ra; 这是一条错误语句,引用在定义时必须初始化
	int& ra = a;
	int& rra = a;//一个变量可以有多个引用
	cout << &a << endl; 
	cout << &ra << endl;
	cout << &rra << endl;
}
int main()
{
	TestRef();
	system("pause");
	return 0;
}

其地址空间也是相同的
在这里插入图片描述

6.3常引用:

当变量被常变量const修饰后,则只能使用不能改写,其引用也要使用const修饰,成为常引用,否则会报错
在这里插入图片描述

void TestRef()
{
	const int  a = 10;
	//int& ra; 这是一条错误语句,引用在定义时必须初始化
	const int& ra = a;
	cout << &a << endl; 
	cout << &ra << endl;
}
int main()
{
	TestRef();
	system("pause");
	return 0;
}

6.4使用场景

1.做参数

int Add(int& n1, int& n2)
{
	return n1 + n2;
}

int main()
{
	int a = 10;
	int b = 20;
	 Add(a, b);
	//TestRef();
	system("pause");
	return 0;
}

2.做返回值

int& TestRef(int& a)
{
	a += 10;
	return a;
}

int main()
{
	int a = 10;
	cout<<TestRef(a)<<endl;
	system("pause");
	return 0;
}

要注意这里引用必须是左值引用(C++11会讲到,现在先不管)

6.5 传值、传引用效率(重点)

这里涉及到深浅拷贝的问题后面再细讲。传引用效率更高
这有一份测试性能的代码

#include <iostream>

#include <Windows.h>

using namespace std;

void test1(string str)

{
	string s = str;
}

void test2(string const& str)

{

	string s = str;

}
int main()

{
	DWORD d;

	d = GetTickCount64();
	string str = "hello world!";

	for (int i = 0; i < 100000; i++)

	{

		test1(str);

	}

	cout << "传值用时:" << GetTickCount64() - d << "\n";

	d = GetTickCount64();

	for (int i = 0; i < 100000; i++)

	{

		test2(str);

	}

	cout << "传引用用时:" << GetTickCount64() - d << "\n";
	system("pause");
	return 0;
}

在这里插入图片描述

6.6指针和引用的区别(重点)

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。

int main(
{
int a = 10;
int& ra = a;
cout<<"&a = "<<&a<<endl;
cout<<"&ra = "<<&ra<<endl;
return 0;
}

在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}

我们来看下引用和指针的汇编代码对比:
在这里插入图片描述
引用和指针的不同点(面试题):
1.引用在定义时必须初始化,指针没有要求
2.引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
3.没有NULL引用,但有NULL指针
4.在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
5.引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
6.有多级指针,但是没有多级引用
7.访问实体方式不同,指针需要显式解引用,引用编译器自己处理
8.引用比指针使用起来相对更安全

7.内联函数

7.1 概念

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。
在这里插入图片描述

7.2特性

1… inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。
2. inline对于编译器而言只是一个建议,编译器会自动优化,如果定义 inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。
3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

发布了37 篇原创文章 · 获赞 134 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43676757/article/details/105361860