C++ 基础入门
1 C++初始
2 数据类型
3 运算符
4 程序流程结构
4.1 选择结构
4.2 循环结构
4.3 跳转语句
4.3.1 break 语句
作用:用于跳出选择结构或者循环结构
break使用的时机:
- 出现在switch条件语句中,作用是终止case并跳出switch
- 出现在循环语句中,作用是跳出当前的循环语句
- 出现在嵌套循环中,跳出最近的内层循环语句
实例1:
#include <iostream>
using namespace std;
int main() {
// break 的使用时机
// 1、出现在switch语句中
cout << "请选择副本难度" << endl;
cout << "1、普通" << endl;
cout << "2、中等" << endl;
cout << "3、困难" << endl;
int select = 0; //创建选择结果的变量
cin >> select; //等待用户输入
switch (select)
{
case 1:
cout << "你选择的是普通难度" << endl;
break;
case 2:
cout << "你选择的是中等难度" << endl;
break;
case 3:
cout << "你选择的是困难难度" << endl;
break;
default:
break;
}
system("pause");
return 0;
}
实例2:
// 2、出现在循环语句中
for (int i = 0; i < 10; i++)
{
if (i == 5)
{
break; //跳出循环语句
}
cout << i << endl;
}
实例3:
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (j == i)
{
break; //退出内层循环
}
cout << "*" ;
}
cout << endl;
}
4.3.2 continue语句
作用:执行到本行,就不在执行后面的代码了,而执行下一次循环
示例:
int main()
{
//continue 语句
for (int i = 0; i <= 100; i++)
{
//如果是奇数输出,偶数不输出
if (i % 2 == 0)
{
continue;
}
cout << i << endl;
}
system("pause");
return 0;
}
4.3.3 goto 语句
作用:可以无条件跳转语句
语法: goto 标记;
解释:如果标记的名称存在,执行到goto语句时,就会跳转到标记的位置
示例:
int main()
{
cout << "1" << endl;
cout << "2" << endl;
goto FLAG;
cout << "3" << endl;
cout << "4" << endl;
FLAG:
cout << "5" << endl;
system("pause");
return 0;
}
注意:在程序中不建议使用goto语句,以免造成程序流程混乱。
5 数组
5.1 概述
所谓数组,就是一个集合,里面存放了相同类型的数据元素
特点1:数组中的每个元素都是相同的数据类型
特点2: 数组是由连续的内存位置组成
5.2 一维数组
5.2.1 一维数组的定义方式
//1、数据类型 数组名[数组长度];
int arr[5];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
int i;
for (i = 0; i <= 2; i++)
{
cout << arr[i] << endl;
}
//2、数据类型 数组名[数组长度] = {值1,值2...}
// 如果在初始化数据时,没有全部填写,会用0来填补
int arr[3] = { 1,2,3 };
int i;
for (i = 0; i <= 2; i++)
{
cout << arr[i] << endl;
}
//3、数据类型 数组名[] = { 值1, 值2... }
int arr[] = { 1,2,3 };
int i;
for (i = 0; i <= 2; i++)
{
cout << arr[i] << endl;
}
总结:数组中下标从0开始索引
5.2.2 一维数组组名
一维数组名称的用途:
- 可以统计整个数组在内存中的长度
- 可以获取数组在内存中的首地址
#include<iostream>
using namespace std;
int main()
{
//1、可以通过数组名统计整个数组占用内存大小
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
cout << "整个数组占用内存空间为:" << sizeof(arr) << endl;
cout << "每个元素占用内存空间为:" << sizeof(arr[0]) << endl;
cout << "数组中元素个数为: " << sizeof(arr) / sizeof(arr[0]) << endl;
//2、可以通过数组名查看数组首地址
cout << "数组首地址为:" << (int)arr << endl;
cout << "数组中第一个元素地址为:" << (int)&arr[0] << endl;
cout << "数组中第二个元素地址为:" << (int)&arr[1] << endl;
//数组名是常量,不能进行赋值操作
system("pause");
return 0
}
案例1:五只小猪称体重
#include<iostream>
using namespace std;
int main()
{
//1、创建5只小猪体重的数组
int arr[5] = { 369,800,490,678,246 };
//2、从数组中找到最大值
int max = 0; //先认定一个最大值为0
for (int i = 0; i < 5; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
cout << "最重的小猪为:" << max << endl;
system("pause");
return 0;
}
案例2:数组逆置
#include<iostream>
using namespace std;
int main()
{
//1、创建数组
int arr[5] = { 1,6,5,3,8 };
cout << "数组逆置前:" << endl;
for (int i = 0; i < 5; i++)
{
cout << arr[i] << " ";
}
//2、实现逆置
//2.1 记录起始下标位置
//2.2 记录结束下标位置
//2.3 起始下标位置与结束下标位置的元素互换
//2.4 起始位置++ 结束位置--
//2.5 循环执行2.1操作,直到起始位置 >= 结束位置
int start = 0; //起始下标
int end = sizeof(arr) / sizeof(arr[0]) - 1; //结束下标
while (start < end)
{
//实现元素互换
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
//下标更新
start++;
end--;
}
for (int i = 0; i < 5; i++)
{
cout << arr[i] << " ";
}
system("pause");
return 0;
}
案例3:冒泡排序
#include<iostream>
using namespace std;
int main()
{
int arr[8] = { 7,1,4,9,6,8,2,0 };
cout << "排序前:" << endl;
for (int i = 0; i < 8; i++)
{
cout << arr[i] << " ";
}
//开始冒泡排序
//总共排序轮数为 元素个数 - 1
for (int j = 0; j < 8 - 1; j++)
{
//内层循环对比 次数 = 元素个数 - 当前轮数 -1
for (int k = 0; k < 8 - j -1; k++)
{
if (arr[k] > arr[k + 1])
{
int temp = arr[k];
arr[k] = arr[k + 1];
arr[k + 1] = temp;
}
}
}
cout << "排序后:" << endl;
for (int i = 0; i < 8; i++)
{
cout << arr[i] << " ";
}
system("pause");
return 0;
}
5.3 二维数组
5.3.1 二维数组定义方式
5.3.2 二维数组数组名
- 查看二维数组所占空间
- 获取二维数组首地址
示例:
#include<iostream>
using namespace std;
int main()
{
//1、可以查看占用内存空间大小
int arr[2][3] =
{
{1,3,5},
{6,4,7}
};
cout << "二维数组占用内存空间为:" << sizeof(arr) << endl;
cout << "二维数组第一行占用内存为:" << sizeof(arr[0]) << endl;
cout << "二维数组第一个元素占用内存为:" << sizeof(arr[0][0]) << endl;
cout << "二维数组行数为:" << sizeof(arr) / sizeof(arr[0]) << endl;
cout << "二维数组列数为:" << sizeof(arr[0]) / sizeof(arr[0][0]) << endl;
//2、可以查看二维数组的首地址
cout << "二维数组首地址为:" << (int)arr << endl;
cout << "二维数组第一行首地址为:" << (int)arr[0] << endl;
cout << "二维数组第二行首地址为:" << (int)arr[1] << endl;
cout << "二维数组第一个元素首地址为:" << (int)&arr[0][0] << endl;
cout << "二维数组第二个元素首地址为:" << (int)&arr[0][1] << endl;
system("pause");
return 0;
}
5.3.3 二维数组应用案例
- 示例:统计分数
#include<iostream>
using namespace std;
#include <string>
int main()
{
//1、创建二维数组
int scores[3][3] =
{
{100,100,100},
{90,50,100},
{60,70,80}
};
string names[3] = { "张三","李四","王五" };
//2、统计每个人的综合分数
for (int i = 0; i < 3; i++)
{
int sum = 0; //统计分数总和变量
for (int j = 0; j < 3; j++)
{
sum += scores[i][j];
//cout << scores[i][j] << " ";
}
cout << names[i] << "的总分为: " << sum << endl;
}
system("pause");
return 0;
}
6 函数
6.1 概述
6.2 函数的定义
6.3 函数的调用
6.4 值传递
- 所谓值传递,就是函数调用时实参将数值传入给形参
- 值传递时,如果形参发生,并不会影响实参
6.5 函数的常见样式
函数常见样式有4种
- 无参无返
- 有参无返
- 无参有返
- 有参有返
示例
#include<iostream>
using namespace std;
//函数常见式样
//1、无参无返
void test01()
{
cout << "this is test01" << endl;
}
//2、有参无返
void test02(int a)
{
cout << "this is test02 a=" << a << endl;
}
//3、无参有返
int test03()
{
cout << "this is test03" << endl;
return 100;
}
//4、有参有返
int test04(int a)
{
cout << "this is test04 a = " << a << endl;
return 36;
}
int main()
{
//1、无参无返调用
test01;
//2、有参无返调用
test02(10);
//3、无参有返调用
int num1 = test03();
cout << "num1=" << num1 << endl;
//4、有参有返调用
int num2 = test04(5);
cout << "num2= " << num2 << endl;
system("pause");
return 0;
}
6.6 函数的声明
示例:
#include<iostream>
using namespace std;
//提前告诉编译器函数的存在,可以利用函数的声明
//函数的声明
//声明可以写多次,但是定义只能有一次
int max(int a, int b);
int min(int c, int d);
int main(){
int a = 10;
int b = 20;
int c = 5;
int d = 7;
cout << max(a, b) << endl;
cout << min(c, d) << endl;
system("pause");
return 0;
}
int max(int a, int b)
{
return a > b ? a : b;
}
int min(int c, int d)
{
return c < d ? c : d;
}
6.7 函数的文件编写
- 创建.h后缀名的头文件
- 创建.cpp后缀名的源文件
- 在头文件中写函数的声明
- 在源文件中写函数的定义
#include<iostream>
#include"swap.h"
using namespace std;
//函数的分文件编写
//实现两个数字进行交换的函数
//函数的声明 放入.h文件
//void swap(int a, int b);
//函数的定义 放入.cpp源文件
//void swap (int a, int b)
//{
// int temp = a;
// a = b;
// b = temp;
//
// cout << "a = " << a << endl;
// cout << "b = " << b << endl;
// }
//1、创建.h后缀名的头文件
//2、创建.cpp后缀名的源文件
//3、在头文件中写函数的声明
//4、在源文件中写函数的定义
int main()
{
int a = 10;
int b = 20;
swap(a, b);
system("pause");
cout << endl;
}
7 指针
7.1 指针的基本概念
7.2 指针变量的定义和使用
#include <iostream>
using namespace std;
int main()
{
//1、定义指针
int a = 10;
//指针定义的语法: 变量类型 * 指针变量名;
int* p;
//让指针记录变量a的地址
p = &a;
cout << "a的地址为:" << &a << endl;
cout << "指针p为:" << p << endl;
//2、使用指针
//可以通过解引用的方式来找到指针指向的内存
//指针前加 * 代表解引用,找到指针指向的内存中的数据
*p = 1000;
cout << "a = " << a << endl;
cout << "*p = " << *p << endl;
system("pause");
cout << endl;
}
7.3 指针所占内存空间
在32位操作系统下,指针所占内存为4位,64位操作系统下,指针占8个字节空间大小
7.4 空指针和野指针
空指针:
- 空指针:指针变量指向内存编号为0的空间
- 空指针用于给指针变量进行初始化
- 空指针是不可以进行访问的,内存编号0~255为系统占用内存,不允许用户访问
#include <iostream>
using namespace std;
int main()
{
//空指针:指针变量指向内存编号为0的空间
//1、空指针用于给指针变量进行初始化
int* p = NULL;
//2、空指针是不可以进行访问的
//内存编号0~255为系统占用内存,不允许用户访问
cout << *p << endl;
system("pause");
cout << endl;
}
野指针:
//野指针:指向非法内存空间
int* p = (int*)0x1100;
//访问野指针报错
cout << *p << endl;
7.5 const修饰指针
int main()
{
int a = 10;
int b = 20;
//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");
cout << endl;
}
7.6 指针和数组
作用:利用指针访问数组中的元素
#include<iostream>
using namespace std;
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = arr; //指向数组的指针
cout << "第一个元素:" << arr[0] << endl;
cout << "指针访问第一个元素:" << *p << endl;
for (int i = 0; i < 10; i++)
{
//利用指针遍历数组
cout << *p << endl;
p++;
}
system("pause");
cout << endl;
}
7.7 指针和函数
总结:如果想改变实参,就用地址传递,如果不想改变实参,就用值传递
#include<iostream>
using namespace std;
void swap01(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "swap01 a = " << a << endl;
cout << "swap01 b = " << b << endl;
}
void swap02(int* p1, int* p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main()
{
//1、值传递
int a = 10;
int b = 20;
swap01(a, b);
//2、地址传递
swap02(&a, &b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
system("pause");
cout << endl;
}
7.8 指针、数组、函数
** 案例描述**:封装一个函数,利用冒泡排序,实现对整型数组的升序排序
例如数组:int arr[10] = {5,7,9,4,3,2,6,8,1,10};
#include<iostream>
using namespace std;
//冒泡排序函数 参数1 数组的首地址 参数2 数组长度
void bubbleSort(int * arr, int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
//如果j > j+1 的值 交换数字
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//打印数组
void printArray(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i] << " ";
}
}
int main()
{
//1、创建数组
int arr[10] = {5,7,9,4,3,2,6,8,1,10};
//数组长度
int len = sizeof(arr) / sizeof(arr[0]);
//2、创建函数,实现冒泡排序
bubbleSort(arr, len);
//3、打印排序后的数组
printArray(arr, len);
system("pause");
return 0;
}
8 结构体
8.1 结构体基本概念
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
8.2 结构体定义和使用
语法:struct结构体名{结构体成员列表};
通过结构体创建变量的方式有三种:
- struct结构体名 变量名
- struct结构体名 变量名 = {成员1值,成员2值…}
- 定义结构体时顺便创建变量
示例:
#include<iostream>
using namespace std;
//1、创建学生数据类型:学生包括(姓名、年龄、分数)
//自定义数据类型,一些类型集合组成的一个类型
//语法 struct 类型名称 {成员列表}
struct Student
{
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
}s3; //顺便创建结构体变量
//2、通过学生类型创建具体学生
int main()
{
//2.1 struct Student s1
//struct 关键字可以省略
struct Student s1;
//给s1属性赋值,通过.访问结构体变量中的属性
s1.name = "张三";
s1.age = 18;
s1.score = 100;
cout << " 姓名:" << s1.name << " 年龄:" << s1.age << " 分数:" << s1.score << endl;
//2.2 struct Student s2 = {...}
struct Student s2 = { "里斯",19,80 };
cout << " 姓名:" << s2.name << " 年龄:" << s2.age << " 分数:" << s2.score << endl;
//在定义结构体时顺便创建结构体变量
s3.name = "王五";
s3.age = 20;
s3.score = 60;
cout << " 姓名:" << s3.name << " 年龄:" << s3.age << " 分数:" << s3.score << endl;
system("pause");
cout << endl;
}
8.3 结构体数组
作用:将自定义的结构体放入数组中方便维护
语法:struct 结构体名 数组名[元素个数] = { {},{},…{}}
示例:
#include<iostream>
#include<string>
using namespace std;
//1、创建学生数据类型:学生包括(姓名、年龄、分数)
//自定义数据类型,一些类型集合组成的一个类型
//语法 struct 类型名称 {成员列表}
struct Student
{
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
};
int main()
{
//2、创建结构体数组
struct Student stuArray[3] =
{
{"张三", 18, 100},
{"里斯",32, 77},
{"王武",34, 89}
};
//3、给结构体数组中的元素赋值
stuArray[2].name = "赵六";
stuArray[2].age = 80;
stuArray[2].score = 60;
///4、遍历结构体数组
for (int i = 0; i < 3; i++)
{
cout << " 姓名:" << stuArray[i].name
<< " 年龄:" << stuArray[i].age
<< " 分数:" << stuArray[i].score << endl;
}
}
8.4 结构体指针
通过结构体指针,访问结构体指针中的属性,需要利用’->'.
#include<iostream>
#include<string>
using namespace std;
//1、创建学生数据类型:学生包括(姓名、年龄、分数)
//自定义数据类型,一些类型集合组成的一个类型
//语法 struct 类型名称 {成员列表}
struct student
{
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
};
int main()
{
//1、创建学生结构体变量
student s = { "张三", 18, 90 };
//2、通过指针指向结构体变量
student* p = &s;
//3、通过指针访问结构体变量中的数据
//通过结构体指针,访问结构体指针中的属性,需要利用'->'
cout << " 姓名:" << p->name
<< " 年龄:" << p->age
<< " 分数:" << p->score << endl;
system("pause");
cout << endl;
}
8.5 结构体嵌套结构体
#include<iostream>
#include<string>
using namespace std;
//1、创建学生数据类型:学生包括(姓名、年龄、分数)
//自定义数据类型,一些类型集合组成的一个类型
//语法 struct 类型名称 {成员列表}
//定义学生结构体
struct student
{
string name;
int age;
int score;
};
//定义老师结构体
struct teacher
{
int id;
string name;
int age;
struct student stu; //辅导的学生
};
int main()
{
//结构体体嵌套结构体
//创建老师
teacher t;
t.id = 10000;
t.name = "老刘";
t.age = 50;
t.stu.name = "小昭";
t.stu.age = 20;
t.stu.score = 70;
cout << " 老师姓名:" << t.name
<< " 老师年龄:" << t.age
<< " 学生分数:" << t.stu.score << endl;
system("pause");
cout << endl;
}
8.6 结构体做函数参数
#include<iostream>
#include<string>
using namespace std;
//1、创建学生数据类型:学生包括(姓名、年龄、分数)
//自定义数据类型,一些类型集合组成的一个类型
//语法 struct 类型名称 {成员列表}
//定义学生结构体
struct student
{
string name;
int age;
int score;
};
//打印学生信息函数
//1、值传递
void printStudent1(struct student s)
{
s.age = 100; //值传递时形参发生任何改变不会修饰实参
cout << "子函数1中 姓名: " << s.name << " 年龄:" << s.age << " 分数;" << s.score << endl;
}
//2、地址传递
void printStudent2(struct student* p)
{
p->age = 300; //修饰了形参外侧数据也会发生改变
cout << "子函数2中 姓名: " << p->name << " 年龄:" << p->age << " 分数;" << p->score << endl;
}
int main()
{
//结构体做函数参数
//将学生传入到一个参数中,打印学生身上的所有信息
//创建结构体变量
struct student s;
s.name = "张三";
s.age = 20;
s.score = 85;
//printStudent1(s);
printStudent2(&s);
cout << "main函数中打印 姓名:" << s.name << " 年龄: " << s.age << " 分数:" << s.score << endl;
system("pause");
cout << endl;
}
8.7 结构体中const使用场景
示例:
#include<iostream>
#include<string>
using namespace std;
//1、创建学生数据类型:学生包括(姓名、年龄、分数)
//自定义数据类型,一些类型集合组成的一个类型
//语法 struct 类型名称 {成员列表}
//定义学生结构体
struct student
{
string name;
int age;
int score;
};
//const 使用场景
void printStudent( student* stu) //加const防止函数体中的误操作
{
// stu->age = 100; //操作失败,因为加了const修饰
cout << "姓名:" << stu->name << " 年龄:" << stu->age << "分数:" << stu->score << endl;
}
int main()
{
student stu = { "张三",29,100 };
printStudent(&stu);
system("pause");
cout << endl;
}
8.8 结构体案例
8.8.1 案例1
案例描述:学校在做毕设,有3名老师,每个老师带5个学生
设计学生和老师的结构体,在老师结构体中,有老师姓名和一个存放5名学生的数组做为成员
学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值
最终打印出老师数据以老师所带学生数据。
#include<iostream>
using namespace std;
#include<string>
//学生的结构体
struct Student
{
string sName;
int score;
};
//老师的结构体定义
struct Teacher
{
//姓名
string tName;
//学生数组
struct Student sArray[5];
};
//给老师和学生赋值的函数
void allocateSpace(struct Teacher tArray[], int len)
{
string nameSeed = "ABCDE";
//给老师开始赋值
for (int i = 0; i < len; i++)
{
tArray[i].tName = "Teacher_";
tArray[i].tName += nameSeed[i];
//通过循环给每名老师所带的学生赋值
for (int j = 0; j < 5; j++)
{
tArray[i].sArray[j].sName = "Student_";
tArray[i].sArray[j].sName += nameSeed[j];
int random = rand() % 61 + 40;
tArray[i].sArray[j].score = random;
}
}
}
//打印所有信息
void printInfo(struct Teacher tArray[], int len)
{
for (int i = 0; i < len; i++)
{
cout << "老师姓名:" << tArray[i].tName << endl;
for (int j = 0; j < 5; j++)
{
cout << "学生姓名: " << tArray[i].sArray[j].sName <<
"学生分数: " << tArray[i].sArray[j].score << endl;
}
}
}
int main()
{
// 随机数种子
srand((unsigned int)time(NULL));
// 1、创建3名老师的数组
struct Teacher tArray[3];
// 2、通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
int len = sizeof(tArray) / sizeof(tArray[0]);
allocateSpace(tArray, len);
// 3、打印所有老师及所带的学生信息
printInfo(tArray, len);
system("pause");
cout << endl;
}
8.8.2 案例2
案例描述:
设计一个英雄的结构体,包括成员姓名、年龄、性别;创建结构体数组,数组中存放着5名英雄,通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。
#include<iostream>
using namespace std;
//1、设计英雄结构体
struct Hero
{
string name;
int age;
string sex;
};
//冒泡排序 实现年龄升序排列
void bubbleSort(struct Hero heroArray[], int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
if (heroArray[j].age > heroArray[j + 1].age)
{
struct Hero temp = heroArray[j];
heroArray[j] = heroArray[j + 1];
heroArray[j + 1] = temp;
}
}
}
//打印排序后数组中的信息
void printHero(struct Hero heroArray[], int len)
{
for (int i = 0; i < len; i++)
{
cout << " 姓名:" << heroArray[i].name << " 年龄:" << heroArray[i].age
<< " 性别:" << heroArray[i].sex << endl;
}
}
int main()
{
//2、创建数组存放5名英雄
struct Hero heroArray[5] =
{
{"刘备", 40, "男"},
{"关羽", 45, "男"},
{"赵云", 23, "男"},
{"张飞", 22, "男"},
{"貂蝉", 18, "男"},
};
int len = sizeof(heroArray) / sizeof(heroArray[0]);
cout << "排序前:" << endl;
for (int i = 0; i < len; i++)
{
cout << " 姓名:" << heroArray[i].name << " 年龄:" << heroArray[i].age
<< " 性别:" << heroArray[i].sex << endl;
}
//3、对数组进行排序,按照年龄进行升序
bubbleSort(heroArray, len);
//4、将排序后的结果打印输出
cout << "排序后:" << endl;
printHero(heroArray, len);
system("pause");
return 0;
}