【C++】——入门(关键字,命名空间,输入输出,缺省参数,函数重载,内联函数,auto关键字与基于范围的for循环)

创作不易,多多支持!

前言

从这篇开始正式走向c++的道路了,这篇主要是c++的入门,也就是大致了解一些c++的基础,这篇就是关于c++对于c的补充和优化,为后面的学习打下基础

一 C++的关键字

对于c++的关键字,因为有很多,毕竟是入门我们现在只做了解就行,c++总计63个关键字,c总计32个关键字

二 命名空间

在写c++的程序的时候,经常会写道using namespace std,这段代码,其实这个的意思就是展开std这个命名空间,使得我们可以用里面的函数和操作符

之所以要有这个命名空间,是因为在c语言里面定义了与库函数同名的变量就会报错,只能修改名字,所以这里使用了这个命名空间去封装,变成一个域,这个域,不使用特殊的操作符是访问不到的

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <math.h>
int  pow= 10;//定义
int main()
{
	printf("%d\n", pow);
	return 0;
}

因为pow函数在math.h这个头文件里面,展开以后会导致重名,而这种在c语言是不允许的

但是如果我们开辟一个域,把它放进域里面,那么就不会有这个现象了

在使用之前得先说明一下它的命名规则
定义命名空间,需要使用到 namespace 关键字 ,后面跟 命名空间的名字 ,然 后接一对 {} 即可, {}
中即为命名空间的成员。
这里注意定义了命名空间就相当于定义了一个新的作用域,这个空间里面的所有内容都局限与这个空间中

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <math.h>
namespace N1
{
	int  pow = 10;
}

int main()
{
	printf("%d\n",pow);//直接访问会出错,因为命名空间的变量,其他地方不能直接访问到
	return 0;
}

这里就变成了随机值

那如何才能访问呢,其实很简单

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <math.h>
namespace N1
{
	int  pow = 10;
}

int main()
{
	printf("%d\n",N1::pow);
	return 0;
}

仔细观察这个::操作符其实很好理解就是在N1这个作用域去寻找这个pow变量。如果放在之前c语言里面看就会是这样

cpp 复制代码
int a = 10;
int main()
{
	int a = 20;
	printf("%d\n",a);//这个a输出是20,因为查找的原则是在局部域找,找不到再在全局域找
	return 0;
}
cpp 复制代码
int a = 10;
int main()
{
	int a = 20;
	printf("%d\n",::a);//这个a输出是10,如果::前面啥都没有,就会跳过局部域,直接在全局域找
	return 0;
}

看完上面两段代码,其实就很好理解这个N1::了,就是在N1这个命名空间去寻找,跳过全局域和局部域。

命名空间有三种使用方式

1.加命名空间名称及作用域限定符

cs 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

namespace N1
{
	int  a = 10;
}

int main()
{
	printf("%d\n",N1::a);
	return 0;
}

2.使用using将命名空间中某个成员引入

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

namespace N1
{
	int  a = 10;
}
using N1::a;//这里引用以后,后面用到这个变量就不需要再用其他操作才能访问了
int main()
{
	printf("%d\n",a);
	return 0;
}

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

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

namespace N1
{
	int  a = 10;
}
using namespace N1;//这里全局展开,代表这个空间的所有内容都可以访问,不需要用限定操作符
int main()
{
	printf("%d\n",a);
	return 0;
}

三**. C++输入&**输出

cpp 复制代码
#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
cout<<"Hello world!!!"<<endl;
return 0;
}

从代码中可以看出来,c++的输入输出是用cin,cout进行的,这两个和c语言里面的输入输出不一样,c++的输入输出不是函数, cout和cin是全局的流对象

#include<iostream>包含了对象和操作符,其实命名空间std包含在这个头文件中,里面的输入输出流对象就是在std这个命名空间定义的

所以我们单纯写一个#include<iostream>是没用的,需要把std展开,或者是用操作符去操作

命名空间有三种使用方式,可能会觉得第三种方便一点,其实不然,全局展开以后,如果变量和函数同名也是一样的报错,特别是在一些大一点项目,查找起来很不方便,为了简化代码,通常使用 using namespace std; 指令来避免在每次使用标准库中的功能时都 缀 std::。但是,这种做法在大型项目或库开发中可能会导致命名冲突,因此建议在小型程序或学习时使用,而在大型项目中谨慎使用。

四 缺省参数

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

如果有点不解可以看下面的代码

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
int fun(int a = 0)
{
	return a;
}
int main()
{
	int b=fun(10);//有实参
	cout << b << endl;
	int c = fun();无实参
	cout << c << endl;
	return 0;
}

从运行结果就可以很好理解上面的话了

缺省参数也分为全缺省和半缺省

1.全缺省

cpp 复制代码
void Fun(int a = 10, int b = 20, int c = 30)
 {
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }

2.半缺省

cpp 复制代码
void Fun(int a, int b = 10, int c = 20)
 {
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }

这里注意半缺省中从右往左去缺省,不能中间空一个

再者就是缺省参数不能在定义和声明中同时出现

因为这个会导致编译器不知道用哪个缺省值

cpp 复制代码
int fun(int a = 10)
{
	return a;
}//.cpp

int fun(int a=10);//.h

五 函数重载

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

在c语言中两个函数同名就会报错,又要重新换名,这就搞得我们这些不会起名字的非常难受,所以在c++中就加了函数重载

在c语言中之所以会报错,因为c语言去调用函数是通过函数名去查找的,而c++是通过函数名加参数类型去查找的,就使得c++支持函数重载,c语言不支持

