一、C++介绍
1、C++的特点
C++面向对象(Object)编程(OOP)
C++面向泛型编程(即模板)
C++静态类型语言
C++结构化教学语言
C++是编译型语言
C贴近硬件、底层,C++以C为基础,更快(适用于做性能好的东西)
C是面向过程(P)编程(POP)
2、C++的应用领域
3、编译型语言和解释型语言
4、C++运行
5、C++标准主要学习1.0、2.0版本
二、下载C++软件与准备工作
1、下载C++软件:
第一步:在官网下载IDE集成环境工具Visual Studio Community(社区版免费)
第二步:选择“C++桌面开发”选项
第三步:选择安装位置,点击“安装”,等待安装完成
第四步:点击“暂时跳过此项”
第五步:点击“创建新项目”
第六步:点击“空项目”,下一步
第七步:配置新项目,点击“创建”
第八步:创建新项目
第九步:案例:输出“Hello World”
2、准备工作
(1)注释:
一行注释//
多行注释/**/
(2)关闭控制台默认的提示语句——不改也挺好
点击工具----》选项---》调试--》调试停止时自动关闭控制台
注意:如上面更改之后,点击“本地调试器运行”,会有控制台一闪而过的问题,解决方案如下:
(3)点击编译---》获得obj目标文件;点击“生成”---》获得exe可执行文件(双击即可运行)
注意:“编译”在该文件右击中,“生成”在项目右击中
三、变量和数据类型
1、变量与标识符
- 变量就是存储空间,变量的值表示内存空间的值。
- 注意1:局部变量未初始化会出错(请注意是局部变量)。全局变量未初始化会默认值为0。
- 变量名一般使用小写字母。自定义类名一般使用大写字母开头。
- 标识符:给变量、函数、类起名。
- 标识符:字母、数字、下划线组成。
- 注意1:不能以下划线开头。
- 注意:标识符不能取名为关键字。
- 命名要求:
2、常量
①使用符号常量,即宏定义。C++不推荐使用
#define ZERO 0
注意:用宏定义时常量名为大写,这里宏定义的后面不用分号
②使用const限定符,const就叫限定符
const int Zero = 20;
这里的常量名可以全字母小写,也可以为了区分是常量首字母选择大写都可以。
注意:const修饰的对象一旦创建就不能更改,所以必须定义的时候就初始化。
3、基本数据类型
数据类型本质上就是告诉计算机这些数据占多少的内存空间。
(1)整型(算数类型和void):
整型案例:
#include<iostream>
using namespace std;
int main() {
short a = 20;
cout << "a = " << a << endl;
cout << "求a的长度的大小即字节的几种方式如下: " << endl;
cout << "a的长度为: " << sizeof(a) << endl; //a的长度为: 2
cout << "a的长度为: " << sizeof a << endl; //a的长度为: 2
cout << "short的长度为: " << sizeof(short) << endl; //short的长度为: 2
}
注意:
整型个数:short 两个字节,16位,有无符号整型数(0、正数)2^16,有符号整型数(正数、负数、0)-2^15~2^15-1。
内存中最小的数据单元为字节byte。即求长度为字节大小。
无符号:unsigned
导致数据溢出:程序不会报错,但是输出结果有问题,会从头开始继续找值输出。
(2)char字符类型(特殊的整型):
AscII:把字符编码成二进制的过程
字符: A a 0
AscII(十进制): 65 97 48
二进制:
注意:大写字母A的AscII码为65,加32,等于小写字母a的AscII为97
注意:字符为char定义的,没被定义的则是AscII,例如下面的案例。
字符与AscII案例(注意理解):⭐⭐⭐
//2、AscII的理解与应用
//A的AscII为65
char c = 65;
cout << "c = " << c << endl; //c = A
//注意:这里c为数字,因为最后 (c + 1)没有定义成char类型的,所以这里c为数字65
cout << "c + 1 =" << (c + 1) << endl; //c + 1 =66
注意:这里c2已经定义为char类型,所以这里的c为A,输出结果为字符B
char c2 = c + 1;
cout <<"c2 = " << c2 << endl; //c2 = B
//2、AscII的理解与应用二
char c ='A';
cout << "c = " << c << endl; //c = A
//注意:这里c为数字,因为最后 (c + 1)没有定义成char类型的,所以这里c为数字65
cout << "c + 1 = " << (c + 1) << endl; //c + 1 = 66 注意:这里c不为A,而是65
char c2 = c + 1;
//注意:这里c2已经定义为char类型,所以这里的c为A,输出结果为字符B
cout << "c2 = " << c2 << endl; //c2 = c + 1 =B
//总结:若为char定义了则为字符,例如A;否则为AscII码,例如65
(3)bool布尔类型(特殊的整型):
布尔案例(注意理解):⭐⭐⭐
输出的为1,而不是true
//3、布尔
bool b = true;
//请注意:输出的为 1,而不是true
cout <<"b = " << b << endl; //1
cout << "b的长度(字节)为: " << sizeof(b) << endl; //1
(4)浮点类型(包括科学计数法):
//浮点类型 用科学计数法时e/E都可以
float a = 3.45;
double b = 3.38E-23;
double c = 2.28E23;
double d = 1e3;
double e = 2.3e2;
cout <<"a = " << a << endl; //a = 3.45
cout <<"b = " << b << endl; //b = 3.38e-023
cout <<"c = " << c << endl; //c = 2.28e+023
cout <<"d = " << d << endl; //d= 1000
cout <<"e = " << e << endl; //e = 230
(5)字面值(字面值常量或显示定义的常量值):
①整型字面值:
②浮点型字面值:
③转义字符字面值:
④案例:
四、流程控制语句
1、if……[else……]:
2、switch(判断条件为固定的几个值,而不是范围):
switch案例:
3、while(条件)……:
while一定要有一个循环变量,并且循环变量要在循环中改变,让循环不成为死循环。
判断质数的while案例:
#include<iostream>
using namespace std;
//判断是否为质数
bool isPrime(int num){
int i = 2;
while(i < num)
{
if(num % i == 0)
{
return false;
}
++i;
}
return true;
}
int main() {
cout << "请输入一个数字判断它是否为质数:" << endl;
int num;
cin >> num;
if(isPrime(num))
cout << num << "是质数" << endl;
else
cout << num << "不是质数" << endl;
//输出1~100之间的质数:
for(int i = 2;i<100;i++)
{
if(isPrime(i))
cout << i << "\t";
}
}
4、do……while(条件)……:至少循环体执行一次
5、goto语句(谨慎使用,别造成死循环):无条件跳转到另一条语句当中
goto案例:
6、break:跳出循环,continue:跳出本次循环,return:跳出循环/返回……
7、额外:debug:双击打出断点,该断点行还没开始执行,也就是说到断点就停止了。
五、复合数据类型:
1、数组:
(1)数组的概念:相同数据类型的数据对象有序的序列,在内存中是连续存放的。序列{}
(2)数组的定义:数据类型 数组名[元素个数/数组长度];
注意:定义数组时元素个数一定要为常量,不能为变量。
(3)数组的初始化:
//数组初始化:必须用{}括起来的数值序列
int a3[4] = { 1, 2, 3, 4 };
//序列中初始化的元素个数会自动显示出来,所以数组元素个数可以为空
float a4[] = { 2.3, 1.3, 2.08 };
//初始化的元素个数少于数组元素个数,默认给前三位赋值,后面值为0
int a5[5] = { 1,2,3 };
//int a6[2] = { 1,2,3 }; //错误,初始化的元素个数多于数组元素个数
//int a7[4] = a3; //错误,不可由另一个数组对数组赋值
(4)数组的访问:数组名[元素下标/索引]
元素下标/索引:由0开始
(5)数组的遍历:
//数组的遍历:不可以遍历出下标,只遍历出元素的例子:
//注意:j为数组的每个元素,a为数组⭐⭐⭐
for (int j : a)
{
cout << j << endl;
}
//数组的访问
int a[] = { 1,2,3,4,5,6,7,8 };
cout << "a数组的内存空间的大小(字节)为:" << sizeof(a) << endl; //32字节
cout << "a数组每个内存空间的大小(字节)为:" << sizeof(a[0]) << endl; //4字节
int aSize = sizeof(a) / sizeof(a[0]);
cout << "a数组的长度(元素个数)为:" << aSize << endl; //8
cout << "a的地址为:" << a << endl;
//数组的遍历:可以遍历出下标
for (int i = 0; i < aSize; i++)
{
cout << "a[" << i << "] = " << a[i] << endl;
}
//数组的遍历:不可以遍历出下标,只遍历出元素
//注意:j为数组的每个元素,a为数组
for (int j : a)
{
cout << j << endl;
}
2、多维数组:
(1)多维数组的概念:
(2)二维数组的初始化:
注意:数组中的数据在内存中的存放位置是连续的,不是必须使用内嵌{}的,它本质就是存放在一行的,没有方针那样的放置。
二维数组:行数可以省略为空,列数必须写。
a[ ][3]={ ……}
(3)二维数组的访问与遍历:
//二维数组:
int a[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
cout << "数组的长度:" << sizeof(a)<< endl; //48 = 3*4*int(4)
cout << "数组每一行的长度:" << sizeof(a[0])<< endl; //16 = 4*int(4)
cout << "数组每一个元素的长度:" << sizeof(a[0][0])<< endl; //4 = 1*int(4)
//行数 = 数组长度 / 数组每一行的长度;
int rowCnt = sizeof(a) / sizeof(a[0]);
//列数 = 数组每一行的长度 / 数组每一个元素的长度;
int colCnt = sizeof(a[0]) / sizeof(a[0][0]);
cout << "行数:" << rowCnt << endl; //3
cout << "列数:" << colCnt << endl; //4
//二维数组的访问
cout << "a[1][2] = " << a[1][2] << endl;
a[0][1] = 5;
cout << "a[0][1] = " << a[0][1] << endl;
//二维数组的遍历
for(int i = 0; i < rowCnt; i++){
for(int j = 0; j < colCnt; j++){
cout << a[i][j] << "\t";
}
cout << endl;
}
//(C++新标准中可以使用,这里C++98不可以)泛型遍历二维数组:&引用, auto自动推断类型 ,num每一个元素
//for(auto& row : a){
// for(auto num : row){
// cout << num << "\t";
// }
// cout << endl;
//}
二维数组中求行数和列数的公式:
cout << "数组的长度:" << sizeof(a)<< endl; //48 = 3*4*int(4)
cout << "数组每一行的长度:" << sizeof(a[0])<< endl; //16 = 4*int(4)
cout << "数组每一个元素的长度:" << sizeof(a[0][0])<< endl; //4 = 1*int(4)
//行数 = 数组长度 / 数组每一行的长度;
int rowCnt = sizeof(a) / sizeof(a[0]);
//列数 = 数组每一行的长度 / 数组每一个元素的长度;
int colCnt = sizeof(a[0]) / sizeof(a[0][0]);
3、数组的简单排序算法(选择排序)⭐⭐⭐
//从小到大排序:
//选择排序:依次两两比较,最小值放到前面
int arr[] = { 5, 8, 6, 1, 2, 1, 4, 8, 9 };
int size = sizeof(arr) / sizeof(arr[0]);
//从第一个位置开始需要替换,一共替换size次
for (int i = 0; i < size; i++){
//前面的已经排好序了
for (int j = i + 1; j < size; j++){
if(arr[j] < arr[i]){
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
//c++98版本可以使用,这里不可以
//for(int num : arr){
// cout << num << "\t";
//}
for(int i = 0; i < size;i++){
cout << arr[i] << "\t";
}
cout << endl;
4、数组的简单排序算法(冒泡排序)⭐⭐⭐
//从小到大排序:
//冒泡排序:两两比较,每一轮找到最大值在最后,像冒泡一样
//每次要遍历的就会要少一个元素,末尾已经排好序了
int arr[] = { 5, 8, 6, 1, 2, 1, 4, 8, 9 };
int size = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < size; i++){
for (int j = 0;j < size - i - 1;j++){
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for(int i = 0; i < size;i++){
cout << arr[i] << "\t";
}
cout << endl;
5、模板类vector
对数组扩展的标准库的类型:vector(容器),容纳这若干个相同的数据类型。
与数组最大的区别就是,vector长度变化更灵活,数组长度要先固定。
(1)使用之前:先引用头文件和使用std命名空间
#include<vector>
using namespace std;
(2)初始化:
//默认初始化,就是一个空容器,里面还没有元素
vector<int> v1;
//列表初始化(拷贝初始化)
vector<char> v2 = {'a', 'b', 'c'};
//省略等号直接列表初始化
vector<char> v3{'a', 'b', 'c'};
//直接初始化
vector<short> v4(5); //表示5个元素
vector<short> v5(5, 100); //表示5个元素,并且有相同的值100
(3)访问:
vector和数组一样不可以越界访问,即超出长度访问
//访问:
cout << "v5[3] = " << v5[3] << endl; //100
v5[3] = 23;
cout << "v5[3] = " << v5[3] << endl; //23
//cout << "v5[8] = " << v5[8] << endl;长度超过,直接出错
//cout << "v1[3] = " << v1[0] << endl; 错误,因为v1还只是空容器
cout << "v4[3] = " << v4[3] << endl; //0
(4)遍历:
//v5的长度(元素个数) : v5.size()
cout << "v5的长度(元素个数)为:" << v5.size() << endl; //5//遍历
for (int i = 0; i < v5.size(); i++) {
cout << v5[i] << "\t";
}
cout << endl;// 遍历 软件Dev C++为C++98版本,不可以使用
// for (int num : v5) {
// cout << num << "\t" << endl;
// }
// cout << endl;
(5)往容器vector中添加元素
数组与容器vector的区别:
数组:在已经确定长度的时候,不能再添加新的元素,只能修改已有的元素。
容器vector:可以在已经确定长度的时候,再添加新的元素。
数组:固定长度的数组,运行速度快。
容器vector:不固定长度的数组,运行速度慢。
//往容器中添加元素:v5.push_back()
v5.push_back(56);
6、字符串
(1)使用之前引入<string>库和std命名空间:
引入<iostream>库可以使用string,但是最好还是再引入一下<string>库.
#include<string>
using namespace std;
(2)初始化
//默认初始化
string s1;
//拷贝初始化
string s2 = s1;
string s3 = "H"; //H
//直接初始化
string s4("world"); //world
string s5(8,'h'); //hhhhhhhh
cout << s3 << endl;
cout << s4 << endl;
cout << s5 << endl;
(3)访问字符:
//查找最后一个字符,其中用到了s4.size()求出字符串长度再减一
cout << s4[s4.size()-1] << endl;
//不要越界访问
(4)字符串拼接(+)
//string本身长度不固定,可以采用字符串拼接(+)
string str1 = "Helllo",str2("World");
//string对象str1 + string对象str2 = string对象str3
string str3 = str1 + str2;
cout << str3 << endl;
//string对象 + 字面值常量 = string对象str4
string str4 = str1 + "," + str2 + "!";
cout << str4 << endl;
//错误,两个字符串类型的字面值常量不能直接相加(拼接)
//字符串类型的字面值常量本质上是char类型的字符数组
//string str5 = "one" + "Two";
//cout << str5 << endl;
(5)字符串比较
字符串比较:一个字符一个字符进行比较。
7、字符数组(char[ ]:C语言风格的字符串)
注意:字符串字面值常量为字符数组类型。
注意:字符数组:要想成为字符串需要‘\0’,很麻烦,所以可以采用string。
8、键盘输入cin
cin >> //空白符(空格、回车换行符、制表符)作为结束标志,保存空白符。
getline(cin,字符串) //换行符直接配丢弃。
cin.get() //读取任意一个字符,其中在最后一行表示读取换行符。
9、简单读写文件
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
int main(){
ifstream input("input.txt");
ofstream output("output.txt");
//1.按照单词逐个从文件中读取,显示到屏幕上
string word;
while(input >> word){
cout << word << endl;
}
//2.逐行从文件中读取,显示到屏幕上
string line;
while(getline(input, line)){
cout << line << endl;
}
//3.逐个字符从文件中读取,显示到屏幕上
char ch;
while(input.get(ch)){
cout << ch << endl;
output << ch << endl;
}
}
10、结构体
结构体通常定义在主函数的外面。
初始化:
扩展:结构体数组
11、枚举
枚举:有限个常量值一一列举出来。
注意:可以在定义枚举的时候赋值整数给枚举量(如上面),但是整数直接给枚举类型赋值不可以(如下面,要强制类型转换)。
注意:可以修改默认枚举量,比如:11,之后的为在11基础上加一。
六、函数
函数的返回类型不能为数组或函数。
作用域:分为局部变量和全局变量。
生命周期:分为静态对象和自动对象。
局部静态对象:保留数据(记忆),只初始化一次。默认初始化为0。比如,static int a = 0;
自动对象:每次都重新创建和销毁。
函数声明:
①int func(int x);
②int func(int);