目录:
一、c++开发环境搭建
二、入门代码学习
2.1、初始c++
2.2、数据类型
2.3、运算符
2.4、程序流程结构
2.5、数组
2.6、函数
2.7、指针
2.8、结构体
三、入门实战:通讯录管理系统
一、c++开发环境搭建
搜索Visual Studio软件,在官网选择社区版进行下载安装
双击安装包,主要勾选c++开发,其他功能模块可以根据实际需求进行勾选
然后选择好安装的路径,等待安装即可。
二、入门代码学习
2.1、初识c++
1、创建项目
2、创建文件
如果右侧没有解决方案资源管理器,可以在视图上点击添加
右键源文件添加新建项
进入到写代码的界面
首先写一个模板,后续都可以用这样的模型作为开始代码。
#include<iostream>
using namespace std;
int main()
{
system("pause");
return 0;
}
在Debug x86模式下,点击运行
弹出的界面没有任何内容
通过cout输出hello world 在弹出窗口
#include<iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
system("pause");
return 0;
}
3、注释介绍
c++中有单行注释和多行注释
单行注释的快捷键:ctrl+k+c
多行注释的快捷键:
取消注释:ctrl+k+u
有且只有一个main函数,否则会报错
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK2005 _main 已经在 02变量的创建和使用.obj 中定义 01c++写HelloWorld D:\csdn\c++\01c++写HelloWorld\01c++写HelloWorld\01书写helloworld.obj 1
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK1169 找到一个或多个多重定义的符号 01c++写HelloWorld D:\csdn\c++\01c++写HelloWorld\Debug\01c++写HelloWorld.exe 1
这里将main替换成main2就不会报错了
4、变量的创建和使用
变量存在的意义:方便我们管理内存空间。
一个16进制数地址代表一个内存,内存里面存放着一个数值10。
这里用变量a来代替这个地址,来管理数值10。即变量a来存储10这个数值。
#include<iostream>
using namespace std;
int main()
{
//变量创建的语法:数据类型 变量名 = 变量初始值
int a = 10;
cout << "a = " << a << endl;
system("pause");
return 0;
}
如果有多个c++代码.cpp文件,优先运行main函数,其他函数没有意义,因此除了要运行的代码为main,其他代码中的主函数修改其他名称,该代码运行后如不再使用,也将main修改成其他名称,如main1。
5、常量
常量用于记录程序中不可更改的数据
c++定义常量的两种方式 1:#define 宏常量 2:const修饰的变量
代码如下:
#include<iostream>
using namespace std;
//常量的定义方式
//1、#define 宏常量
#define Day 7
int main()
{
cout << "一周总共有:" <<Day<<"天" << endl;
system("pause");
return 0;
}
如果 在后续再定义则会报错,常量不可修改,一旦修改就会报错。
会提示严重性 代码 说明 项目 文件 行 禁止显示状态
错误(活动) E0137 表达式必须是可修改的左值 01c++写HelloWorld D:\csdn\c++\01c++写HelloWorld\01c++写HelloWorld\03常量.cpp 11
const常量代码如下:
#include<iostream>
using namespace std;
//常量的定义方式
//1、#define 宏常量
#define Day 7
int main()
{
//Day = 14;
cout << "一周总共有:" <<Day<<"天" << endl;
const int month = 12;
//month = 24; //错误,const修饰的变量也称为常量
cout << "一年总共有: " << month << " 个月份" << endl;
system("pause");
return 0;
}
如果month注释打开则会报错
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 C3892 “month”: 不能给常量赋值 01c++写HelloWorld D:\csdn\c++\01c++写HelloWorld\01c++写HelloWorld\03常量.cpp 15
6、关键词
作用是C++中预先保留的单词
如果用c++关键词命名则会报错
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 C2632 “int”后面的“int”非法 01c++写HelloWorld D:\csdn\c++\01c++写HelloWorld\01c++写HelloWorld\04关键词.cpp 7
#include<iostream>
using namespace std;
int main()
{
//在定义变量或常量时候,不要用关键字
//int int =10
system("pause");
return 0;
}
6、标识符命名规则
c++规定给标识符(变量、常量)命名时,有一套自己的规则
标识符不能是关键字
标识符只能由字母、数字、下划线组成
第一个字符必须为字母或下划线
标识符中字母区分大小写
如果不满足要求则会报错
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 C2059 语法错误:“user-defined literal” 01c++写HelloWorld D:\csdn\c++\01c++写HelloWorld\01c++写HelloWorld\05标识符命名规则.cpp 7
#include<iostream>
using namespace std;
int main()
{
//标识符第一个字符只能是字母或下划线
int 123abc = 40;
int abc = 10;
system("pause");
return 0;
}
int 123abc = 40;是不行的
2.2数据类型
1、整型
作用:整型变量表示的是整数类型的数据
#include <iostream>
using namespace std;
int main() {
//整型,区别:占用空间不同,取值范围不同
//1、短整型 取值范围(-32768~32767)
short num1 = 10;
//2、整型
int num2 = 10;
//3、长整型
long num3 = 10;
//4、长长整型
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.2、sizeof关键字
作用:利用sizeof关键字可以统计数据类型所占内存大小。
#include <iostream>
using namespace std;
int main() {
//整型:short (2字节) int (4字节) long (4字节) 1ong 1ong (8字节)
//可以利用sizeof求出数据类型占用内存大小
//语法:sizeof(数据类型 / 变量)
short num1 = 10;
cout << "shaort占用空间为:" << sizeof(short) << endl;
int num2 = 10;
cout << "int占用空间为:" << sizeof(num2) << endl;
system("pause");
return 0;
}
2.3、浮点型
作用:用于表示小数。
浮点型变显分为两种:1.单精度float,2.双精度double。
两者的区别在于表示的有效数字范围不同。
#include <iostream>;
using namespace std;
int main() {
//单精度 float
//双精度 double
float f1 = 3.1415926;
cout << "F1=" << f1 << endl;
double d1 = 3.14159263;
cout << "d1=" << d1 << endl;
//统计float和double占用空间
cout << "float占用空间为:" << sizeof(float) << endl;//4字节
cout << "double占用内存空间为:" << sizeof(double) << endl;//8字节
//科学技术法
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;
}
2.4、字符型
作用:字符型变量用于显示单个字符。
语法:char ch = 'a'
注意1:在显示字符型变量时,用单引号将字符括起来,不要用双引号。
注意2:单引号内只能有—个字符,不可以是字符串。
C和C++中字符型变品只占用1个字节。
字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元。
a-97;A-65
2.5、转义字符
作用:用于表示一些不能显示出来的ASCII字符。
现阶段常用转义字符:\n
\\
\t
#include <iostream>;
using namespace std;
int main() {
//换行符 \n
cout << "Hello world" << endl;
cout << "Hello world\n";//与上面加endl是一样的
//输出反斜杠
cout << "\\" << endl; //输出一个反斜杠
//水平制表符 \t
cout << "aaa\thelloworld" << endl;
cout << "aaaaa\thelloworld" << endl;
cout << "aaaa\thelloworld" << endl;
cout << "aaa helloworld" << endl;
cout << "aaaaa helloworld" << endl;
cout << "aaaa helloworld" << endl;
system("pause");
return 0;
}
2.6、字符串型
作用:用于表示—串字符。
C风格:char 变量名[ ] = “字符串值”
C++风格:string 变量名 = “字符串值”
//字符串型
#include<iostream>;
using namespace std;
#include<string>//使用C++风格字符串时,要调用头文件。
int main() {
//C语言字符串
char str[] = "Hello world";
cout << str << endl;
//C++字符串
string str2 = "hello world";
cout << str2 << endl;
system("pause");
return 0;
}
2.7、布尔类型bool
作用:布尔数据类型代去真或假的值。
True——真(代表1)
False——假(代表0)
//布尔型
#include<iostream>;
using namespace std;
int main() {
//创建bool数据类型
bool flag = true;
cout << flag << endl;
flag = false;
cout << flag << endl;
//查看bool类型所占字节
cout << "所占字节:"<<sizeof(bool) <<endl;
system("pause");
return 0;
}
2.8、数据的输入
作用:用于从键盘获取数据,输入的数据。
关键字: cin
语法:cln >>变量。
#include<iostream>;
using namespace std;
#include<string>
int main() {
/*
//整型
int a = 0;
cout << "整型变量a赋值:" << endl;
cin >> a;//使输入的等于a的整型
cout << "整型变量a = " << a <<endl;
*/
/*
//浮点型
float f = 3.14f;
cout << "浮点型变量f赋值:" << endl;
cin >> f;
cout << "浮点型变量f = " << f <<endl;
*/
//字符型
//char ch = 'a';
//cout << "字符型变量ch赋值:" << endl;
//cin >> ch;
//cout << "字符型变量ch = " << ch << endl;
//字符串型
//string str = "hello";
//cout << "给str赋值:" << endl;
//cin >> str;
//cout << "字符串str=" << str << endl;
//布尔型
bool flag = true;
cout << "给flag赋值:" << endl;
cin >> flag;
cout << "布尔类型flag=" << flag << endl;
system("pause");
return 0;
}
比如bool类型的flag输入非0就是1
2.3运算符
3.1、加减乘除与递增递减
注意:
被除数不能为0
除法操作的时候如果为int型会舍弃小数点
小数不能进行取余运算
#include<iostream>
using namespace std;
int main() {
//1.前置递增
int a = 10;
++a;
cout << "a = " << a << endl;
//1.后置递增
int b = 10;
b++;
cout << "b = " << b << endl;
//3.前置递增和后置递增的区别
//前置递增 先让变量+1 然后进行表达式运算
int a2 = 10;
int b2 = ++a2 * 10;
cout << "a2 = " << a2 << endl;//11
cout << "b2 = " << b2 << endl;//110
//后置递增 先进行表达式运算,后让变量+1
int a3 = 10;
int b3 = a3++ * 10;
cout << "a3 = " << a3 << endl;//11
cout << "b3 = " << b3 << endl;//100
system("pause");
return 0;
}
3.2、取模运算
#include<iostream>
using namespace std;
int main() {
//只有整数可以进行取余运算
//取模运算本质,就是求余数
int a1 = 10;
int b1=3;
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 d1 = 3.14;
double d2 = 1.1;
//cout << d1 % d2 << endl;
return 0;
}
3.3、赋值运算符
#include<iostream>
using namespace std;
int main() {
//赋值运算符
// =
int a = 10;
a = 100;
cout << "a=" << a << endl;//100
// +=
a = 10;
a += 2;
cout << "a=" << a << endl;//12
// -=
a = 10;
a -=2;
cout << "a=" << a << endl;//8
// *=
a = 10;
a *= 2;
cout << "a=" << a << endl;//20
// /=
a = 10;
a /= 2;
cout << "a=" << a << endl;//5
// %=
a = 10;
a %= 2;
cout << "a=" << a << endl;//0
return 0;
}
3.4、比较运算符
#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
return 0;
}
3.5、逻辑运算符
#include<iostream>
using namespace std;
int main() {
//01 逻辑运算符 非 !
int a =10;
// 在C++中 除了0,都为真
cout << !a << endl;//0
cout << !!a << endl;//1
//02 逻辑运算符 与 && 同真为真,其余为假
int a1 = 10;
int b1 = 10;
cout << (a1&&b1)<< endl;//1
a1 = 0;
b1 = 10;
cout << (a1&&b1)<< endl;//0
a1 = 0;
b1 = 0;
cout << (a1&&b1)<< endl;//0
//03 逻辑运算符 或 || 同假为假,其余为真
int a2 = 10;
int b2 = 10;
cout << (a2||b2) << endl;//1
a2 = 0;
b2 = 10;
cout << (a2||b2) << endl;//1
a2 = 0;
b2 = 0;
cout << (a2||b2) << endl;//0
return 0;
}
2.4程序流程结构
c++支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构
- 顺序结构:程序按顺序执行,不发生跳转
- 选择结构:依据条件是否满足,有选择的执行相应的功能
- 循环结构:依据条件是否满足,循环多次执行某段代码
1.1、选择结构-单行判断
#include<iostream>
using namespace std;
int main() {
//选择结构 单行if语句
//用户输入分数,如果分数大于600,视为考上一本大学,在屏幕上输出
int score = 0;
cout << "请输入一个分数:" << endl;
cin >> score;
cout << "您输入的分数为:" << score << endl;
if (score >= 600)//这里不要加分号,如果加了分号那么不论条件是否满足,后面的代码都会执行
{
cout << "考上了一本大学" << endl;
}
system("pause");
return 0;
}
选择结构-多行判断
#include<iostream>
using namespace std;
int main() {
//1、用户输入分数
int score = 0;
cout << "请输入一个分数:" << endl;
cin >> score;
//2、打印用户输入的分数
cout << "您输入的分数为:" << score << endl;
//3、判断是否大于600,如果大于,那么输出
if (score > 600)
{
cout << "恭喜 您考上了一本大学!";
}
else
{
cout << "未考上一本";
}
return 0;
}
选择结构-多条件语句
#include<iostream>
using namespace std;
int main() {
//1、用户输入分数
int score = 0;
cout << "请输入一个分数:" << endl;
cin >> score;
//2、打印用户输入的分数
cout << "您输入的分数为:" << score << endl;
//3、分数大于600,视为考上一本大学
//大于500,视为考上二本大学,屏幕输出
//大于400,视为考上三本大学,屏幕输出
//小于等于400,视为未考上本科
if (score > 600)
{
cout << "恭喜 您考上了一本大学!";
}
else if (score > 500)
{
cout << "恭喜 您考上了二本大学!";
}
else if (score > 400)
{
cout << "恭喜 您考上了二本大学!";
}
else
{
cout << "未考上本科";
}
return 0;
}
选择结构-嵌套if语句
#include<iostream>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
cout << "A=" << a << endl;
cout << "B=" << b << endl;
cout << "C=" << c << endl;
if (a>b)// a比b大
{
if (a>c)//a最大
{
cout << "A最大" << endl;
}
else
{
cout << "C最大" << endl;
}
}
else// b比a大
{
if (b > c)//b最大
{
cout << "B最大" << endl;
}
else
{
cout << "C最大" << endl;
}
}
return 0;
}
判断是否为闰年
#include<iostream>
using namespace std; //命名空间
int main() { //主函数
int year;
cin >> year;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//&&优先级更高
{
cout << "闰年" << endl;
}
else
{
cout << "不是闰年" << endl;
}
return 0;
}
三目运算符判断
若表达式1的值为真,则执行表达式2,并返回表达式2的结果
若表达式1的值为假,则执行表达式3,并返回表达式3的结果
#include<iostream>
using namespace std;
int main() {
//三目运算符
//创建3个变量 a b c
// 将a和b做比较,将变量大的值赋值给变量c
int a = 10;
int b = 0;
int c;
c=(a > b ? a : b);
cout << "C=" << c << endl;//10
//C++中三目运算符返回的是变量,可以继续赋值
(a > b ? a : b)=100;
cout << "A=" << a << endl;
cout << "B=" << b << endl;
return 0;
}
判断一个数是3还是5的倍数
#include<iostream>
using namespace std; //命名空间
int main() { //主函数
int num;
cout << "Please input a number:" << endl;
cin >> num;
//法1:
(num % 3== 0&&num%5==0) ?
cout << "yes" << endl :
cout << "no" << endl;
//法2:
(num % 3 == 0)?
((num%5==0) ? cout << "yes" << endl : cout << "no" << endl):
cout << "no" << endl;
return 0;
}
switch开关
1.switch语句中表达式类型只能是整型或字符型;
2.case里如果没有break,那么程序会一直向下执行。
#include<iostream>
using namespace std;
int main() {
//switch语句
//给电影进行打分
//10~9 经典
//8~7 非常好
//6~5 一般
//5以下 烂片
//1、提示用户给电影评分
cout << "请给电影评分" << endl;
//2、用户开始进行打分
int score;
cin >> score;
cout << "Score=" << score << endl;
//3、根据用户输入的分数来提示用户最后的结果
switch (score)
{
case 10:
cout << "您认为是经典电影" << endl;
break;//退出当前分支
case 9:
cout << "您认为是经典电影" << endl;
break;
case 8:
cout << "您认为是电影非常好" << endl;
break;
case 7:
cout << "您认为是电影非常好" << endl;
break;
case 6:
cout << "您认为是电影一般" << endl;
break;
case 5:
cout << "您认为是电影一般" << endl;
break;
default:
cout << "您认为是烂片" << endl;
break;
}
//if和switch区别
//switch 缺点,判断时候只能是整型或者字符型,不可以是一个区间
//switch 有点,结构清晰,执行效率高
return 0;
}
while循环猜数字
#include<iostream>
using namespace std;
#include<ctime>
int main() {
//添加随机数种子 作用利用当前系统时间生成随机数,防止每次随机数都一样
srand((unsigned int)time(NULL));
//1、系统生成随机数
int num = rand() % 100 + 1; //生成0~100的随机数
cout << num << endl;
//2、玩家进行猜测
cout << "请玩家输入猜测的数据:" << endl;
int val; //玩家输入的数据
while (1)
{
cin >> val;
//3、判断玩家的猜测
if (val > num)
{
cout << "猜测过大!" << endl;
}
else if(val < num)
{
cout << "猜测过小!" << endl;
}
else
{
cout << "猜对啦!" << endl;
break; //利用该关键字,退出循环
}
}
//猜对 退出游戏
//猜错 提示猜的结果,过大或者过小 重新返回第2步
return 0;
}
do...while
while与do...while的区别:
do...while无论while中条件是否为真,先执行{}内语句;
while中条件若为假,则不执行。
#include<iostream>
using namespace std;
int main() {
int num = 100;
do
{
int a = num % 10;// 个位
int b = num / 10 % 10; //十位
int c = num / 100; //百位
if (num == a*a*a+b*b*b+c*c*c)
{
cout << num << endl;
}
num++;
} while (num<1000);
return 0;
}
循环控制
break:跳出循环
遇负,则不进行累加,接着加下一个正数
#include <iostream>
using namespace std;
int main()
{
int i, n, sum;
sum = 0;
cout << "input 10 number" << endl;
for (i = 1; i <= 10; i++)
{
cout << i << ":";
cin >> n;
if (n < 0) //判断输入是否为负数,是负数就停止累加
break;
sum += n; //对输入的数进行累加
}
cout << "The Result :" << sum << endl;
return 0;
}
continue:跳出本次循环,继续下一次循环
#include <iostream>
using namespace std;
int main()
{
int i, n, sum;
sum = 0;
cout << "input 10 number" << endl;
for (i = 1; i <= 10; i++)
{
cout << i << ":";
cin >> n;
if (n < 0) //判断输入是否为负数
continue;
sum += n; //对输入的数进行累加
}
cout << "The Result :" << sum << endl;
return 0;
}
goto:跳转到label,接着往下走
跳转
累加1到10
#include <iostream>
using namespace std;
int main()
{
int ivar = 0; //定义一个整型变量,初始化为0
int num = 0; //定义一个整型变量,初始化为0
label: //定义一个标签
ivar++; //ivar自加1
num += ivar; //累加求和
if (ivar < 10) //判断ivar是否小于100
{
goto label; //转向标签
}
cout << ivar << num << endl;
return 0;
}
注意点:goto语句不能越过复合语句之外的变量定义的语句,例如,下面是非法的
goto label;
int i 10;
label:
cout << "goto" << endl;
正确的:
goto label;
{
int i 10;
}
label:
cout << "goto" << endl;
嵌套循环打印三角
#include<iostream>
using namespace std; //命名空间
int main() { //主函数
int i, j, k;
for (i = 1; i <= 5; i++) //控制行数
{
for (j = 1; j <= 5 - i; j++) //控制空格数
cout << " ";
for (k = 1; k <= 2 * i - 1; k++) //控制打印*号的数量
cout << "*";
cout << endl;
}
return 0;
}
嵌套循环输出乘法口诀
#include<iostream>
using namespace std;
int main() {
for (int i = 1; i < 10; i++)
{
for (int j = 1; j <= i; j++) {
cout << j << "*" << i << "=" << i * j << "\t";
}
cout << endl;
}
return 0;
}
2.5数组
所谓数组,就是一个集合,里面存放了相同类型的数据元素
**特点1:**数组中的每个数据元素都是相同的数据类型
**特点2:**数组是由连续的内存位置组成的
1.1、一维数组
一维数组定义的三种方式:
数据类型 数组名[ 数组长度 ];
数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
数据类型 数组名[ ] = { 值1,值2 ...};
#include<iostream>
using namespace std;
int main() {
//定义方式1
//数据类型 数组名[元素个数];
int score[10];
//利用下标赋值
score[0] = 100;
score[1] = 99;
score[2] = 85;
//利用下标输出
cout << score[0] << endl;
cout << score[1] << endl;
cout << score[2] << endl;
//第二种定义方式
//数据类型 数组名[元素个数] = {值1,值2 ,值3 ...};
//如果{}内不足10个数据,剩余数据用0补全
int score2[10] = { 100, 90,80,70,60,50,40,30,20,10 };
//逐个输出
//cout << score2[0] << endl;
//cout << score2[1] << endl;
//一个一个输出太麻烦,因此可以利用循环进行输出
for (int i = 0; i < 10; i++)
{
cout << score2[i] << endl;
}
//定义方式3
//数据类型 数组名[] = {值1,值2 ,值3 ...};
int score3[] = { 100,90,80,70,60,50,40,30,20,10 };
for (int i = 0; i < 10; i++)
{
cout << score3[i] << endl;
}
system("pause");
return 0;
}
注意:数组名是常量,不可以赋值
总结1:直接打印数组名,可以查看数组所占内存的首地址
总结2:对数组名进行sizeof,可以获取整个数组占内存空间的大小
冒泡排序
作用: 最常用的排序算法,对数组内元素进行排序
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值。
- 重复以上的步骤,每次比较次数-1,直到不需要比较
#include<iostream>
using namespace std;
int main() {
int arr[9] = { 4,2,8,0,5,7,1,3,9 };
for (int i = 0; i < 9 - 1; i++)
{
for (int j = 0; j < 9 - 1 - i; 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 < 9; i++)
{
cout << arr[i] << endl;
}
system("pause");
return 0;
}
二维数组
二维数组就是在一维数组上,多加一个维度。
二维数组定义的四种方式:
数据类型 数组名[ 行数 ][ 列数 ];
数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
建议:以上4种定义方式,利用第二种更加直观,提高代码的可读性
#include<iostream>
using namespace std;
int main() {
//方式1
//数组类型 数组名 [行数][列数]
int arr[2][3];
arr[0][0] = 1;
arr[0][1] = 2;
arr[0][2] = 3;
arr[1][0] = 4;
arr[1][1] = 5;
arr[1][2] = 6;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
cout << arr[i][j] << " ";
}
cout << endl;
}
//方式2
//数据类型 数组名[行数][列数] = { {数据1,数据2 } ,{数据3,数据4 } };
int arr2[2][3] =
{
{1,2,3},
{4,5,6}
};
//方式3
//数据类型 数组名[行数][列数] = { 数据1,数据2 ,数据3,数据4 };
int arr3[2][3] = { 1,2,3,4,5,6 };
//方式4
//数据类型 数组名[][列数] = { 数据1,数据2 ,数据3,数据4 };
int arr4[][3] = { 1,2,3,4,5,6 };
system("pause");
return 0;
}
总结:在定义二维数组时,如果初始化了数据,可以省略行数
二维数组数组名
- 查看二维数组所占内存空间
- 获取二维数组首地址
#include<iostream>
using namespace std;
int main() {
//二维数组数组名
int arr[2][3] =
{
{1,2,3},
{4,5,6}
};
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;
//地址
cout << "二维数组首地址:" << arr << endl;
cout << "二维数组第一行地址:" << arr[0] << endl;
cout << "二维数组第二行地址:" << arr[1] << endl;
cout << "二维数组第一个元素地址:" << &arr[0][0] << endl;
cout << "二维数组第二个元素地址:" << &arr[0][1] << endl;
system("pause");
return 0;
}
总结1:二维数组名就是这个数组的首地址
总结2:对二维数组名进行sizeof时,可以获取整个二维数组占用的内存空间大小
二维数组应用案例
考试成绩统计:
有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表,请分别输出三名同学的总成绩
#include<iostream>
using namespace std;
int main() {
int scores[3][3] =
{
{100,100,100},
{90,50,100},
{60,70,80},
};
string names[3] = { "张三","李四","王五" };
for (int i = 0; i < 3; i++)
{
int sum = 0;
for (int j = 0; j < 3; j++)
{
sum += scores[i][j];
}
cout << names[i] << "同学总成绩为: " << sum << endl;
}
system("pause");
return 0;
}
2.6函数
作用:将一段经常使用的代码封装起来,减少重复代码
一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。
函数的定义一般主要有5个步骤:
1、返回值类型
2、函数名
3、参数表列
4、函数体语句
5、return 表达式
函数的调用
功能:使用定义好的函数
语法:函数名(参数)
#include<iostream>
using namespace std;
//函数定义
int add(int num1, int num2) //定义中的num1,num2称为形式参数,简称形参
{
int sum = num1 + num2;
return sum;
}
int main() {
int a = 10;
int b = 10;
//调用add函数
int sum = add(a, b);//调用时的a,b称为实际参数,简称实参
cout << "sum = " << sum << endl;
a = 100;
b = 100;
sum = add(a, b);
cout << "sum = " << sum << endl;
system("pause");
return 0;
}
值传递
- 所谓值传递,就是函数调用时实参将数值传入给形参
- 值传递时,如果形参发生改变,并不会影响实参
#include<iostream>
using namespace std;
void swap(int num1, int num2)
{
cout << "交换前:" << endl;
cout << "num1 = " << num1 << endl;
cout << "num2 = " << num2 << endl;
// 10
// 20
int temp = num1;
num1 = num2;
num2 = temp;
cout << "交换后:" << endl;
cout << "num1 = " << num1 << endl;
cout << "num2 = " << num2 << endl;
// 20
// 10
//return ; 当函数声明时候,不需要返回值,可以不写return
}
int main() {
int a = 10;
int b = 20;
swap(a, b);
cout << "main中的 a = " << a << endl;
cout << "main中的 b = " << b << endl;
// 10
// 20
system("pause");
return 0;
}
总结: 值传递时,形参是修饰不了实参的
6.5 函数的常见样式
常见的函数样式有4种
- 无参无返
- 有参无返
- 无参有返
- 有参有返
//函数常见样式
//1、 无参无返
void test01()
{
//void a = 10; //无类型不可以创建变量,原因无法分配内存
cout << "this is test01" << endl;
//test01(); 函数调用
}
//2、 有参无返
void test02(int a)
{
cout << "this is test02" << endl;
cout << "a = " << a << endl;
}
//3、无参有返
int test03()
{
cout << "this is test03 " << endl;
return 10;
}
//4、有参有返
int test04(int a, int b)
{
cout << "this is test04 " << endl;
int sum = a + b;
return sum;
}
函数的声明
作用: 告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
函数的声明可以多次,但是函数的定义只能有一次
#include<iostream>
using namespace std;
//声明可以多次,定义只能一次
//声明
int max(int a, int b);
int max(int a, int b);
//定义
int max(int a, int b)
{
return a > b ? a : b;
}
int main() {
int a = 100;
int b = 200;
cout << max(a, b) << endl;
system("pause");
return 0;
}
函数的分文件编写
作用:让代码结构更加清晰
函数分文件编写一般有4个步骤
- 创建后缀名为.h的头文件
- 创建后缀名为.cpp的源文件
- 在头文件中写函数的声明
- 在源文件中写函数的定义
//swap.h文件
#include<iostream>
using namespace std;
//实现两个数字交换的函数声明
void swap(int a, int b);
//swap.cpp文件
#include "swap.h"
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
//main函数文件
#include "swap.h"
int main() {
int a = 100;
int b = 200;
swap(a, b);
system("pause");
return 0;
}
2.7指针
指针的作用: 可以通过指针间接访问内存
- 内存编号是从0开始记录的,一般用十六进制数字表示
- 可以利用指针变量保存地址
指针变量定义语法: 数据类型 * 变量名;
#include<iostream>
using namespace std;
int main() {
//1、指针的定义
int a = 10; //定义整型变量a
//指针定义语法: 数据类型 * 变量名 ;
int* p;
//指针变量赋值
p = &a; //指针指向变量a的地址
cout << &a << endl; //打印数据a的地址
cout << p << endl; //打印指针变量p
//0073F8BC
//0073F8BC
//2、指针的使用
//通过*操作指针变量指向的内存
cout << "*p = " << *p << endl;
// *p = 10
system("pause");
return 0;
}
指针变量和普通变量的区别
- 普通变量存放的是数据,指针变量存放的是地址
- 指针变量可以通过" * "操作符,操作指针变量指向的内存空间,这个过程称为解引用
总结1: 我们可以通过 & 符号 获取变量的地址
总结2:利用指针可以记录地址
总结3:对指针变量解引用,可以操作指针指向的内存
指针所占内存空间
#include<iostream>
using namespace std;
int main() {
int a = 10;
int * p;
p = &a; //指针指向数据a的地址
cout << *p << endl; //* 解引用
cout << sizeof(p) << endl;
cout << sizeof(char *) << endl;
cout << sizeof(float *) << endl;
cout << sizeof(double *) << endl;
system("pause");
return 0;
}
总结:所有指针类型在32位操作系统下是4个字节
空指针和野指针
空指针:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的
空指针:
int main() {
//指针变量p指向内存地址编号为0的空间
int * p = NULL;
//访问空指针报错
//内存编号0 ~255为系统占用内存,不允许用户访问
cout << *p << endl;
system("pause");
return 0;
}
野指针:指针变量指向非法的内存空间
#include<iostream>
using namespace std;
int main() {
//指针变量p指向内存地址编号为0x1100的空间
int* p = (int*)0x1100;
//访问野指针报错
cout << *p << endl;
system("pause");
return 0;
}
总结:空指针和野指针都不是我们申请的空间,因此不要访问。
const修饰指针
const修饰指针有三种情况
- const修饰指针 — 常量指针
- const修饰常量 — 指针常量
- const既修饰指针,又修饰常量
#include<iostream>
using namespace std;
int main() {
int a = 10;
int b = 10;
//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;
}
指针和数组
#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");
return 0;
}
指针和函数
作用:利用指针作函数参数,可以修改实参的值
#include<iostream>
using namespace std;
//值传递
void swap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
//地址传递
void swap2(int* p1, int* p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main() {
int a = 10;
int b = 20;
swap1(a, b); // 值传递不会改变实参
swap2(&a, &b); //地址传递会改变实参
cout << "a = " << a << endl;
cout << "b = " << b << endl;
system("pause");
return 0;
}
指针、数组、函数案例
封装一个函数,利用冒泡排序,实现对整型数组的升序排序
例如数组:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
#include<iostream>
using namespace std;
//冒泡排序函数
void bubbleSort(int* arr, int len) //int * arr 也可以写为int arr[]
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
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] << endl;
}
}
int main() {
int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
int len = sizeof(arr) / sizeof(int);
bubbleSort(arr, len);
printArray(arr, len);
system("pause");
return 0;
}
总结:当数组名传入到函数作为参数时,被退化为指向首元素的指针
结构体
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
语法:struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
- struct 结构体名 变量名
- struct 结构体名 变量名 = { 成员1值 , 成员2值…}
- 定义结构体时顺便创建变量
#include<iostream>
using namespace std;
//结构体定义
struct student
{
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
}stu3; //结构体变量创建方式3
int main() {
//结构体变量创建方式1
struct student stu1; //struct 关键字可以省略
stu1.name = "张三";
stu1.age = 18;
stu1.score = 100;
cout << "姓名:" << stu1.name << " 年龄:" << stu1.age << " 分数:" << stu1.score << endl;
//结构体变量创建方式2
struct student stu2 = { "李四",19,60 };
cout << "姓名:" << stu2.name << " 年龄:" << stu2.age << " 分数:" << stu2.score << endl;
stu3.name = "王五";
stu3.age = 18;
stu3.score = 80;
cout << "姓名:" << stu3.name << " 年龄:" << stu3.age << " 分数:" << stu3.score << endl;
system("pause");
return 0;
}
总结1:定义结构体时的关键字是struct,不可省略
总结2:创建结构体变量时,关键字struct可以省略
总结3:结构体变量利用操作符 ‘’.’’ 访问成员
结构体数组
作用:将自定义的结构体放入到数组中方便维护
语法:struct 结构体名 数组名[元素个数] = { {} , {} , ... {} }
#include<iostream>
using namespace std;
//结构体定义
struct student
{
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
int main() {
//结构体数组
struct student arr[3] =
{
{"张三",18,80 },
{"李四",19,60 },
{"王五",20,70 }
};
for (int i = 0; i < 3; i++)
{
cout << "姓名:" << arr[i].name << " 年龄:" << arr[i].age << " 分数:" << arr[i].score << endl;
}
system("pause");
return 0;
}
结构体指针
作用:通过指针访问结构体中的成员
- 利用操作符
->
可以通过结构体指针访问结构体属性
#include<iostream>
using namespace std;
//结构体定义
struct student
{
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
int main() {
struct student stu = { "张三",18,100, };
struct student* p = &stu;
p->score = 80; //指针通过 -> 操作符可以访问成员
cout << "姓名:" << p->name << " 年龄:" << p->age << " 分数:" << p->score << endl;
system("pause");
return 0;
}
结构体嵌套结构体
作用: 结构体中的成员可以是另一个结构体
例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体
#include<iostream>
using namespace std;
//学生结构体定义
struct student
{
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
//教师结构体定义
struct teacher
{
//成员列表
int id; //职工编号
string name; //教师姓名
int age; //教师年龄
struct student stu; //子结构体 学生
};
int main() {
struct teacher t1;
t1.id = 10000;
t1.name = "老王";
t1.age = 40;
t1.stu.name = "张三";
t1.stu.age = 18;
t1.stu.score = 100;
cout << "教师 职工编号: " << t1.id << " 姓名: " << t1.name << " 年龄: " << t1.age << endl;
cout << "辅导学员 姓名: " << t1.stu.name << " 年龄:" << t1.stu.age << " 考试分数: " << t1.stu.score << endl;
system("pause");
return 0;
}
总结:在结构体中可以定义另一个结构体作为成员,用来解决实际问题
结构体做函数参数
作用:将结构体作为参数向函数中传递
传递方式有两种:
- 值传递
- 地址传递
#include<iostream>
using namespace std;
//学生结构体定义
struct student
{
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
//值传递
void printStudent(student stu)
{
stu.age = 28;
cout << "子函数中 姓名:" << stu.name << " 年龄: " << stu.age << " 分数:" << stu.score << endl;
}
//地址传递
void printStudent2(student* stu)
{
stu->age = 28;
cout << "子函数中 姓名:" << stu->name << " 年龄: " << stu->age << " 分数:" << stu->score << endl;
}
int main() {
student stu = { "张三",18,100 };
//值传递
printStudent(stu);
cout << "主函数中 姓名:" << stu.name << " 年龄: " << stu.age << " 分数:" << stu.score << endl;
cout << endl;
//地址传递
printStudent2(&stu);
cout << "主函数中 姓名:" << stu.name << " 年龄: " << stu.age << " 分数:" << stu.score << endl;
system("pause");
return 0;
}
总结:如果不想修改主函数中的数据,用值传递,反之用地址传递
结构体中 const使用场景
作用:用const来防止误操
#include<iostream>
using namespace std;
//学生结构体定义
struct student
{
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
//const使用场景
void printStudent(const student* stu) //加const防止函数体中的误操作
{
//stu->age = 100; //操作失败,因为加了const修饰
cout << "姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;
}
int main() {
student stu = { "张三",18,100 };
printStudent(&stu);
system("pause");
return 0;
}
通讯录管理系统
通讯录是一个可以记录亲人、好友信息的工具
本教程主要利用C++来实现一个通讯录管理系统
系统中需要实现的功能如下:
- 添加联系人:向通讯录中添加新人,信息包括(姓名、性别、年龄、联系电话、家庭住址)最多1000人
- 显示联系人:显示通讯录中所有联系人信息
- 删除联系人:按照姓名进行删除指定联系人
- 查找联系人:按照姓名查看指定联系人信息
- 修改联系人:按照姓名重新修改指定联系人信息
- 清空联系人:清空通讯录中所有信息
- 退出通讯录:退出当前使用的通讯录
#include <iostream>
#include <string>
using namespace std;
//1. 菜单
void showMenu()
{
cout << "*************************" << endl;
cout << "***** 1、添加联系人 *****" << endl;
cout << "***** 2、显示联系人 *****" << endl;
cout << "***** 3、删除联系人 *****" << endl;
cout << "***** 4、查找联系人 *****" << endl;
cout << "***** 5、修改联系人 *****" << endl;
cout << "***** 6、清空联系人 *****" << endl;
cout << "***** 7、退出通讯录 *****" << endl;
cout << "*************************" << endl;
}
//设计联系人结构体
struct Person
{
string m_Name;
int m_Sex;
int m_Age;
string m_Phone;
string m_Addr;
};
//设计通讯录结构体
//#define MAX 1000 //最大人数
const int MAX = 1000;
struct Addressbooks
{
struct Person personArray[MAX];
int m_Size = NULL;
};
//添加联系人
void addPerson(Addressbooks* abs)
{
//判断通讯录是否已满,如果满了就不再添加
if (abs->m_Size == MAX)
{
cout << "通讯录已满,无法添加!" << endl;
return;
}
else
{
//添加具体联系人
//姓名
string name;
cout << "请输入姓名: " << endl;
cin >> name;
abs->personArray[abs->m_Size].m_Name = name;
//性别
int sex;
cout << "请输入性别: " << endl;
cout << "1 --- 男" << endl;
cout << "2 --- 女" << endl;
while (true)
{
// 判断输入性别是否符合要求,否则一直循环输入
cin >> sex;
if (sex == 1 || sex == 2)
{
abs->personArray[abs->m_Size].m_Sex = sex;
break;
}
else
{
cout << "性别输入有误,请重新输入!" << endl;
}
}
//年龄
cout << "请输入年龄: " << endl;
int age;
cin >> age;
abs->personArray[abs->m_Size].m_Age = age;
//电话
cout << "请输入联系电话: " << endl;
string phone;
cin >> phone;
abs->personArray[abs->m_Size].m_Phone = phone;
//地址
cout << "请输入地址: " << endl;
string address;
cin >> address;
abs->personArray[abs->m_Size].m_Addr = address;
//更新通讯录人数
abs->m_Size++;
cout << "添加成功!" << endl;
}
system("pause"); //请按任意键继续
system("cls"); //清屏操作
}
//显示所有联系人
void showPerson(Addressbooks* abs)
{
if (abs->m_Size == 0)
{
cout << "通讯录为空!" << endl;
}
else
{
for (int i = 0; i < abs->m_Size; i++)
{
cout << "姓名: " << abs->personArray[i].m_Name << "\t";
cout << "性别: " << (abs->personArray[i].m_Sex == 1 ? "男" : "女") << "\t";
cout << "年龄: " << abs->personArray[i].m_Age << "\t";
cout << "电话: " << abs->personArray[i].m_Phone << "\t";
cout << "住址: " << abs->personArray[i].m_Addr << endl;
}
}
system("pause");
system("cls");
}
//检测联系人是否存在,如果存在,返回联系人所在数组中的具体位置,不存在返回-1
//参数1 通讯录 参数2 对比姓名
int isExist(Addressbooks* abs, string name)
{
for (int i = 0; i < abs->m_Size; i++)
{
if (abs->personArray[i].m_Name == name)
{
return i;
}
}
return -1; //如果遍历结束都没有找到,则返回-1;
}
//删除指定的联系人
void deletePerson(Addressbooks* abs)
{
cout << "请输入要删除的联系人姓名" << endl;
string name;
cin >> name;
int ret = isExist(abs, name);
if (ret != -1)
{
//查找到人,要进行删除操作
for (int i = ret; i < abs->m_Size; i++)
{
//数据前移覆盖
abs->personArray[i] = abs->personArray[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 = isExist(abs, name);
if (ret != -1)
{
cout << "姓名:" << abs->personArray[ret].m_Name << "\t";
cout << "性别:" << abs->personArray[ret].m_Sex << "\t";
cout << "年龄:" << abs->personArray[ret].m_Age << "\t";
cout << "电话:" << abs->personArray[ret].m_Phone << "\t";
cout << "地址:" << abs->personArray[ret].m_Addr << endl;
}
else
{
cout << "查无此人" << endl;
}
system("pause");
system("cls");
}
//修改指定联系人信息
void modifyPerson(Addressbooks* abs)
{
cout << "请输入要修改的联系人姓名" << endl;
string name;
cin >> name;
int ret = isExist(abs, name);
if (ret != -1)
{
//姓名
string name;
cout << "请输入姓名: " << endl;
cin >> name;
abs->personArray[ret].m_Name = name;
//性别
int sex;
cout << "请输入性别: " << endl;
cout << "1 --- 男 " << endl;
cout << "2 --- 女 " << endl;
while (true) {
cin >> sex;
if (sex == 1 || sex == 2)
{
abs->personArray[ret].m_Sex = sex;
break;
}
cout << "输入有无,请重新输入" << endl;
}
//年龄
cout << "请输入年龄:" << endl;
int age;
cin >> age;
abs->personArray[ret].m_Age = age;
//电话
cout << "请输入联系电话:" << endl;
int phone;
cin >> phone;
abs->personArray[ret].m_Phone = phone;
//地址
cout << "请输入地址:" << endl;
string address;
cin >> address;
abs->personArray[ret].m_Addr = address;
cout << "修改成功!" << endl;
}
else
{
cout << "查无此人" << endl;
}
system("pause");
system("cls");
}
//清空联系人
void cleanPerson(Addressbooks* abs)
{
abs->m_Size = 0;
cout << "通讯录已清空" << endl;
system("pause");
system("cls");
}
int main()
{
//创建通讯录结构体变量
Addressbooks abs;
//初始化通讯录中当前人员个数
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:
cleanPerson(&abs);
break;
case 0:
cout << "欢迎下次使用" << endl;
system("pause");
return 0;
break;
default:
break;
}
}
system("pause");
return 0;
}