提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
环境:Win 11 64位
Visual Studio 2022
一、创建第一个项目
软件下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/
安装:
创建一个新项目:
#include<iostream>
using namespace std;
int main() {
cout << "Hello world" << endl;
system("pause");
return 0;
}
在基础入门的阶段,前三行和后三行基本上是固定的,基本上每一个demo都会包含,先记住就行。。。
二、变量和常量
1.变量和常量
变量存在的意义:方便管理空间
变量创建的语法:数据类型 变量名 = 变量初始值
int a = 10;
cout << "a = " << a << endl;
常量:用于记录程序中不可更改的数据
定义常量的两种方式:
#define宏常量:#define 常量名 常量值
通常在文件上方定义,表示一个常量
//1、宏常量
#define day 7
const修饰的变量:const 数据类型 常量名 = 常量值
通常在变量定义前加关键字const,修饰该变量为常量,不可修改
//2、const修饰变量
const int month = 12;
2.关键字&标识符
在定义变量或者常量时候,不要用关键字
标识符:
- 不可以是关键字
- 由字母、数字、下划线构成
- 第一个字符只能是字母或下划线
- 区分大小写
3.数据类型
用sizeof关键字可以统计数据类型所占内存大小
语法:sizeof(数据类型/变量)
short b;
cout << "short 类型所占内存空间为: " << sizeof(short) << endl;
int a;
cout << "short 类型所占内存空间为: " << sizeof(a) << endl;
(1)整型
区别在于占用内存不同
大小对比:short < int <= long <= long long
(2)实型(浮点型)
- 单精度float
- 双精度double
区别在于表示的有效数字范围不同
科学计数法
float f2 = 3e2; // 3 * 10 ^ 2
float f3 = 3e-2; // 3 * 0.1 ^ 2
(3)字符型
用于显示单个字符
ASCII码
运算符
算术运算符 四则运算
赋值运算符 将表达式的值赋给变量
比较运算符 表达式比较,返回布尔值
逻辑运算符 或与非,返回布尔值
算术运算符 四则运算
赋值运算符 将表达式的值赋给变量
比较运算符 表达式比较,返回布尔值
逻辑运算符 或与非,返回布尔值
程序流程结构
顺序结构:代码从上到下按顺序执行
选择结构:
单行if语句:if(条件){ 条件满足执行的语句 }
代码:
//注意事项,在if判断语句后面,不要加分号
if (score > 600)
{
cout << "我考上了一本大学!!!" << endl;
}
多行格式if语句:if(条件){ 条件满足执行的语句 }else{ 条件不满足执行的语句 };
代码:
if (score > 600)
{
cout << "我考上了一本大学" << endl;
}
else
{
cout << "我未考上一本大学" << endl;
}
多条件的if语句:if(条件1){ 条件1满足执行的语句 }else if(条件2){条件2满足执行的语句}... else{ 都不满足执行的语句}
代码:
int main() {
int score = 0;
cout << "请输入考试分数:" << endl;
cin >> score;
if (score > 600)
{
cout << "我考上了一本大学" << endl;
}
else if (score > 500)
{
cout << "我考上了二本大学" << endl;
}
else if (score > 400)
{
cout << "我考上了三本大学" << endl;
}
else
{
cout << "我未考上本科" << endl;
}
system("pause");
return 0;
}
嵌套if语句-案例:三只小猪称体重
//三个小猪比体重
int num1 = 0;
int num2 = 0;
int num3 = 0;
cout << "请输入小猪A的体重:" << endl;
cin >> num1;
cout << "请输入小猪B的体重:" << endl;
cin >> num2;
cout << "请输入小猪C的体重:" << endl;
cin >> num3;
if (num1 > num2) {
if (num1 > num3) {
cout << "小猪A最重" << endl;
}
else {
cout << "小猪C最重" << endl;
}
}
else
{
if (num2 > num3) {
cout << "小猪B最重" << endl;
}
else
{
cout << "小猪C最重" << endl;
}
}
三目运算符
语法:表达式1 ? 表达式2 :表达式3
//三目运算符:表达式?为真:为假
int a = 10;
int b = 2;
int c = 0;
c = a > b ? a : b;
cout << c << endl;
//在C++中三目运算符返回的是变量,可以继续赋值
(a > b ? a : b) = 100;
cout << a << endl;
cout << b << endl;
switch语句
执行多条件分支
if和switch的区别?
缺点:判断只能是整型或字符型,不可以是一个区间
优点:结构清晰
注意:如果case语句里代码较长,需要用{}框住,否则会报错!
//电影评分,根据用户输入的分数提示
// 10-9经典/7-9非常好/5-6一般/5以下烂片
int score = 0;
cout << "给出您的评分:" << endl;
cin >> score;
switch (score)
{
case 10:
cout << "您认为是经典电影" << endl;
break; //退出当前分支
case 8:
cout << "您认为是非常好的电影" << endl;
break;
case 5:
cout << "您认为是一般的电影" << endl;
break;
default:
cout << "烂片" << endl;
break;
}
循环结构
依据条件是否满足,循环多次执行某段代码
while
do…while
for
随机数:
头文件:#include<ctime>
设置种子值:srand((unsigned int)time(NULL));
随机生成40~100的随机值:int random = rand() % 61+40;
案例:猜数字
#include<iostream>
#include<ctime> //系统时间头文件
using namespace std;
int main() {
//通过srand()函数设置种子值,确保每次运行随机值不同
srand(static_cast<unsigned int>(time(nullptr)));
int num = 0;
int num1 = rand()%100+1;
cout << "请输入您猜测的数字:" << endl;
cin >> num;
while (num != num1) {
if (num > num1) {
cout << "猜大了" << endl;
}
else {
cout << "猜小了" << endl;
}
cout << "请输入您猜测的数字:" << endl;
cin >> num;
}
cout << "恭喜你猜中了!正确数字是:" << num1 << endl;
system("pause");
return 0;
}
案例:水仙花数
一个三位数,每个位上的数字的3次幂之和等于它本身
#include<iostream>
using namespace std;
int main() {
int num = 100;
int a ,b ,c;
do {
a = num / 100; //百位
b = (num/10)%10;//十位
c = num %10; //个位
//在C++中 a^3不表示a的三次方,可以用math.h函数中的pow表示
if ( (a*a*a + b*b*b + c*c*c) == num ) {
cout << num << endl;
}
num++;
} while (num < 1000);
system("pause");
return 0;
}
案例:九九乘法表
#include<iostream>
using namespace std;
int main() {
for (int i = 1; i < 10; i++) {
for (int j = 1; j <= i; j++) {
int num = i * j;
cout << i << "*" << j << "=" << num<<" ";
}
cout << " " << endl;
}
system("pause");
return 0;
}
跳转语句
break:用于跳出选择语句或循环结构
• 出现在switch语句中,终止case并跳出switch
• 出现在循环语句中,跳出当前循环语句
• 出现在嵌套循环中,跳出最近的内层循环语句
continue:执行到本行就不执行后面的代码了,直接进入下一次循环
goto:无条件跳转语句,直接跳转到标记位置
在程序中不建议使用goto语句,以免造成程序流程混乱
数组
一个集合,里面存放了相同类型的数据元素,由连续的内存位置组成
//一维数组名称用途
//1.统计整个数组在内存中的长度,计算数组元素个数
int arr[5] = { 1,2,3,4,5 };
cout << "整个数组占用内存空间为:" << sizeof(arr) << endl;
cout << "每个元素占用的内存空间为:" << sizeof(arr[1]) << endl;
cout << "数组中元素个数为:" << sizeof(arr) / sizeof(arr[0]) << endl;
//2.获取数组在内存中的首地址,强转格式
cout << "数组首地址为:" << (int)arr << endl;
cout << "数组中第一个元素的地址为:" << (int)&arr[0] << endl;
cout << "数组中第二个元素的地址为:" << (int)&arr[1] << endl;
//数组名是常量,不可以进行赋值操作
元素逆置
代码:
int arr[5] = { 1,2,3,4,5 };
int start = 0;
int end = sizeof(arr) / sizeof(arr[0]) - 1;
int temp = 0;
for (int i = 0; i < 5; i++) {
cout << arr[i] << endl;
}
while (start < end) {
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
for (int i = 0; i < 5; i++) {
cout << arr[i] << endl;
}
冒泡排序
排序轮数 对比次数
1.比较相邻的元素,如果第一个比第二个大,交换
2.对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值
3.重复以上步骤,每次比较次数-1,直到不需要比较
图示:
代码:
int arr[10] = { 4,3,5,6,1,2,7,9,8,7 };
int temp = 0;
//外层循环:总共排序轮数 元素个数-1
for (int j = 0; j < 9; j++) {
//内层循环:次数=元素个数-当前轮数-1
for (int i = 0; i < 9-j; i++) {
if (arr[i] > arr[i + 1]) {
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
for (int i = 0; i < 10; i++) {
cout << arr[i] << endl;
}
二维数组
函数
将一段经常使用的代码封装起来,减少重复代码
函数的定义:
返回值类型 函数名(参数列表){
函数体语句
return 表达式
}
值传递
函数调用时实参将数值传递给形参,如果形参发生改变,不会影响实参
值传递&引用传递
void swap(int num1, int num2) {
int temp = num1;
num1 = num2;
num2 = temp;
}
int main() {
int a = 2;
int b = 3;
swap(a, b);
system("pause");
return 0;
}
函数常见样式
1. 无参无返
2. 有参无返
3. 有参有返
4. 无参有返
函数的声明
声明写在函数定义之前,可实现先写main 函数再写具体函数
如果具体函数在main函数之前,则声明可以省略
声明可以写多次,但是定义只能有一次
函数的分文件编写
1. 创建.h后缀名的头文件
2. 创建.cpp后缀名的源文件
3. 在头文件中写函数的声明
4. 在源文件中写函数的定义
指针
作用:可以通过指针间接访问内存
内存编号时从0开始记录的,一般用十六进制数字表示
可以用指针变量保存地址
语法:数据类型 * 指针变量 ;
可以通过指针保存一个地址
指针占用的内存
在32位操作系统下,占用4个字节空间 Linux
在64位操作系统下,占用8个字节空间
不管是什么数据类型
空指针和野指针
空指针:指针变量指向内存中编号为0的空间
初始化指针变量 int * p =NULL;
空指针指向的内存是不可以访问的
野指针:指针变量指向非法的内存空间
const修饰指针
1. const修饰指针——常量指针 指针指向可以改,指针指向的值不可以更改
2. const修饰常量——指针常量 指针指向不可以改,指针指向的值可以改
3. const既修饰指针,又修饰常量
记忆方式:const->常量 ->指针
const int * p = &a; const临近,则修饰*,*操作不可以
int * const p = &a; const临近p,则修饰p,p操作不可以
常量指针
指针常量
const既修饰指针,又修饰常量
指针和数组:利用指针访问数组中的元素
指针和函数
值传递
void swap1(int a, int b) { 地址传递
void swap2(int* p1, int* p2) {
int temp = a; int temp = *p1;
a = b; *p1 = *p2;
b = temp; *p2 = temp;
cout << “a=” << a << endl; }
cout << “b=” << b << endl; int main{
} swap2(&a, &b);
int main{ cout << “a=” << a << endl;
int a = 10; cout << “b=” << b << endl;
int b = 20; }
swap1(a, b);
cout << “a=” << a << endl;
cout << “b=” << b << endl;
}
结构体
属于用户自定义的数据类型,允许用户存储不同的数据类型
结构体定义语法:struct 结构体名(结构体成员列表);
结构体创建:
• struct 结构体名 变量名
• struct 结构体名 变量名 = {成员1值,成员2值…}
• 定义结构体时同时创建变量
结构体数组 arr[0].name=“张三”
结构体指针 p->age = 18;
结构体嵌套->案例1 t.stu1.age = 20;
案例:通讯录管理系统
#include<iostream>
#include<string>
#define max 1000
using namespace std;
struct person {
string m_name;
int m_sex; //性别:1男 2女
int m_age;
string m_phone;
string m_address;
};
struct Addressbooks {
struct person perArr[max];
int m_size;
};
//菜单界面
void showMenu() {
cout << "****************************" << endl;
cout << "****** 1.添加联系人 ******" << endl;
cout << "****** 2.显示联系人 ******" << endl;
cout << "****** 3.删除联系人 ******" << endl;
cout << "****** 4.查找联系人 ******" << endl;
cout << "****** 5.修改联系人 ******" << endl;
cout << "****** 6.清空联系人 ******" << endl;
cout << "****** 0.退出通讯录 ******" << endl;
cout << "****************************" << endl;
}
//1.添加联系人
void addPerson(Addressbooks* abs) {
//判断通讯录是否已满
if (abs->m_size == max) {
cout << "通讯录已满,无法添加" << endl;
return;
}
else {
//添加具体联系人
string name;
cout << "请输入姓名:" << endl;
cin >> name;
abs->perArr[abs->m_size].m_name = name;
int sex;
cout << "请输入性别:1-男,2-女" << endl;
cin >> sex;
abs->perArr[abs->m_size].m_sex = sex;
int age;
cout << "请输入年龄:" << endl;
cin >> age;
abs->perArr[abs->m_size].m_age = age;
string phone;
cout << "请输入号码:" << endl;
cin >> phone;
abs->perArr[abs->m_size].m_phone = phone;
string address;
cout << "请输入地址:" << endl;
cin >> address;
abs->perArr[abs->m_size].m_address = address;
//变更通讯录人数
abs->m_size++;
cout << "添加成功!" << endl;
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
}
//显示所有联系人
void showPerson(Addressbooks abs) {
if (abs.m_size == 0) {
cout << "当前记录为空" << endl;
}
else
{
cout << "姓名\t性别\t年龄\t号码\t\t地址" << endl;
for (int i = 0; i < abs.m_size; i++) {
cout << abs.perArr[i].m_name << "\t"
<< (abs.perArr[i].m_sex == 1 ? "男" : "女") << "\t"
<< abs.perArr[i].m_age << "\t"
<< abs.perArr[i].m_phone << "\t"
<< abs.perArr[i].m_address << endl;
}
}
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
//检测联系人是否存在
int judgePerson(Addressbooks* abs, string name) {
for (int i = 0; i < abs->m_size; i++) {
if (abs->perArr[i].m_name == name) {
return i;//找到了返回数组下标
}
}
return -1;
}
//删除联系人
void deletePerson(Addressbooks* abs) {
cout << "请输入删除联系人的姓名:" << endl;
string name;
cin >> name;
int ret = judgePerson(abs, name);
if (ret != -1) {
for (int i = ret; i < abs->m_size; i++) {
//数据前移
abs->perArr[i] = abs->perArr[i + 1];
}
abs->m_size--; //更新通讯录长度
cout << "删除成功" << endl;
}
else
{
cout << "查无此人" << endl;
}
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
//查找联系人
void findPerson(Addressbooks* abs) {
cout << "请输入查找联系人的姓名:" << endl;
string name;
cin >> name;
int ret = judgePerson(abs, name);
if (ret != -1) {
cout << "姓名:" << abs->perArr[ret].m_name << "\t"
<< "性别:" << (abs->perArr[ret].m_sex == 1 ? "男" : "女") << "\t"
<< "年龄:" << abs->perArr[ret].m_age << "\t"
<< "号码:" << abs->perArr[ret].m_phone << "\t"
<< "地址:" << abs->perArr[ret].m_address << endl;
}
else
{
cout << "查无此人" << endl;
}
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
//修改联系人 用指针可以修改实参
void modifyPerson(Addressbooks* abs) {
cout << "请输入您要修改的联系人的姓名:" << endl;
string name;
cin >> name;
int ret = judgePerson(abs, name);
if (ret != -1) {
string name;
cout << "请输入姓名:" << endl;
cin >> name;
abs->perArr[ret].m_name = name;
int sex;
cout << "请输入性别:1-男,2-女" << endl;
while (true)
{
cin >> sex;
if (sex == 1 || sex == 2) {
abs->perArr[abs->m_size].m_sex = sex;
break;
}
cout << "输入有误,请重新输入:" << endl;
}
int age;
cout << "请输入年龄:" << endl;
cin >> age;
abs->perArr[abs->m_size].m_age = age;
string phone;
cout << "请输入号码:" << endl;
cin >> phone;
abs->perArr[abs->m_size].m_phone = phone;
string address;
cout << "请输入地址:" << endl;
cin >> address;
abs->perArr[abs->m_size].m_address = address;
cout << "修改成功,修改后的联系人信息为:" << endl;
cout << "姓名:" << abs->perArr[ret].m_name << "\t"
<< "性别:" << (abs->perArr[ret].m_sex == 1 ? "男" : "女") << "\t"
<< "年龄:" << abs->perArr[ret].m_age << "\t"
<< "号码:" << abs->perArr[ret].m_phone << "\t"
<< "地址:" << abs->perArr[ret].m_address << endl;
}
else {
cout << "查无此人" << endl;
}
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
//清空联系人
void clearPerson(Addressbooks* abs) {
int judge;
cout << "确认清空?确认请按2,其他键返回" << endl;
cin >> judge;
if (judge == 2) {
abs->m_size = 0; //将当前记录联系人的数量置为0,做逻辑清空操作
cout << "通讯录已清空!" << endl;
}
system("pause");
system("cls");
}
int main() {
Addressbooks abs;
person p;
abs.m_size = 0;
int select = 0;
while (true) {
showMenu();
cin >> select;
switch (select) {
case 1: //添加联系人
addPerson(&abs);//利用地址传递,可以修饰实参
break;
case 2: //显示联系人
showPerson(abs);
break;
case 3://按照姓名删除指定联系人
deletePerson(&abs);
break;
case 4: //查找联系人
findPerson(&abs);
break;
case 5: //修改联系人
modifyPerson(&abs);
break;
case 6: //清空联系人
clearPerson(&abs);
break;
case 0: //退出通讯录
cout << "欢迎下次使用!" << endl;
system("pause");
return 0;
break;
}
}
system("pause");
return 0;
}