通过这里就理解了 C 语言没办法支持重载,因为同名函数没办法区分。而 C++ 是通过函数修
饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载

这里还需要注意的就是如果单单只是返回值不一样是不构成重载的,因为这个命名规则只与参数类型和函数名来决定,返回值是不在里面的

六 引用

6.1 引用概率

引用不是创建一个新的变量,可以理解为是对另外一个对象进行取别名,相信你们小时候肯定也会

有小名,那叫你的姓名和叫你的小名都是你自己没用区别,所以使用引用的时候,编译器不会为引

用变量开辟内存空 间,它和它引用的变量共用同一块内存空间。引用的底层其实和指针是一样

的,这里不深究,只需要知道就行。

cpp 复制代码
int main()
{
	int a = 10;
	int& b = a;//引用用法
	cout << a << endl << b << endl;
	return 0;
}

这里的a,b的结果是一样的 都是10

这里注意引用类型必须和引用实体是同一类型

6.2 引用特性

1.使用引用的时候必须初始化

2.一个变量可以有多个引用

3.引用一旦引用一个实体就不能再引用其他实体了(也就是说引用不能改变方向)

6. 3 常应用

cpp 复制代码
void fun()
{
    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;
}

这里之所以不能用是因为权限不能被放大,但是能缩小const int a=10,只能读,不能写,但是int& ra=a以后,那a的权限就被放大了,这是不被允许的

对于int &rd=d来说,d会被强制类型转换成int类型,这个阶段会产生一个临时变量,这个临时变量是不能改变的,所以就会报错

七 内联函数

7.1内联函数概念

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

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
int Add(int a, int b)
{
	return a + b;
}
int main()
{
	int ret = Add(1, 2);
	return 0;
}

对于上面的Add函数如果加上inline修饰那么就会在编译期间把函数体替换这个函数

7.2内联函数特性

  1. inline 是一种 以空间换时间 的做法,如果编译器将函数当成内联函数处理,在 编译阶段,会
    用函数体替换函数调用 ,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运
    行效率
    2.如果是短小且经常用到的函数可以用内联这样可以提高允许效率,如果是比较长的代码函数去用
    内联可能会导致错误,我们在使用内联函数的时候其实只是一个建议,采不采取看编译器
  2. inline 不建议声明和定义分离,分离会导致链接错误。因为 inline 被展开,就没有函数地址
    了,链接就会找不到。
    其实内联函数的出现就是为了替代c语言里面的宏,因为宏非常容易出错,且不容易调试

八 auto关键字

8.1 auto与typedef

对于auto关键字来说,可以理解为自动标识类型,可以避免很长的命名,导致拼写出错

可能也有人用typedef去代替,其实大部分都行,只不过有特殊的会有错误

cpp 复制代码
typedef char* pstring;
int main()
{
 const pstring p1;    // 编译成功还是失败?
 const pstring* p2;   // 编译成功还是失败?
 return 0;
}

这里就是下面一行编译成功,因为pstring 是char*的别名所以这里的p1因为用const修饰,所以得

初始化,这里的p2是const pstring 的一个指针,这里const修饰只是使得p2不能改变这个值,但

是他可以指向其他的const pstring 。

8.2 auto****简介

在早期 C/C++ 中 auto 的含义是:使用 auto 修饰的变量,是具有自动存储器的局部变量 ,但遗憾的
是一直没有人去使用它,大家可思考下为什么?
C++11 中,标准委员会赋予了 auto 全新的含义即: auto 不再是一个存储类型指示符,而是作为一
个新的类型指示符来指示编译器, auto 声明的变量必须由编译器在编译时期推导而得

auto在与指结合使用的时候,可以
auto a = & x ;
auto * b = & x ;
两者方式都行,对于引用类型就只能加上&

8.3 auto使用规则

1.auto不能作为函数参数进行传参

2.auto类型必须初始化

3.auto不能用来声明数组

cpp 复制代码
auto b[]={1,2,3};//错误

4.auto类型不能在同一行定义多个不同类型的变量

cpp 复制代码
auto c = 3, d = 4.0;//类型不同

九.基于范围的for循环

对于一个数组的遍历可能我们最多的是下面这种形式

cpp 复制代码
int main()
{
	int a[] = { 1,2,3,4,5,6,7,8,9 };
	for (int i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		cout << a[i];
	}
}

可行,但是对于c++来说,有更好的表达方式

cpp 复制代码
int main()
{
	int a[] = { 1,2,3,4,5,6,7,8,9 };
	for (auto& e : a)//相当于从a里面拿数据然后放进e里面去
	{
		cout << e << endl;
	}
}

注意这里e是a的别名,所以改变e就可以改变a数组里面的值

cpp 复制代码
int main()
{
	int a[] = { 1,2,3,4,5,6,7,8,9 };
	for (auto& e : a)
	{
		e = 2 * e ;
	}
	for (int i = 0; i < sizeof(a)/sizeof(int); i++)
	{
		cout << a[i] << endl;
	}
}

10.指针空值nullptr

这里说明一下,在c++中,NULL表示是0,并不是一个void*类型的

所以在c++中引入了一个新的关键字nullptr用来表示空值,不需要包含头文件。

以上就是c++入门的大致知识点,理解完这些,对于以后的学习才能够一通百通!如果看到这里觉得对你有用,那就支持一下吧,铁铁,我爱说实话

相关推荐
一点媛艺3 小时前
Kotlin函数由易到难
开发语言·python·kotlin
姑苏风3 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
奋斗的小花生4 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程5 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
UestcXiye6 小时前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
Chrikk6 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*6 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue6 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang