C++语法介绍(一) —— C++初步

大家好,我是Eterna丶King。这是讲解C++类设计的前置基础介绍,我会尽力用通俗易懂的语言使大家明白C++语言的部分特性。

 

一、读入和输出

对于C++来说,读入和输出并没有任何函数可以用来调用,而是专门使用了一个全面的标准库来提供IO机制(input/output)。大多数时候,iostream库已经可以解决大部分问题了。C++是一门OOP语言(Object Oriented Programming),这意味着我们实际上是使用对象来解决问题,而非单纯的函数。标准库定义了4个IO对象。大多数时候我们只需要使用的是cin和cout对象。另外还有两个ostream对象cerr和clog(不过不常用就是了)。接下来用一段代码解释解释一下怎么使用这两个对象。

#include<iostream> //如果想使用IO,就得先引入头文件
int main(void)
{
	int a, b;//定义变量,注意,局部变量在没有赋值的情况下是没有特定值的,因此无法获取里面的值
	//int c = b;比如这是一句错误的代码
	std::cin >> a >> b;// std::是一个命名空间 实际上 >> 是一个被重载的运算符,而且这个运算符优先级非常低
	std::cout << a + b << std::endl;//endl是一个操纵符,主要功能是换行并且清空缓冲区
	return 0;
}

 

二、内置数据类型

C++定义了几个常用的基本数据类型,比如int,double,char,bool。(默认大家都会,不会再问)。对于数据,主要有类型转换这种操作。在C语言中,一般有隐式和显式转换两种。但是需要注意的是,类型转换常常伴随着一定的危险。数据是有其表示范围的,如果将一个范围大的转换成一个范围小的数据类型,那么很容易发生精度损失,最后得到的值就不是期望值了。如果将一个范围小的转换到范围大的数据就没有什么大问题了。而隐式转换和显式转换有什么区别呢?实际上,显式转换更像是一种强行转换,在特定的情况下使用比较好,接下来代码展示一下类型转换。

#include<iostream>
int main(void)
{
	int a = 10000000;
	short b = 1;
	short c = a;//因为short的表示范围为-32768~32767, 因此最后c的输出结果肯定不是a表示的值
	double k = double(b) / a;//如果想要最后得到是一个浮点数,就得先强制类型转换
	std::cout << c << std::endl;
	std::cout << k << std::endl;
	return 0;
}

三、引用

引用是变量的一个别名。为什么说是一个别名,首先我们明确一下变量是个什么东西,变量其实是一块具名的内存空间。那么引用就相当于你对同一块内存空间取了两个名字。那么这两个变量名字其实都是可以操作这片空间,下面一段代码解释一下以上说的是什么。

#include<iostream>
int main(void)
{
	int a = 2, c = 1;
	int& b = a;//在类型说明后面加&表示b是a的一个引用,此时对b的操作等价于对a操作
	b = 3;//a也变成了3
	// b = c;错误的代码语句,因为引用绑定之后就相当于这个变量变成了a,如果此时将b绑定到c上,等价于把a变成c,所以一旦引用绑定后,就不能再重新绑定了
	std::cout << a << std::endl;
	return 0;
}

 

四、指针

指针是C语言和C++语言的一大特色。要理解指针能做什么,就要先理解指针到底是个什么东西。指针其实也是一个对象,但是指针很特殊,它存储的是指针所指向变量的地址。这么说起来其实挺复杂的,我们先来考虑一下变量是什么,变量是一块具名的内存空间,那么对于一个空间来说,必定是有自己所存在的位置的。考虑一下,我们假设品学楼是一块内存空间,那么对于一个教室来说,就有它自己的位置,这就是地址,而B413之类的就相当于一个地址名了。实际上,对于计算机来说也是一样的,内存空间也是有自己的编号的,而计算机想要使用这些内存空间,就需要进行寻址操作,显然想要寻址就要有一个地址名,那么指针就起到了存储地址名的作用。所以指针只是一个存储位置的变量,而我们通常喜欢形象地说“指针指向了变量”。下面一段代码介绍一下指针如何使用。

