一、简介
学习 C++,主要是理解一些概念,不要深究某些写法。
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World" << endl;
return 0;
}
/*
1、#include <iostream>:
是告诉编译器我的程序加了这个头文件,可以使用其中的东西,头文件中有我们所需要的信息
2、using namespace std;告诉编译器使用 std 命名空间
3、main() 是一个程序的开始
4、int main()
{
-----
}
是写法,大括号写所需要的程序
5、cout << "Hello World" << endl;
在窗口输出"Hello World", endl 表示换行
6、return 0;程序结束,返回值为零,再不需要返回值的数据类型不需要写这句话,例如void
*/
二、注释
作用:在自己所写的代码中添加解释,以供自己后续查阅或者其他程序员学习
1、单行注释:// 描述信息
一般放在一行代码的上方,或者一条语句的末尾,对该行代码说明
2、多行注释: /* 描述信息 */
一般放在一段代码的上方,对该段代码做整体说明
#include<iostream>
using namespace std;
int main()
{
/*
变量创建的语法:数据类型 变量名 =变量初始值
*/
int a = 10;//输出 a
cout << "a=" << a << endl;
system("pause");
return 0;
}
三、变量
作用:给一段指定的内存空间起名,方便操作和管理这段内存
语法:数据类型 变量名 = 初始值;
示例:int c = 1925;
注意:C++在创建变量时,必须给变量一个初始值,否则会报错
#include<iostream>
using namespace std;
int main()
{
int c = 1925;
cout << "c=" << c << endl;
system("pause");
return 0;
}
四、常量
作用:用于记录程序中不可更改的数据
C++定义常量的两种方式:
1、#define 宏常量: #define 常量名 常量值
通常在文件上方定义,表示一个常量
2、const 修饰的变量: const 数据类型 常量名 = 常量值
通常在变量定义前加关键字const,修饰该变量为常量,不可修改
#include<iostream>
using namespace std;
//常量的定义方式
//#define 宏常量
//const 修饰的变量
//1、#define 宏常量
#define Day 7
int main()
{
//输出一周总共有几天 文字要打双引号不然报错显示未定义标识符
cout << "一周总共有" << Day << "天" << endl;
//2、const 修饰的变量
const int mouth = 12;
//mouth = 24;//错误,const修饰的变量也称为常量
cout << "一年总共有" << mouth << "个月份" << endl;
system("pause");
return 0;
}
五、关键字
作用:关键字是C++中预先保留的单词(标识符)
在定义变量或者常量时候,不要用关键字
C++关键字如下:
#include<iostream>
using namespace std;
int main1()
{
//创建变量:数据类型 变量名称 = 变量初始值
//不要用关键字给变量或者常量起名称
//int int = 10; 错误,第二个int是个关键字,不可以作为变量的名称
system("pause");
return 0;
}
六、标识符
定义:是程序中所使用的对象(变量、常量等)的名字
#include<iostream>
using namespace std;
//标识符(即变量/常量名)的命名规则
int main()
{
//1、标识符不能是关键字
//int int = 10;这样命名是错误的,int是关键字(数据类型)
//2、标识符是由字母,下划线,数字组成的
int abc = 10;
int abc123 = 20;
int abc123__ = 30;
//3、标识符的第一个字符只能是字母或者下划线
//int 1abc = 40; 错误,第一个字符为数字1
//4、标识符是区分大小写的
int aaa = 100;
cout << aaa << endl;
//cout << AAA << endl; 字母aaa和AAA区分大小写
system("pause");
return 0;
}
七、运算符
1、算术运算符
作用:处理四则运算
#include<iostream>
using namespace std;
int main()
{
/*
1、加减乘除
*/
int a1 = 10;
int b1 = 3;
cout << a1 + b1 << endl;
cout << a1 - b1 << endl;
cout << a1 * b1 << endl;
cout << a1 / b1 << endl;//两个整数相除结果依然是整数
int a2 = 10;
int b2 = 20;
cout << a2 / b2 << endl;//运行结果为零,不显示小数
int a3 = 10;
int b3 = 0;
//cout << a3 / b3 << endl;//错误,除数不可以为零
double a4 = 0.5;
double b4 = 0.25;
cout << a4 / b4 << endl;//小数可以相除,也可以得出小数
/*
2、取模即取余数
*/
int a5 = 19;
int b5 = 3;
cout << a5 % b5 << endl;//输出结果为1
int a6 = 10;
int b6 = 20;
cout << a6 % b6 << endl;//输出结果为0
int a7 = 10;
int b7 = 0;
//cout << a7 % b7 << endl;//取模运算时,除数也不能为零
double a8 = 3.14;
double b8 = 1.1;
//cout << a8 % b8 << endl;//两个小数不可以取模
/*
3、后置递增
*/
int a9 = 10;
a9++; //等价于a9 = a9 + 1
cout << a9 << endl; // 输出a9为11
/*
4、前置递增
*/
int b9 = 10;
++b9;
cout << b9 << endl; // 输出b9为11
//区别
//前置递增先对变量进行++,再计算表达式
int a10 = 10;
int b10 = ++a10 * 10;
cout << a10 << endl;//输出a2为11
cout << b10 << endl;//输出b2为110
//后置递增先计算表达式,后对变量进行++
int a11 = 10;
int b11 = a11++ * 10;
cout << a11 << endl;//输出a3为11
cout << b11 << endl;//输出b3为100
system("pause");
return 0;
}
2、赋值运算符
作用:将表达式的值赋给变量
#include<iostream>
using namespace std;
int main()
{
// =
int a1 = 10;
a1 = 100;
cout << "a1 = " << a1 << endl;//输出a1为100
// +=
int a2 = 10;
a2 += 4; // 即 a2 = a2 + 4;
cout << "a2 = " << a2 << endl;//输出a2为14
// -=
int a3 = 10;
a3 -= 4; // 即 a3 = a3 - 4;
cout << "a3 = " << a3 << endl;//输出a3为6
// *=
int a4 = 10;
a4 *= 4; // 即 a4 = a4 * 4;
cout << "a4 = " << a4 << endl;//输出a4为40
// /=
int a5 = 10;
a5 /= 2; // 即 a5 = a5 / 2;
cout << "a5 = " << a5 << endl;//输出a5为5
// %=
int a6 = 10;
a6 %= 2; // 即 a6 = a6 % 2;
cout << "a6 = " << a6 << endl;//输出a6为0
system("pause");
return 0;
}
3、比较运算符
作用:表达式的比较,并返回一个真值或假值
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int b = 20;
cout << (a == b) << endl; //输出结果为0
cout << (a != b) << endl; //输出结果为1
cout << (a > b) << endl; //输出结果为0
cout << (a < b) << endl; //输出结果为1
cout << (a >= b) << endl; //输出结果为0
cout << (a <= b) << endl; //输出结果为1
//"!=" 的意思是"不等于"
//c++里边运算符有优先级这一说法
//( )是做一个优先级,先输出( )里边的再输出endl拼接换行
system("pause");
return 0;
}
4、逻辑运算符
作用:根据表达式的值返回真值或假值
4.1、" !"
#include<iostream>
using namespace std;
int main()
{
//"!"即"非",如果a为假,则!a为真; 如果a为真,则!a为假。
int a = 10;
cout << !a << endl; // 在C++里,非0都为真,!a即为假,输出0
cout << !!a << endl; // 两个!!为真输出1
system("pause");
return 0;
}
4.2、" && "
#include<iostream>
using namespace std;
int main()
{
//"&&"即"与",a && b,如果a和b都为真,则结果为真,否则为假。
int a1 = 10;
int b1 = 10;
cout << (a1 && b1) << endl;//输出结果为1
int a2 = 10;
int b2 = 0;
cout << (a2 && b2) << endl;//输出结果为0
int a3 = 0;
int b3 = 0;
cout << (a3 && b3) << endl;//输出结果为0
system("pause");
return 0;
}
4.3、" || "
#include<iostream>
using namespace std;
int main()
{
//"||"即"或",a || b,如果a和b有一个为真,则结果为真,二者都为假时,结果为假。
int a1 = 10;
int b1 = 10;
cout << (a1 || b1) << endl;//输出结果为1
int a2 = 10;
int b2 = 0;
cout << (a2 || b2) << endl;//输出结果为1
int a3 = 0;
int b3 = 0;
cout << (a3 || b3) << endl;//输出结果为0
system("pause");
return 0;
}
5、 三目运算符
语法:表达式1 ? 表达式2 :表达式3
注释: 如果表达式1的值为真,执行表达式2,并返回表达式2的结果;
如果表达式1的值为假,执行表达式3,并返回表达式3的结果。
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int b = 20;
int c = 0;
c = a > b ? a : b;
cout << "c = " << c << endl;
//0 = 10 > 20 为假,执行表达式3,输出为20
//C++中三目运算符返回的是变量,可以继续赋值
(a > b ? a : b) = 100;
cout << "a = " << a << endl;//a=10
cout << "b = " << b << endl;//b=100
cout << "c = " << c << endl;//c=0
system("pause");
return 0;
}
八、数据类型
C++规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存
1、整型
作用:整型变量表示的是整数类型的数据
C++中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同:
#include<iostream>
using namespace std;
int main()
{
//1、短整形,占用空间:2字节
short num1 = 10;
//2、整形,占用空间:4字节
int num2 = 10;
//3、长整型,占用空间:Windows为4字节,Linux为4字节(32位),8字节(64位)
long num3 = 10;
//4、长长整形,占用空间:8字节
long long num4 = 10;
cout << "num1=" << num1 << endl;
cout << "num2=" << num2 << endl;
cout << "num3=" << num3 << endl;
cout << "num4=" << num4 << endl;
system("pause");
return 0;
}
2、sizeof 关键字
作用:利用 sizeof 关键字可以统计数据类型所占内存大小
语法: sizeof(数据类型) 或者 sizeof(变量名)
#include<iostream>
using namespace std;
int main()
{
//整形: short(2) int(4) long(4) long long(8)
//可以利用sizeof关键字求出数据类型所占用内存空间的大小
//语法:sizeof(数据类型/变量名称)
short num1 = 10;
cout << "short所占用的内存空间为" << sizeof(short) << endl;
int num2 = 10;
cout << "int所占用的内存空间为" << sizeof(num2) << endl;
long num3 = 10;
cout << "long所占用的内存空间为" << sizeof(long) << endl;
long long num4 = 10;
cout << "long long 所占用的内存空间为" << sizeof(num4) << endl;
system("pause");
return 0;
}
3、实型(浮点型)
作用:用于表示小数
浮点型变量分为两种:float 和 double
#include<iostream>
using namespace std;
int main()
{
//1、单精度 float
//2、双精度 double
//默认情况下:输出一个小数会显示 6 位有效数字
float fl1 = 3.1415926f;//不加 f 默认为双精度,要转换一步,加 f 直接显示单精度
cout << "fl1=" << fl1 << endl;
double d1 = 3.1415926;
cout << "d1=" << d1 << endl;
//统计 float 和 double 占用内存空间
//1、单精度 float;占用空间:4字节;有效数字范围:7位
//2、双精度double;占用空间:8字节;有效数字范围:15~16位
cout << "float所占用内存空间为:" << sizeof(float) << endl;
cout << "double所占用内存空间为:" << sizeof(double) << endl;
//科学计数法
//科学计数法 e 后边为正数表示10的几次方,e后边为负数表示0.1的几次方
float f2 = 3e2;//3*10~2
cout << "f2=" << f2 << endl;
float f3 = 3e-2;//3*0.1~2
cout << "f3=" << f3 << endl;
system("pause");
return 0;
}
4、字符型
作用:字符型变量用于代表单个字符
语法:char ch = 'a'
#include<iostream>
using namespace std;
int main()
{
//1、字符型变量的创建方式
char zifu = 'a';
cout << zifu << endl;
//2、字符型变量所占的内存空间大小,字符型变量只占用 1 个字节。
cout << "char字符型变量所占内存" << sizeof(char) << endl;
//3、字符型变量的注意点
//char zifu1 = "b";//创建字符型变量时,字符要用单引号,双引号不行
//char zifu2 = 'abcdefg';//创建字符型变量时单引号内只能是一个字符
//4、字符型变量对应的ASCII编码
cout << (int)ch << endl;//int:整形,将字符型强转为整形
system("pause");
return 0;
}
5、字符串型
作用:用于表示一串字符,例如"qwerdf"就为一个字符串
#include<iostream>
#include<string>
using namespace std;
int main()
{
/*
1、C语言中字符串
语法:char 变量名 [ ] = "字符串值"
注意:等号后面要用双引号包含起来字符串
*/
char zfc[] = "Hohai 1925";
cout << zfc << endl;
/*
2、C++风格字符串
语法:string 变量名 = "字符串值"
注意:必须包含一个头文件 #include<string>
*/
string zfc1 = "Hohai 1925";
cout << zfc1 << endl;
system("pause");
return 0;
}
6、布尔类型 bool
作用:布尔数据类型代表 true--1 或 false--0 的值
#include<iostream>
using namespace std;
int main()
{
//定义bool类型,通过程序运行输出1或0
bool flag;
cin>>a;
cin>>b;
flag = a < b;
cout << "flag=" << flag <<endl;
//创建bool数据类型,直接对其赋值真假
bool flag1 = true;
bool flag2 = false;
bool flag3 = 1;
bool flag4 = 0;
cout << flag1 << endl;
cout << flag2 << endl;
cout << flag3 << endl;
cout << flag4 << endl;
//2、查看bool类型所占内存空间,bool类型占1个字节大小
cout << "bool所占内存空间为" << sizeof(bool) << endl;
system("pause");
return 0;
}
7、数据的输入
作用:用于从键盘获取数据
语法: cin >> 变量
#include<iostream>
using namespace std;
#include<string>
int main()
{
//1、整型
int a = 10;
cout <<"请给整型变量a赋值"<< endl;
cin>>a;
cout << "整型变量a=" << a << endl;
//2、浮点型
float f = 3.14f;
cout << "请给浮点型变量f赋值" << endl;
cin >> f;
cout << "浮点型变量f=" << f << endl;
//3、字符型
char ch = 'd';
cout << "请给字符型变量ch赋值" << endl;
cin >> ch;
cout << "字符型变量ch=" << ch << endl;
//4、字符串型
string str = "hello";//字符串型必须包含头文件
cout << "请给字符串str赋值" << endl;
cin >> str;
cout << "字符串型变量str=" << str << endl;
//5、布尔类型
bool flag = false;
cout << "请给布尔类型flag赋值" << endl;
cin >> flag;//布尔类型只要是输入非0值都代表真,输出为1即true
cout << "布尔类型flag=" << flag << endl;
system("pause");
return 0;
}
九、数组
定义:就是在一段连续的空间里面存放了相同类型的数据元素的容器
注意1:数组中的每个数据元素都是相同的数据类型
注意2:数组是由连续的内存位置组成的,是定长的,不可改变
1、一维数组
1.1、一维数组定义
语法:
1、数据类型 数组名 [ 数组长度 ];
2、数据类型 数组名 [ 数组长度 ] = { 值1,值2 ...};
3、数据类型 数组名 [ ] = { 值1,值2 ...};
#include<iostream>
using namespace std;
int main()
{
//1、数据类型 数组名[元素个数];
int array1 [5];
char array2 [5];
float array3 [5];
double array4 [5];
//赋值
//0代表第一个数据,1代表第二个数据,以此类推;即数组中下标是从0开始索引
array1[0] = 100;
array1[1] = 99;
array1[2] = 85;
//输出
cout << array1[0] << endl;
cout << array1[1] << endl;
cout << array1[2] << endl;
//数据类型 数组名[元素个数] = {值1,值2 ,值3 ...};
int array5[5] = { 1,2,3 };
cout << array5[3] << endl;//输出0
cout << array5[4] << endl;//输出0
//数组大小大于初始数,后续用0补齐
//2、数据类型 数组名[] = {值1,值2 ,值3 ...};
int array6[] = { 1,2,3,4,5 };
system("pause");
return 0;
}
1.2、一维数组名称的用途
1、可以统计整个数组在内存中的长度
2、可以获取数组在内存中的首地址
#include<iostream>
using namespace std;
int main()
{
//1、可以获取整个数组占用内存空间大小
int array[5] = { 1,2,3,4,5 };
cout << "整个数组所占内存空间为: " << sizeof(array) << endl;
cout << "每个元素所占内存空间为: " << sizeof(array[0]) << endl;
cout << "数组的元素个数为: " << sizeof(array) / sizeof(array[0]) << endl;
//2、可以通过数组名获取到数组首地址
//array[0]表示的数组中第一个数字,在此段代码中为1,要想看一个数字的地址要加一个取址符&
cout << "数组首地址为: " << (int)array << endl;
cout << "数组中第一个元素地址为: " << (int)&array[0] << endl;
cout << "数组中第二个元素地址为: " << (int)&array[1] << endl;
//array = 10; 错误,数组名是常量,因此不可以赋值
system("pause");
return 0;
}
2、二维数组
二维数组就是在一维数组上多加一个维度:即既有行又有列
2.1、二维数组定义方式
语法:
1、数据类型 数组名 [ 行数 ] [ 列数 ];
2、数据类型 数组名 [ 行数 ] [ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
3、数据类型 数组名 [ 行数 ] [ 列数 ] = { 数据1,数据2,数据3,数据4};
#include<iostream>
using namespace std;
int main()
{
//数组类型 数组名 [行数][列数];
int array1[2][3];
array1[0][0] = 1;
array1[0][1] = 2;
array1[0][2] = 3;
array1[1][0] = 4;
array1[1][1] = 5;
array1[1][2] = 6;
//数据类型 数组名[行数][列数] = { {数据1,数据2 } ,{数据3,数据4 } };
int array2[2][3] =
{
{1,2,3},
{4,5,6}
};
system("pause");
return 0;
}
2.2、二维数组名称的用途
作用:查看二维数组所占内存空间及获取二维数组首地址
#include<iostream>
using namespace std;
int main()
{
//创建一个二维数组
int array[2][3] =
{
{1,2,3},
{4,5,6}
};
//1、可以查看内存空间大小
cout << "二维数组大小: " << sizeof(array) << endl;
cout << "二维数组一行大小: " << sizeof(array[0]) << endl;
cout << "二维数组元素大小: " << sizeof(array[0][0]) << endl;
//除法计算行数
cout << "二维数组行数为: " << sizeof(array) / sizeof(array[0]) << endl;
cout << "二维数组列数为: " << sizeof(array[0]) / sizeof(array[0][0]) << endl;
//2、可以查看二维数组首地址
cout << "二维数组首地址:" << (int)array << endl;
cout << "二维数组第一行地址:" << (int)array[0] << endl;
cout << "二维数组第二行地址:" << (int)array[1] << endl;
//arr[0][0]是一个数字,要想看一个数字的地址要加一个取址符&
cout << "二维数组第一个元素地址:" << (int)&array[0][0] << endl;
cout << "二维数组第二个元素地址:" << (int)&array[0][1] << endl;
system("pause");
return 0;
}
十、判断
1、if 语句
if 语句:即执行满足 if 后()内条件的语句
1.1、单行 if 语句
语法:if (条件)
{
条件满足执行的程序;
}
#include<iostream>
using namespace std;
int main()
{
//输入一个数字,如果数字大于10,视为正确,输出“正确”
int number;
cout << "请输入一个数字:" << endl;
cin >> number;
cout << "您输入的数字为: " << number << endl;
if (number > 10)
{
cout << "正确" << endl;
}
system("pause");
return 0;
}
1.2、多行 if 语句
语法: if (条件)
{
条件满足执行的程序;
}
else
{
条件不满足执行的程序;
}
#include<iostream>
using namespace std;
int main()
{
//输入一个数字,如果数字大于10,视为正确,输出“正确”
//如果不大于10,视为错误,输出“错误”
int number;
cout << "请输入一个数字:" << endl;
cin >> number;
cout << "您输入的数字为: " << number << endl;
if (number > 10)
{
cout << "正确" << endl;
}
else
{
cout << "错误" << endl;
}
system("pause");
return 0;
}
1.3、多条件 if 语句
语法:if (条件1)
{
条件1满足执行的程序;
}
else if (条件2)
{
条件2满足执行的程序;
}
...
...
...
else
{
都不满足执行的程序;
}
#include<iostream>
using namespace std;
int main()
{
//输入一个数字,如果数字大于80,视为优秀,输出“优秀”
//如果大于70,视为良好,输出“良好”
//如果大于60,视为合格,输出“合格”
//其他情况,视为不合格,输出“不合格”
int number;
cout << "请输入一个数字:" << endl;
cin >> number;
cout << "您输入的数字为: " << number << endl;
if (number > 80)
{
cout << "优秀" << endl;
}
else if (number > 70)
{
cout << "良好" << endl;
}
else if (number > 60)
{
cout << "合格" << endl;
}
else
{
cout << "不合格" << endl;
}
system("pause");
return 0;
}
1.4、嵌套 if 语句
使用:在 if 语句中,可以嵌套使用 if 语句,达到更精确的条件判断
#include<iostream>
using namespace std;
int main()
{
//输入一个数字
//如果大于60,视为合格,输出“合格”
//60~70,合格;70~80,良好;80~90;优秀;90以上,完美
//其他情况,视为不合格,输出“不合格”
int number;
cout << "请输入一个数字:" << endl;
cin >> number;
cout << "您输入的数字为: " << number << endl;
if (number > 60)
{
cout << "合格" << endl;
if (number > 90)
{
cout << "完美" << endl;
}
else if (number > 80)
{
cout << "优秀" << endl;
}
else if (number > 70)
{
cout << "良好" << endl;
}
}
else
{
cout << "不合格" << endl;
}
system("pause");
return 0;
}
1.5、if 中的 continue
continue 语句用于循环语句中,作用是不执行循环体剩余部分,直接进行下次循环。常见的就是与 if 连用。
#include<iostream>
using namespace std;
int main()
{
int i;
for (i = 0; i < 10; i++)
{
if (i % 2 == 0) continue;//如果i为偶数 调用continue;
cout << " i= " << i << endl;//输出结果为1、3、5、7、9
//i为偶数就不执行if下面的语句,跳出当前循环,出去继续执行for循环
}
system("pause");
return 0;
}
2、switch语句
作用:在编程中,常常需要把表达式和一组值相比较,从中找到匹配项,执行相应的语句。对于整型的表达式值和选择项来说,switch 语句比 if 更易读,执行速度往往更快。
//语法:
switch(表达式)
{
case 结果1:执行语句;break;
case 结果2:执行语句;break;
...
default:执行语句;break;
注释:
switch语句中表达式类型只能是整型或者字符型
case里如果没有break,那么程序会一直向下执行
与 if 语句比,对于多条件判断时,switch的执行效率高,缺点是switch不可以判断区间
}
#include<iostream>
using namespace std;
int main()
{
//请给颜值打分
//10 非常漂亮
//9、8 漂亮
//7、6、5 一般
//5分以下 普通
int score = 0;
cout << "请给颜值打分" << endl;
cin >> score;
switch (score)
{
case 10:
cout << "非常漂亮" << endl;
break;
case 9:
case 8:
cout << "漂亮" << endl;
break;
case 7:
case 6:
case 5:
cout << "一般" << endl;
break;
default:
cout << "普通" << endl;
break;
}
system("pause");
return 0;
}
十一、循环
1、while 循环语句
语法: while (循环条件)
{
循环语句;
}
注释:只要循环条件的结果为真,就执行循环语句;即只有循环条件为假才会停止循环
#include<iostream>
using namespace std;
int main()
{
int number =5;
while (number < 10)
{
cout << "number = " << number << endl;
num++;
}
system("pause");
return 0;
}
2、do...while循环语句
作用: 满足循环条件,执行循环语句
语法: do{循环语句} while(循环条件);
注意: 与while的区别在于do...while会先执行一次循环语句,再判断循环条件
#include<iostream>
using namespace std;
int main()
{
int num = 0;
do
{
cout << num << endl;
num++;
} while (num < 10);
system("pause");
return 0;
}
3、for 循环语句
语法: for ( 起始表达式;条件表达式;末尾循环体 )
{
循环语句;
}
#include<iostream>
using namespace std;
int main()
{
for (int i = 1; i < 10; i++)
{
cout << i << endl;
}
system("pause");
return 0;
}
4、for 嵌套循环
作用:在循环体中再嵌套一层循环,来实现某些目的
#include<iostream>
using namespace std;
int main()
{
//外循环执行1次,内循环执行1次
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
cout << "1" << " ";
}
cout << endl;
}
system("pause");
return 0;
}
十二、函数
作用:将一段经常使用的代码封装起来,减少重复代码,方便以后进行调用
1、函数的定义
语法:
返回值类型 函数名 (参数列表)
{
函数体语句;
return表达式;
}
1、返回值类型 :一个函数可以返回一个值,在函数定义中
2、函数名:给函数起个名称
3、参数列表:使用该函数时,传入的数据
4、函数体语句:花括号内的代码,函数内需要执行的语句
5、return表达式: 和返回值类型挂钩,函数执行完后,返回相应的数据
示例:
int add(int number1, int number2)
{
int sum = number1 + number2;
cout << "sum=" << sum << endl;
return sum;
}
void add()
{
cout << "Hello Word" << endl;
}
2、函数的调用
语法:函数名称 ( 参数/无参数 );
#include<iostream>
using namespace std;
//函数定义
//定义的num1,num2没有真实数据
//定义中的num1,num2称为形式参数,简称形参
int add(int num1, int num2)
{
int sum = num1 + num2;
return sum;
}
int main()
{
int a;
int b;
int sumber;
//函数调用语法:函数名称(参数)
//调用时的a,b称为实际参数,简称实参
//当调用函数时,实参的值会传递给形参
//所谓值传递,就是函数调用时实参将数值传入给形参
//值传递时,如果形参发生改变,并不会影响实参
a = 100;
b = 100;
sumber = add(a, b);
cout << "sumber = " << sumber << endl;
system("pause");
return 0;
}
3、函数的声明
作用:在 .h 或者 .cpp 中告诉编译器函数名称及如何调用函数
注释:函数的声明可以多次,但是函数的定义只能有一次
#include<iostream>
using namespace std;
//函数声明
//数据类型 函数名;
int add(int num1, int num2);
//函数定义
int add(int num1, int num2)
{
int sum = num1 + num2;
return sum;
}
int main()
{
int a;
int b;
int sumber;
a = 100;
b = 100;
//函数调用
sumber = add(a, b);
cout << "sumber = " << sumber << endl;
system("pause");
return 0;
}
4、函数的写法
1、在 .h 中进行函数声明
2、在 .cpp 中进行函数定义
3、在 main 中进行函数调用输出结果
十三、指针
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。
也就是说指针变量所存的内容就是内存的地址编号。
1、指针定义
#include<iostream>
using namespace std;
int main()
{
//定义一个变量a
int a = 10;
//定义指针变量
//语法:数据类型 * 变量名 ;
int *p = &a;
cout << " a= " << a << endl;
cout << " &a = " << &a << endl;
cout << " p = " << p << endl;
cout << " *p = " << *p << endl;
/*
输出结果
a = 10;
&a = 000000437C2FFA14;//变量a的内存地址编号
p = 000000437C2FFA14;//定义的指针变量p所存的内容就是内存的地址编号
*p = 10;//*pi 即:pi所指的地址的内容,即在000000437C2FFA14这个地址存储了10这个数据
*/
system("pause");
return 0;
}
注释:指针变量和普通变量的区别:
(1)普通变量存放的是数据,指针变量存放的是地址
(2)指针变量可以通过" * "操作符,操作指针变量指向的内存空间,这个过程称为解引用
(3)" * " 解引用,通过对指针变量解引用,可以操作指针指向的内存
2、二级指针
二级指针,是一种 “指向指针” 的 “指针” 。可以通过二级指针间接访问数据和改变一级指针的指向问题。
#include<iostream>
using namespace std;
int main()
{
//定义一个变量a
int a = 10;
cout << " a= " << a << endl;//输出 a=10
cout << " &a = " << &a << endl;//输出 &a = 000000437C2FFA14
int *p = &a;
cout << " p = " << p << endl; //输出 p = 000000437C2FFA14
cout << " *p = " << *p << endl;//输出 *p = 10
//指向指针的指针,*(*变量名)
//* 操作符具有从右向左的结合性
int * *pi = &p;
//cout << " pi = " << pi << endl;//输出 pi = 00000072C24FF5F8
cout << " *pi = " << *pi << endl;//输出 *pi = 00000072C24FF5D4
cout << " **pi = " << **pi <<endl;//输出 **pi = 10
system("pause");
return 0;
}
3、NULL 指针
#include <iostream>
using namespace std;
int main ()
{
//指针变量 p 指向内存地址编号为 0 的空间
int *p = NULL;
cout << " p的值是 " << p;//p=0
//cout << " *p= " << *p ;//报错
return 0;
}
4、const 修饰指针
#include<iostream>
using namespace std;
int main()
{
int a = 1;
int b = 1;
//const修饰的是指针 常量指针
//指针指向可以改,指针指向的值不可以更改
const int * p1 = &a;
p1 = &b; //正确
//*p1 = 100; 报错
//const修饰的是常量 指针常量
//指针指向不可以改,指针指向的值可以更改
int * const p2 = &a;
//p2 = &b; //错误
*p2 = 100; //正确
//const既修饰指针又修饰常量
const int * const p3 = &a;
//p3 = &b; //错误
//*p3 = 100; //错误
system("pause");
return 0;
}
5、指针和数组
指针和数组是密切相关的,可以利用指针访问数组中元素
#include<iostream>
using namespace std;
int main()
{
//利用指针访问数组中的元素
int array[5] = { 1921,1925,1949,1999,2008 };
cout << "数组中第一个元素: " << array[0] << endl;
int *p = array; //指向数组的指针,array就是数组首地址
cout << "指针访问数组中第一个元素: " << *p << endl;
p++;//让指针向后偏移4个字节,因为整型int为4个字节
cout << "指针访问数组中第二个元素: " << *p << endl;
int *pi = array;
for (int i = 0; i < 5; i++)
{
//利用指针访问数组中的每一个元素
cout << *pi << endl;
pi++;
}
system("pause");
return 0;
}
6、指针数组
定义:指针数组的本质是数组,数组中每一个成员是一个指针。
#include <iostream>
using namespace std;
int main()
{
//1、定义一个5个整数的数组
int array1[5]={ 1921,1925,1949,1999,2008 };
//2、然后是指向整数的指针数组的声明:
//语法:数据类型 * 数组名 [i];
int *array2[5];
//将 “指针数组中的每一个指针” 指向 1 中定义的数组中的每个地址编号
for (int i = 0; i < 5; i++)
{
array2[i] = &array1[i];
}
//输出指针数组中的每个成员指针指向地址编号对应的内容
for (int i = 0; i < 5; i++)
{
cout << *array2[i] << endl;
}
system("pause");
return 0;
}
#include <iostream>
using namespace std;
int main()
{
string array1[5] = { "ab","bc","cd","de","ef"};
string *array2[5];
for (int i = 0; i < 5; i++)
{
array2[i] = &array1[i];
}
for (int i = 0; i < 5; i++)
{
cout << *array2[i] << endl;
}
system("pause");
return 0;
}
7、指针和函数
在C++中允许传递指针给函数,在此之前需要声明函数参数为指针类型
#include <iostream>
using namespace std;
//函数声明,一般在.h文件中
void GS(unsigned long *p);
//函数定义,一般在.cpp文件中
void GS(unsigned long *p)
{
//获取当前的秒数
// time( NULL );获取系统时间,单位为秒;
*p = time( NULL );
}
int main ()
{
unsigned long time;
GS( &time );
// 输出实际值
cout << " 当前秒数= " << time << endl;
system("pause");
return 0;
}
十四、结构体
1、结构体简介
C++中有很多不同的数据类型,例如整形,字符串型等。而有时候我们需要一些并不是系统自带的数据类型来定义某些数据,这就是结构体的概念。结构体属于用户自定义的数据类型,用来存储不同的数据类型。
2、结构体定义与使用
语法:struct 结构体名 { 结构体成员列表 };
创建结构体变量的三种方式:
1、struct 结构体名 变量名;
2、struct 结构体名 变量名 = { 成员1值 , 成员2值...};
3、定义结构体时顺便创建变量;
#include<iostream>
#include<string>
using namespace std;
//结构体定义,定义结构体时的关键字是struct,不可省略
struct student
{
//结构体成员列表
string name; //姓名
int age; //年龄
int score; //分数
}stu3; //结构体变量创建方式3
int main()
{
//结构体变量创建方式1
struct student stu1;
//struct 关键字可以省略,即 student stu1;注释:创建结构体变量时,关键字struct可以省略
//结构体变量利用操作符 ''.'' 访问成员
stu1.name = "李一";
stu1.age = 23;
stu1.score = 100;
cout << " 姓名:" << stu1.name
<< " 年龄:" << stu1.age
<< " 分数:" << stu1.score << endl;
//结构体变量创建方式2
struct student stu2 = { "李二",24,99 };
cout << " 姓名:" << stu2.name
<< " 年龄:" << stu2.age
<< " 分数:" << stu2.score << endl;
//结构体变量创建方式3
stu3.name = "李三";
stu3.age = 25;
stu3.score = 98;
cout << " 姓名:" << stu3.name
<< " 年龄:" << stu3.age
<< " 分数:" << stu3.score << endl;
system("pause");
return 0;
}
3、结构体数组
语法:struct 结构体名 数组名 [元素个数]=
{
{ } , { } , ... { }
};
#include<iostream>
#include<string>
using namespace std;
struct student
{
string name; //姓名
int age; //年龄
int score; //分数
}
int main()
{
//定义结构体数组
//将自定义的结构体放入到数组中方便维护
struct student array[3]=
{
{ "李一",23,100 },
{ "李二",24,99 },
{ "李三",25,98 }
};
//输出结构体数组数据
for (int i = 0; i < 3; i++)
{
cout << " 姓名:" << array[i].name
<< " 年龄:" << array[i].age
<< " 分数:" << array[i].score << endl;
//访问结构体数组成员也用 "."
}
system("pause");
return 0;
}
4、结构体指针
#include<iostream>
#include<string>
using namespace std;
struct student
{
//结构体成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
int main()
{
student stu1;
stu1.name = "李一";
stu1.age = 23;
stu1.score = 100;
//定义结构体指针
struct student *pi = &stu1;
//利用操作符 "->" 可以通过结构体指针访问结构体成员
cout << " 姓名:" << pi->name
<< " 年级:" << pi->age
<< " 分数:" << pi->score << endl;
system("pause");
return 0;
}
5、结构体嵌套结构体
#include<iostream>
#include<string>
using namespace std;
struct child
{
string name;
string gender;
int age;
};
struct parent
{
string name;
string gender;
int age;
struct child ch1;
struct child ch2;
//结构体就是自定义的数据类型!!!
};
int main()
{
//创建结构体变量par
parent par;
//给结构体成员赋值
par.name = "李父";
par.gender = "男";
par.age = 55;
par.ch1.name = "李一";
par.ch1.gender = "男";
par.ch1.age = 24;
par.ch2.name = "李二";
par.ch2.gender = "男";
par.ch2.age = 18;
cout << " 长辈姓名:" << par.name << " 性别:" << par.gender << " 年纪:" << par.age << endl;
cout << " 第一个孩子姓名:" << par.ch1.name << " 性别:" << par.ch1.gender << " 年纪:" << par.ch1.age << endl;
cout << " 第二个孩子姓名:" << par.ch2.name << " 性别:" << par.ch2.gender << " 年纪:" << par.ch2.age << endl;
system("pause");
return 0;
}
6、结构体传递函数参数
6.1、值传递
定义一个函数,参数为变量,实现值传递,不会改变主函数中原来定义的数据。
#include<iostream>
#include<string>
using namespace std;
struct student
{
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
//定义一个函数,参数为变量,实现值传递
void ValuePassing(struct student i)
{
i.name = "李二";
i.age = 20;
i.score = 99;
cout << " 函数中的姓名:" << i.name
<< " 年龄:" << i.age
<< " 分数:" << i.score << endl;
}
int main()
{
student stu;
stu.name = "李一";
stu.age = 18;
stu.score = 100;
//调用函数ValuePassing,将main函数中所定义的"stu成员变量的值"传递给"i中的成员变量"
ValuePassing(stu);
//输出结果为 " 李二 20 99 "
cout << " 原主函数中定义的姓名:" << stu.name
<< " 年龄:" << stu.age
<< " 分数:" << stu.score << endl;
//输出结果为 " 李一 18 100"
system("pause");
return 0;
}
6.2、地址传递
定义一个函数,参数为指针变量,实现地址传递,而后主函数中原来定义的数据会改变为函数中我们所重新定义的数据。
#include<iostream>
#include<string>
using namespace std;
struct student
{
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
//定义一个函数,参数为指针变量,实现地址传递
void AddressPassing(struct student *i)
{
i->name = "李二";
i->age = 20;
i->score = 99;
cout << " 函数中的姓名:" << i->name
<< " 年龄:" << i->age
<< " 分数:" << i->score << endl;
}
int main()
{
student stu;
stu.name = "李一";
stu.age = 18;
stu.score = 100;
//调用函数AddressPassing,将main函数中所定义的"stu成员变量的值"传递给"i中的成员变量"
AddressPassing(&stu);
//输出结果为 " 李二 20 99 "
cout << " 原主函数中定义的姓名:" << stu.name
<< " 年龄:" << stu.age
<< " 分数:" << stu.score << endl;
//输出结果为 " 李二 20 99 "
system("pause");
return 0;
}
7、const在结构体中的应用
#include<iostream>
#include<string>
using namespace std;
struct student
{
string name;
int age;
int score;
};
//定义一个地址传递函数,参数为指针变量
//加const防止函数体中的误操作
//const修饰的是指针,为“常量指针”
//“常量指针”中:指针指向可以改,指针指向的值不可以更改
void AddressPassing(const struct student * stu)
{
//stu->age = 100; //操作失败,因为加了const修饰,指针指向的值不可以更改
cout << " 姓名:" << stu->name
<< " 年龄:" << stu->age
<< " 分数:" << stu->score << endl;
}
int main()
{
student stu;
stu.name = "李一";
stu.age = 18;
stu.score = 100;
AddressPassing(&stu);
//输出结果为 " 李一 18 100 "
//地址传递后主函数中“原来定义的数据”会改变为“函数中我们所重新定义的数据”
//加入const就能防止“原来定义的数据”被更改
system("pause");
return 0;
}
十五、引用
1、引用简介
引用变量是一个别名,它是我们给某个已存在变量的别名。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向已存在的变量。
语法: 数据类型 & 别名 = 已知变量名
#include <iostream>
using namespace std;
int main()
{
int a = 10;//定义变量a
int &b = a;//引用语法
cout << " a = " << a << endl;//输出结果 a = 10
cout << " b = " << b << endl;//输出结果 b = 10
b = 50;
cout << " a = " << a << endl;//输出结果 a = 50
cout << " b = " << b << endl;//输出结果 b = 50
system("pause");
return 0;
}
2、引用作参数
#include <iostream>
using namespace std;
//函数声明
void swap1(int a, int b);
void swap2(int * a, int * b);
void swap3(int & a, int & b);
//1、值传递函数定义
void swap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
//2、地址传递函数定义
void swap2(int * a, int * b)
{
int temp = *a;
*a = *b;
*b = temp;
}
//3、引用传递函数定义
void swap3(int & a, int & b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 10;
int b = 20;
swap1(a, b);
cout << "a:" << a << " b:" << b << endl;//输出结果 a=10,b=20
swap2(&a, &b);
cout << "a:" << a << " b:" << b << endl;//输出结果 a=20,b=10
swap3(a, b);
cout << "a:" << a << " b:" << b << endl;//输出结果 a=10,b=20
system("pause");
return 0;
}
十六、类和对象
类是 C++ 的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,是一种用户自定义的数据类型,它是一种封装了数据和函数的组合。类中的数据称为成员变量,函数称为成员函数。类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象。
C++面向对象的三大特性为:封装、继承、多态,C++认为万事万物都皆为对象,对象上有其属性和行为。人可以作为对象,属性有姓名、年龄、体重...,行为有走、跑、跳、吃饭、唱歌
1、封装
1.1、封装简介
语法: class 类名
{
访问权限:
属性 / 行为
};
#include <iostream>
using namespace std;
//圆周率为常量,定义常量Pai
const double Pai = 3.14;
//封装的意义
//将属性和行为作为一个整体,用来表现生活中的事物
//封装一个圆类,求圆的周长
//class代表设计一个类,后面跟着的是类名
//类中的属性和行为,我们统一称为成员
//属性 成员属性,成员变量
//行为 成员方法,成员函数
//创建具体对象后通过“.”进行访问
class Circle
{
//访问权限 公共的权限
public:
//属性
//成员变量
int my_r;//半径
//行为
//成员函数
//获取到圆的周长
double calculateZC()
{
//返回圆的周长
return 2 * Pai * my_r;
}
};
int main()
{
//通过圆类,创建圆的一个具体对象
//实例化,即通过一个类创建一个对象的过程
//circle1就是一个具体的圆
Circle circle1;
circle1.my_r = 10; //给圆对象的半径 进行赋值操作
cout << "圆的周长为: " << circle1.calculateZC() << endl;//输出62.8
system("pause");
return 0;
}
1.2、访问权限
类在设计时,可以把属性和行为放在不同的权限下,加以控制
#include <iostream>
using namespace std;
//三种权限
//公共权限 public 类内可以访问 类外可以访问
//保护权限 protected 类内可以访问 类外不可以访问
//私有权限 private 类内可以访问 类外不可以访问
class Person
{
//姓名 公共权限
public:
string m_Name;
//汽车 保护权限
protected:
string m_Car;
//银行卡密码 私有权限
private:
int m_Password;
public:
void func()
{
m_Name = "张三";
m_Car = "拖拉机";
m_Password = 123456;
}
};
int main()
{
Person p;
p.m_Name = "李四";
//p.m_Car = "奔驰"; //保护权限类外访问不到
//p.m_Password = 123; //私有权限类外访问不到
system("pause");
return 0;
}
1.3、struct or class
在C++中 struct 和 class 的区别就在于 默认的访问权限不同,struct 默认为公共,而 class 默认为私有。
#include <iostream>
using namespace std;
class Class1
{
int m_A; //默认是私有权限
};
struct Class2
{
int m_A; //默认是公共权限
};
int main()
{
Class1 c1;
c1.m_A = 10; //错误,访问权限是私有
Class2 c2;
c2.m_A = 10; //正确,访问权限是公共
system("pause");
return 0;
}
1.4、成员属性设置为私有
优点1:将所有成员属性设置为私有,可以自己控制读写权限
优点2:对于写权限,我们可以检测数据的有效
#include <iostream>
using namespace std;
class Person
{
public:
//姓名设置可读可写
void setName(string name)
{
m_Name = name;
}
string getName()
{
return m_Name;
}
//获取年龄
int getAge()
{
return m_Age;
}
//设置年龄
void setAge(int age)
{
if (age < 0 || age > 150)
{
cout << "不存在!" << endl;
return;
}
m_Age = age;
}
//情人设置为只写
void setLover(string lover)
{
m_Lover = lover;
}
private:
string m_Name; //可读可写 姓名
int m_Age; //只读 年龄
string m_Lover; //只写 情人
};
int main()
{
Person p;
//姓名设置
p.setName("张三");
cout << "姓名: " << p.getName() << endl;
//年龄设置
p.setAge(50);
cout << "年龄: " << p.getAge() << endl;
//情人设置
p.setLover("苍井");
//cout << "情人: " << p.m_Lover << endl; //只写属性,不可以读取
system("pause");
return 0;
}
2、构造函数和析构函数
2.1、简介
我们需要进行对象的初始化和清理工作,C++中利用构造函数和析构函数来实现这一点,是编译器强制要我们做的事情,如果我们不写这两个函数,编译器也会自动提供。
构造函数:创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
语法: 类名(){ }
注意事项:
1、构造函数,没有返回值也不写void
2、函数名称与类名相同
3、构造函数可以有参数,因此可以发生重载
4、程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
语法: ~类名(){ }
注意事项:
、析构函数,没有返回值也不写void
2、函数名称与类名相同,在名称前加上符号 ~
3、析构函数不可以有参数,因此不可以发生重载
4、程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
#include <iostream>
using namespace std;
//创建一个人(Person)类,在类中写构造和析构函数
class Person
{
public:
//构造函数语法:类名()
Person()
{
cout << "Person的构造函数已被调用" << endl;
}
//析构函数语法
~Person()
{
cout << "Person的析构函数已被调用" << endl;
}
};
//创建一个test函数
void test()
{
//用Person类实例化一个对象p
Person p;
}
int main()
{
//调用test函数,会输出上面两句话
test();
system("pause");
return 0;
}
2.2 、构造函数的分类及调用
#include <iostream>
using namespace std;
//1、构造函数分类
// 按照参数分类分为:有参和无参构造(默认构造函数)
// 按照类型分类分为:普通构造和拷贝构造
class Person
{
public:
//无参(默认)构造函数
Person()
{
cout << "无参构造函数!" << endl;
}
//有参构造函数
Person(int a)
{
age = a;
cout << "有参构造函数!" << endl;
}
//拷贝构造函数
//语法:类名(const 类名 & 要拷贝的对象名){ }
Person(const Person & p)
{
age = p.age;
cout << "拷贝构造函数!" << endl;
}
//析构函数
~Person()
{
cout << "析构函数!" << endl;
}
public:
int age;
};
//2、构造函数的调用
//调用无参构造函数
void test01()
{
//调用无参构造函数
Person p;
//注意:调用无参构造函数不能加括号,如果加了编译器认为这是一个函数声明
//Person p();错误!
}
//调用有参的构造函数
void test02()
{
//2.1、括号法,常用
Person p1(10);
//2.2、显式法
Person p2 = Person(10);
Person p3 = Person(p2);
//Person(10)单独写就是匿名对象 当前行结束之后,马上析构
//2.3 隐式转换法
Person p4 = 10; // Person p4 = Person(10);
Person p5 = p4; // Person p5 = Person(p4);
//注意2:不能利用 拷贝构造函数 初始化匿名对象 编译器认为是对象声明
//Person p5(p4);
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
2.3、拷贝构造函数调用时机
#include <iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "无参构造函数!" << endl;
mAge = 0;
}
Person(int age)
{
cout << "有参构造函数!" << endl;
mAge = age;
}
Person(const Person & p)
{
cout << "拷贝构造函数!" << endl;
mAge = p.mAge;
}
//析构函数在释放内存之前调用
~Person()
{
cout << "析构函数!" << endl;
}
public:
int mAge;
};
//1. 使用一个已经创建完毕的对象来初始化一个新对象
void test01()
{
Person man(100); //p对象已经创建完毕
Person newman(man); //调用拷贝构造函数
Person newman2 = man; //拷贝构造
//Person newman3;
//newman3 = man; //不是调用拷贝构造函数,赋值操作
}
//2. 值传递的方式给函数参数传值
//相当于Person p1 = p;
void doWork(Person p1)
{
}
void test02()
{
Person p; //无参构造函数
doWork(p);
}
//3. 以值方式返回局部对象
Person doWork2()
{
Person p1;
cout << (int *)&p1 << endl;
return p1;
}
void test03()
{
Person p = doWork2();
cout << (int *)&p << endl;
}
int main()
{
test01();
test02();
test03();
system("pause");
return 0;
}
2.4 、构造函数调用规则
默认情况下,c++编译器至少给一个类添加3个函数:
1、默认构造函数(无参,函数体为空)
2、默认析构函数(无参,函数体为空)
3、默认拷贝构造函数,对属性进行值拷贝
构造函数调用规则如下:
-
如果用户定义有参构造函数,c++不在提供默认无参构造,但是会提供默认拷贝构造
-
如果用户定义拷贝构造函数,c++不会再提供其他构造函数
#include <iostream>
using namespace std;
class Person
{
public:
//无参(默认)构造函数
Person()
{
cout << "无参构造函数!" << endl;
}
//有参构造函数
Person(int a)
{
age = a;
cout << "有参构造函数!" << endl;
}
//拷贝构造函数
Person(const Person & p)
{
age = p.age;
cout << "拷贝构造函数!" << endl;
}
//析构函数
~Person()
{
cout << "析构函数!" << endl;
}
public:
int age;
};
void test01()
{
Person p1(18);
//如果不写拷贝构造,编译器会自动添加拷贝构造,并且做浅拷贝操作
Person p2(p1);
cout << "p2的年龄为: " << p2.age << endl;
}
void test02()
{
//如果用户提供有参构造,编译器不会提供默认构造,会提供拷贝构造
Person p1; //此时如果用户自己没有提供默认构造,会出错
Person p2(10); //用户提供的有参
Person p3(p2); //此时如果用户没有提供拷贝构造,编译器会提供
//如果用户提供拷贝构造,编译器不会提供其他构造函数
Person p4; //此时如果用户自己没有提供默认构造,会出错
Person p5(10); //此时如果用户自己没有提供有参,会出错
Person p6(p5); //用户自己提供拷贝构造
}
int main()
{
test01();
system("pause");
return 0;
}
2.5 、初始化列表
语法:构造函数():属性1(值1),属性2(值2)... { }
作用:C++提供了初始化列表语法,用来初始化属性
#include <iostream>
using namespace std;
class Person
{
public:
//传统方式初始化
Person(int q, int w, int e)
{
m_q = q;
m_w = w;
m_e = e;
}
//初始化列表方式初始化
//语法:构造函数():属性1(值1),属性2(值2)... { }
Person(int a, int b, int c) :m_A(a), m_B(b), m_C(c) { }
void PrintPerson()
{
cout << "mA:" << m_A << endl;
cout << "mB:" << m_B << endl;
cout << "mC:" << m_C << endl;
}
private:
int m_A;
int m_B;
int m_C;
};
int main()
{
Person p(1, 2, 3);
p.PrintPerson();
system("pause");
return 0;
}
2.6、类对象作为类成员
C++类中的成员可以是另一个类的对象,我们称该成员为对象成员
class A { };
class B
{
A a;
};
#include <iostream>
using namespace std;
//创建一个Phone类
class Phone
{
public:
//构造函数
Phone(string name)
{
m_PhoneName = name;
cout << "Phone构造" << endl;
}
//析构函数
~Phone()
{
cout << "Phone析构" << endl;
}
string m_PhoneName;
};
//创建一个Person类
class Person
{
public:
//构造函数
//初始化列表语法:构造函数():属性1(值1),属性2(值2)... { }
Person(string name, string pName):m_Name(name), m_Phone(pName)
{
cout << "Person构造" << endl;
}
~Person()
{
cout << "Person析构" << endl;
}
void playGame()
{
cout << m_Name << " 使用" << m_Phone.m_PhoneName << " 牌手机! " << endl;
}
string m_Name;
Phone m_Phone;
};
void test()
{
//当类中成员是其他类对象时,我们称该成员为 对象成员
//构造的顺序是 :先调用对象成员的构造,再调用本类构造
//析构顺序与构造相反
Person p("张三" , "苹果X");
p.playGame();
}
int main()
{
test();
system("pause");
return 0;
}
2.7、静态成员
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员
2.7.1、静态成员变量
#include <iostream>
using namespace std;
class Person
{
public:
//静态成员变量语法:static 数据类型 变量名
static int m_A;
/*
静态成员变量特点:
1、在编译阶段分配内存
2、类内声明,类外初始化
3、所有对象共享同一份数据
*/
private:
static int m_B;
//静态成员变量也是有访问权限的
};
int Person::m_A = 10;
int Person::m_B = 10;
void test()
{
//静态成员变量两种访问方式
//1、通过对象
Person p1;
p1.m_A = 100;
cout << " p1.m_A = " << p1.m_A << endl;//输出100
Person p2;
p2.m_A = 200;
//所有对象共享同一份数据
cout << "p1.m_A = " << p1.m_A << endl;//输出200
cout << "p2.m_A = " << p2.m_A << endl;//输出200
//2、通过类名
cout << "m_A = " << Person::m_A << endl;
//cout << "m_B = " << Person::m_B << endl; //私有权限访问不到
}
int main()
{
test();
system("pause");
return 0;
}
2.7.2、静态成员函数
#include <iostream>
using namespace std;
class Person
{
public:
//静态成员函数特点:
//1 程序共享一个函数
//2 静态成员函数只能访问静态成员变量
static void func()
{
cout << "func调用" << endl;
m_A = 100;
//m_B = 100; //错误,不可以访问非静态成员变量
}
//变量静态成员变量
static int m_A;
//普通变量
int m_B;
private:
//静态成员函数也是有访问权限的
static void func2()
{
cout << "func2调用" << endl;
}
};
int Person::m_A = 10;
void test()
{
//静态成员变量两种访问方式
//1、通过对象
Person p1;
p1.func();
//2、通过类名
//类作用域,用来标明类的变量、函数
Person::func();
//Person::func2(); //私有权限访问不到
}
int main()
{
test();
system("pause");
return 0;
}