1. C++发展历史(了解)
1983年,贝尔实验室(Bell Labs)的Bjarne Stroustrup发明了C++。 C++在C语言的基础上进行了扩充和完善,是一种面向对象程序设计(OOP)语言。
Stroustrup说:“这个名字象征着源自于C语言变化的自然演进”。还处于发展完善阶段时被称为“new C”,之后被称为“C with Class”。C++被视为C语言的上层结构,1983年Rick Mascitti建议使用C++这个名字,就是源于C语言中的“++”操作符(变量自增)。而且在共同的命名约定中,使用“+”以表示增强的程序。
常用于系统开发,引擎开发、嵌入式开发等应用领域, 至今仍然是最受广大程序员喜爱的编程语言之一。
2. C++特点(熟悉)
- 在支持C的基础上,全面支持面向对象编程
- 编程领域广泛,功能强大
- 标准保持更新,目前常用的版本为ISO C++98标准、ISO C++11标准等。
- 为数不多的支持底层操作的面向对象语言。
- 在面向对象的语言中执行效率极高。
3. 面向对象核心术语(熟悉)
类、对象、封装 → 继承 → 多态
后三者被称为是面向对象的三大特性。
【思考】如果开车在路上爆胎了,应该怎么做?
面向过程的编程思想:
1. (我)边上停下来。
2. (我)后背箱拿出三角警示牌,放在路上。
3. (我)拿出备胎和千斤顶,顶起汽车,上备胎。
4. (我)收起所有工具,开到最近的修理厂。
面向对象的编程思想:
1. (我)边上停下来。
2. 打电话给对象来救援。
3. 对象来处理。
面向过程更加注重算法,因此语言的执行效率更高,更偏向于计算机的思维,只要按照预设的算法步骤来做,就能得到预计的结果,缺点是程序开发效率低。
面向对象更加注重调度,调度的是“对象(一系列由于某种联系聚集在一起的数据)”,更偏向于人类社会的思考方式,因此程序的开发效率高,缺点是执行效率低。
4. 开发环境
因为C++和Qt是连续课程,因此两门课程使用的开发环境都为Qt Creator 5.4,但是纯C++也可以使用其他的开发环境。
安装和配置环境的操作步骤如下:
1. 双击安装包
2. Qt Creator的安装程序非常简单,一直下一步即可,只需要注意一点:安装路径不能包含中文字符!!!
3. 安装完成后,默认直接启动Qt Creator。
4. 默认C++不支持中文输出,因此先进行中文设置:
5. 设置完成关闭Qt Creator,重新启动Qt Creator。
5. 新建项目
新建并运行一个项目的操作步骤如下:
1. 点击
2. 在弹出的窗口中,按照下图所示进行操作。
3. 在弹出的窗口中,输入项目名称和路径(不要包含任何中文字符!!!)。
4. 直接下一步,使用默认的编译器。
5. 在项目管理界面,直接点击完成。
6. 可以看到在项目中包含三个文件。
.pro 项目配置文件:可以在内部添加C++11的完整功能支持。
.pri文件:用不到,不用管。
main.cpp:C++的源代码主文件,内部包含主函数,即程序运行的入口。后续课程中主要在此文件中进行编程。
运行结果如下:
1. 引用 reference(重点)
1.1 基础使用
引用就是某个变量或常量的别名,对引用进行操作与操作原变量或常量完全相同。
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int& b = a; // b是a的引用
b++;
cout << a << " " << b << endl; // 2 2
cout << &a << " " << &b << endl; // 0x61fe88 0x61fe88
return 0;
}
1.2 特性
- 可以改变引用变量的值,但是不能再次成为其他变量的引用。
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int& b = a; // b是a的引用
int c = 8;
b = c; // 仅仅是赋值,b仍然是a的别名
cout << a << " " << b << " " << c << endl; // 8 8 8
cout << &a << endl; // 地址1
cout << &b << endl; // 地址1
cout << &c << endl; // 地址2
// &b = c; 错误
// int& b = c; 错误
return 0;
}
- 声明引用时,必须初始化。
- 声明引用时,初始化的值不能为NULL。
- 声明引用时,初始化的值可以是纯数值,但是此时引用需要使用const修饰,表示常引用,不允许修改引用值。
#include <iostream>
using namespace std;
int main()
{
// int& b = 123; 错误
const int& b = 123; // 常引用
cout << b << endl; // 123
// b++; 错误
return 0;
}
- 可以将变量引用的地址赋值给一个指针,此时指针指向的还是原来的变量。
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int &b = a;
int* c = &b;
cout << *c << endl; // 1
cout << c << " " << &a << endl; // 0x61fe84 0x61fe84
return 0;
}
- 可以建立指针变量的引用。
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int* b = &a;
int*& c = b; // c是b的引用
cout << c << " " << b << " " << endl; // 0x61fe88 0x61fe88
cout << *c << endl; // 1
return 0;
}
- 可以使用const修饰引用,表示常引用,此时不允许改变引用的值,但是可以改变原变量。
#include <iostream>
using namespace std;
int main()
{
int a = 1;
const int& b = a; // b是a的常引用
// b++; 错误
a++;
cout << b << endl; // 2
return 0;
}
1.3 引用参数
【思考题】写一个函数,功能为交换两个int变量参数的数值。
#include <iostream>
using namespace std;
/**
* @brief swap1 错误的交换方式
*/
void swap1(int a,int b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
cout << a << endl; // 2
cout << b << endl; // 1
}
/**
* @brief swap2 C的交换方式
* 指针比较复杂繁琐
*/
void swap2(int* a,int* b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
/**
* @brief swap3 使用引用参数传递,方便简洁
*/
void swap3(int& a,int& b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
int main()
{
int a = 1;
int b = 2;
swap1(a,b);
cout << a << endl; // 1
cout << b << endl; // 2
swap2(&a,&b);
cout << a << endl; // 2
cout << b << endl; // 1
swap3(a,b);
cout << a << endl; // 1
cout << b << endl; // 2
return 0;
}
使用引用作为函数参数时,不产生副本,可以使参数传递的效率提升,相比指针又更加简洁。
需要注意的是:
引用参数应该在内被const修饰的情况下,尽量使用const修饰,以达到引用参数的安全性。
#include <iostream>
using namespace std;
void show(const int& a,const int& b)
{
cout << a << endl;
cout << b << endl;
}
int main()
{
int a = 1;
int b = 2;
show(a,b);
cout << a << endl;
return 0;
}
2. C++窄化(了解)
#include <iostream>
using namespace std;
int main()
{
double a = 123234.8;
int b = (int)a; // C强制类型转换格式
int c(a); // C++格式
cout << b << endl;
cout << c << endl;
int d{a}; // C++11格式:可以给出数据窄化警告
cout << d << endl;
return 0;
}
3. 输入(熟悉)
在C++中使用cin进行键盘输入,与cout一样支持连续操作。
#include <iostream>
using namespace std;
int main()
{
int a;
double b;
string c; // C++的字符串类型
cout << "依次输入整型、浮点型与字符串类型:" << endl;
// 连续输入三个数据,分别给abc三个变量
cin >> a >> b >> c;
cout << "您输入的数据是:" << endl;
cout << a << endl;
cout << b << endl;
cout << c << endl;
return 0;
}
如果想输入空格,可以使用getline函数,可以一次获得一行的数据:
#include <iostream>
using namespace std;
int main()
{
string s;
cout << "请输入一行字符串,可以包含空格:" << endl;
getline(cin,s);
cout << "您输入的数据是:" << endl;
cout << s << endl;
return 0;
}
4. string 字符串类(掌握)
4.1 基础使用
string不是C++本身的基本数据类型,而是在C++标准库std中的一个字符串类。
在使用时需要引入头文件<string>,而不是<string.h>,string用于在绝大多数情况下代替char*,不必担心内存是否足够、字符串长度等问题。
string内部集成的函数可以完成绝大多数情况下字符串的操作。
string支持多种遍历方式:
- for循环
- for-each循环(C++11)
- 迭代器(后面讲)
#include <iostream>
using namespace std;
int main()
{
string s = "fsdhfjdhsjkf";
// size和length效果完全相同
cout << "字符串长度:" << s.size()
<< " " << s.length() << endl;
cout << "for循环遍历:" << endl;
for(int i = 0;i<s.size();i++)
{
cout << s[i] << " ";
}
cout << endl << "for-each遍历:" << endl;
for(char i:s)
cout << i << " ";
return 0;
}
4.2 取出元素
在C++中除了使用[]取出元素外,还可以使用at函数取出元素。
在绝大多数情况下,更推荐使用at函数取出元素,因为at函数更安全,但是[]性能更好。
#include <iostream>
using namespace std;
int main()
{
string s = "fsdhfjdhsjkf";
cout << s[1] << endl; // 's'
// at函数
cout << s.at(1) << endl; // 's'
// cout << s[-100] << endl; // '\0'或乱码
cout << s.at(-100) << endl; // 检测到越界则终止运行
cout << "主函数结束" << endl;
return 0;
}
4.3 字符串与数字转换
转换方式有很多种,在此使用的是字符串流。
整数 → 字符串
#include <iostream>
#include <sstream> // 头文件
using namespace std;
int main()
{
int i = 2323;
stringstream ss;
ss << i;
string s = ss.str();
cout << s << endl;
return 0;
}
字符串 → 整数
#include <iostream>
#include <sstream> // 头文件
using namespace std;
int main()
{
string s = "12345";
istringstream iss(s);
int i;
iss >> i;
cout << i << endl;
return 0;
}
5. 函数
5.1 内联函数 inline(掌握)
在C++中使用内联函数主要是为了取代C语言中宏定义的函数,内联函数在编译时,可以直接展开函数体到主函数中,因此提升了程序执行的效率,消除了普通的额外开销。
建议把代码长度较小(1-5行且不能包含复杂的控制语句)且频繁使用的函数定义为内联函数,内联函数只是给编译器的建议,编译器并不一定采纳。
只要在函数定义处使用inline关键字修饰函数,就可以把函数设置为内联函数。
#include <iostream>
using namespace std;
/**
* @brief test 内联函数
*/
inline void test(int a)
{
cout << "fdfd" << endl;
cout << ++a << endl;
}
void func(); // 函数声明
inline void func() // 函数定义
{
cout << "翻江倒海发的" << endl;
cout << "法国活动经费" << endl;
}
int main()
{
int a = 1;
test(a);
func();
return 0;
}
需要注意的是,后面要学习的成员函数默认都定义为内联函数。
5.2 函数重载 overload
C++中允许同一个函数名称定义多个函数,这就是函数重载。
函数签名是编译器区分不同函数的方式,包括以下几个组成部分:
- 函数名称
- 参数数量
- 参数类型
两个函数的签名不可以相同,即一个函数只有一个独一无二的签名。
当函数签名中函数名称相同,剩余条件不同时(参数数量或参数类型不同),就构成了函数重载。
#include <iostream>
using namespace std;
void test()
{
cout << "没有参数" << endl;
}
void test(int a)
{
cout << "一个int参数" << a << endl;
}
void test(int a,int b)
{
cout << "两个int参数" << a+b << endl;
}
void test(string a,string b)
{
cout << "两个string参数" << a+b << endl;
}
//int test(string a,string b) 错误
//{
// cout << "两个string参数" << a+b << endl;
// return 1;
//}
int main()
{
test(1,3);
test(54);
test();
test("aa","bb");
return 0;
}
后面学习的函数中,需要注意的是:构造函数可以重载,但是析构函数不能重载。
标签:std,cout,int,C++,Day1,c++,窄化,include,函数 From: https://blog.csdn.net/weixin_64032452/article/details/142531671