#include<iostream>
int main(void)
{
	int a = 3, b = 10;
	int* pos = &a;//int* 表示这是一个指向整形变量的指针
	//注意,对上面这句话的理解应该是这样的:
	//首先我们声明了一个指针,然后这个指针是int类型的,但是如果你写下了如下语句:
	//int *pos2 = &b, c = 5;
	//我们需要注意的是在考虑c这个变量时,不应该将其看成一个指针,我们对于指针声明应该保持一对一,一个*号代表一个指针
	std::cout << *pos << std::endl;// *pos表示输出这个地址里面的变量值,*叫做解引用符。
	//*号对于一个指针来说有点类似于寻址,我们用*号寻到这个地址,然后输出里面的值。
	pos = &b;//因为指针是一个对象,拥有自己的地址,因此可以直接修改它。
	std::cout << *pos << std::endl;//输出10
	return 0;
}

 

五、类型说明符auto

如果想要将一个值赋给声明的变量时,就需要知道完整地知道这个变量的类型。但是,在某些情况下,我们很难推断出一个变量到底是什么类型(比如说C++的lambda表达式),这对于写代码造成了极大的麻烦。但是,在C++11中,引入了auto类型说明符这个神奇的东西。这个东西的作用的就是不需要写出变量类型就能直接声明出这个变量了,下面这段代码进行展示。

#include<iostream>
#include<vector>
int main(void)
{
	std::vector<int> v;
	auto iter = v.begin();//这个时候我们无需知道v.begin()究竟是什么类型就能直接说明
	return 0;
}

但需要注意的是不能滥用auto,若无必要,少用auto。首先,auto的推断依赖于编译器,因此在某些很糟糕的情况下,是会推断失败的。其次,使用了auto之后,对于阅读这份代码的人来说增加了极大的困难。

除了以上两点之外,我们还需要注意两个地方。当想要声明的变量为引用或者指针的时候,必须要直截了当的表明声明的变量类型,下面这段代码举例。

#include<iostream>
int main(void)
{
	int a = 3;
	auto& b = a;//如果想要声明一个变量的引用,请务必在auto后面加上引用说明符
	auto* c = &a;//同理,在声明一个指向该变量的指针时,应该显式的加上地址说明符
	return 0;
}

六、命名空间的using声明

一般来说,想要使用标准头文件里面的东西,都得加上std::,这表示我们使用std命名空间中的变量。这样导致代码写的很慢,因此在非工程代码中,我们可以加上using namespace std;, 这样就不用写std::前缀了。但是,当写自己的头文件时,请务必不要加这句话,因为可能会产生名字冲突。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
make_heap、push_heap、pop_heap和sort_heap都是C++ STL库的算法,用于操作堆(heap)数据结构。 1. make_heap:将一个无序的区间转换为堆。函数原型如下: ``` template <class RandomAccessIterator> void make_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其,first和last分别为区间的起始和结束迭代器。make_heap函数会将[first,last)区间转换为堆。调用该函数后,该区间的最大元素会被放在第一个位置上。 2. push_heap:将一个元素添加到堆。函数原型如下: ``` template <class RandomAccessIterator> void push_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其,first和last分别为区间的起始和结束迭代器。当前,[first,last-1)已经是一个堆,push_heap函数将last-1位置的元素添加到堆,并且保证该堆仍然是一个堆。 3. pop_heap:将堆的最大元素移动到末尾。函数原型如下: ``` template <class RandomAccessIterator> void pop_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其,first和last分别为区间的起始和结束迭代器。当前,[first,last)已经是一个堆,pop_heap函数将该堆的最大元素(即first位置的元素)移动到last-1位置,并且保证[first,last-1)仍然是一个堆。 4. sort_heap:将一个堆排序。函数原型如下: ``` template <class RandomAccessIterator> void sort_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其,first和last分别为区间的起始和结束迭代器。当前,[first,last)已经是一个堆,sort_heap函数会将该堆转换为有序序列。 需要注意的是,这几个函数都要求操作的区间是一个随机访问迭代器(RandomAccessIterator)类型的迭代器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值