课程链接:https://www.bilibili.com/video/BV1et411b73Z
作用:在代码中加一些说明SEO靠我和解释,方便自己或其他程序员阅读代码
CPP的注释有两种格式:
单行注释: // 描述信息 通常放在一行代码的上方,或者一条语句的末尾,对该行代码说明 多行注释: /* 描述信息 */ 通常放在一段代码的SEO靠我上方,对该段代码做整体说明Note: 编译器在编译代码时,会忽略注释的内容
#include <iostream> using namespace std;/*main是一个程序的入口,SEO靠我每个程序都必须有这么一个函数,有且仅有一个 */ int main() {// 在屏幕中输出Hello Worldcout << "Hello World" << enSEO靠我dl;system("pause");return 0; }作用:给一段指定的内存空间起名,方便操作这段内存
语法:数据类型 变量名 = 初始值;示例:
#include<ioSEO靠我stream> using namespace std;int main() {// 变量创建的语法:数据类型 变量名 = 变量初始值int a = 10;cout << "a = "SEO靠我 << a << endl; // a = 10system("pause");return 0; }作用:用于记录程序中不可更改的数据
C++定义常量的两种方式:
#defiSEO靠我ne 宏常量: #define 常量名 常量值 通常在文件上方定义,表示一个常量 const修饰的变量: const 数据类型 常量名 = 常量值 通常在变量定义前加关键字const,修饰该变量为常量SEO靠我,不可修改const: 英[kɒnst] 美[kɑnst]
adj. 恒定的; 不变的;
n. 常数; 恒量;示例:
#include <iostream> using namespace SEO靠我std;/* 常量的定义方式1. #define 宏常量 -> #define 常量名 常量值2. const修饰的变量 -> const 数据类型 常量名 = 常量值 SEO靠我 */#define Day 7int main() {cout << "一周总共有: " << Day << " 天" << endl; // 一周总共有: 7 天const int month =SEO靠我 12; // const修饰的变量也称为常量cout << "一年总共有: " << month << " 个月份" << endl; // 一年总共有: 12 个月份system("pause")SEO靠我;return 0; }作用:关键字是C++中预先保留的单词(标识符)
在定义变量或常量时,不要覆盖关键字!C++关键字如下:
关键字asmdoifreturntypedefSEO靠我autodoubleinlineshorttypeidbooldynamic_castintsignedtypenamebreakelselongsizeofunioncaseenummutablesSEO靠我taticunsignedcatchexplicitnamespacestatic_castusingcharexportnewstructvirtualclassexternoperatorswitSEO靠我chvoidconstfalseprivatetemplatevolatileconst_castfloatprotectedthiswchar_tcontinueforpublicthrowwhilSEO靠我edefaultfriendregistertruedeletegotoreinterpret_casttryNote:在给变量或常量起名时,不要使用CPP的关键字,否则会产生歧义。
示例:
#incluSEO靠我de <iostream> using namespace std;int main() {// 创建变量时变量名使用关键字int true = 10; // 不能使用关键字作为变量名SEO靠我,会报错!system("pause");return 0; }作用:C++规定给标识符(变量、常量)命名时,有一套自己的规则:
标识符不能是关键字标识符只能由字母SEO靠我、数字、下划线组成第一个字符必须为字母或下划线(不能以数字开头)标识符中字母区分大小写建议:给标识符命名时,争取做到见名知意的效果,方便自己和他人阅读
#include <iostream>using SEO靠我namespace std;/*1. 标识符不能是关键字2. 标识符只能由字母、数字、下划线组成3. 第一个字符必须为字母或下划线(不能以数字开头)4. 标识符中字母区分大小写 */ SEO靠我 int main() {// 1. 标识符不能是关键字// int int = 10; // 错误// 2. 标识符只能由字母、数字、下划线组成int abc = 10;int _abSEO靠我c = 20;int _123abc = 30;// 3. 第一个字符必须为字母或下划线(不能以数字开头)// int 123abc = 40; // 错误// 4. 标识符中字母区分大小写int aSEO靠我aa = 100;int AAA = 300;cout << aaa << endl; // 100cout << AAA << endl; // 300system("pause");return SEO靠我0; }C++规定在创建一个变量或常量时,必须要指定出相应的数据类型,否则无法给变量分配内存。
数据类型存在的意义是给变量分配合适的内存空间。
作用:整型变量表示SEO靠我的是整数类型的数据。C++中能够表示整型的类型有以下几种方式,区别在于所占用的空间不同:
数据类型占用空间取值范围short(短整型)2字节(−215∼215−1)(-2^{15} \sim 2^{15SEO靠我} - 1)(−215∼215−1) ⇔\Leftrightarrow⇔ (−32,768∼32,767)(-32,768 \sim 32,767)(−32,768∼32,767)int(整型)4字节SEO靠我(−231∼231−1)(-2^{31} \sim 2^{31} - 1)(−231∼231−1) ⇔\Leftrightarrow⇔ (−2,147,483,648∼2,147,483,647)(-SEO靠我2,147,483,648 \sim 2,147,483,647)(−2,147,483,648∼2,147,483,647)long(长整型)Windows为4字节,Linux为4字节(32位),8SEO靠我字节(64位)(−231∼231−1)(-2^{31} \sim 2^{31} - 1)(−231∼231−1) ⇔\Leftrightarrow⇔ (−2,147,483,648∼2,147,483SEO靠我,647)(-2,147,483,648 \sim 2,147,483,647)(−2,147,483,648∼2,147,483,647)long long(长长整型)8字节(−263∼263−1)SEO靠我(-2^{63} \sim 2^{63} - 1)(−263∼263−1) ⇔\Leftrightarrow⇔ (−9,223,372,036,854,775,808∼9,223,372,036,85SEO靠我4,775,807)(-9,223,372,036,854,775,808 \sim 9,223,372,036,854,775,807)(−9,223,372,036,854,775,808∼9,2SEO靠我23,372,036,854,775,807)在日常开发中,int是最常用的。
#include<iostream> using namespace std;/*整型:1. 短整型 shSEO靠我ort2. 整型 int3. 长整型 long4. 长长整型 long long */ int main() {// 1. 短整型 short (−32,768 ~ 3SEO靠我2,767)short num1 = 10;// 2. 整型 int (−2,147,483,648 ~ 2,147,483,647)int num2 = 10;// 3. 长整型 long (−2,SEO靠我147,483,648 ~ 2,147,483,647)long num3 = 10;// 4. 长长整型 long long ((−9,223,372,036,854,775,808 ~ 9,223SEO靠我,372,036,854,775,807))long long num4 = 10; cout << "num1: " << num1 << endl; // num1: 10cout << "numSEO靠我2: " << num2 << endl; // num2: 10cout << "num3: " << num3 << endl; // num3: 10cout << "num4: " << nuSEO靠我m4 << endl; // num4: 10cout << "-------------------" << endl;/*探讨越界的情况:当出现超过表示范围的数时,会自动轮到开头*/// 1. 短SEO靠我整型 short (−32768~32767)short ol_num1 = 32768;cout << "ol_num1: " << ol_num1 << endl; // ol_num1: -32SEO靠我768// 2. 整型 int (−2,147,483,648 ~ 2,147,483,647)int ol_num2 = 2147483648;cout << "ol_num2: " << ol_nSEO靠我um2 << endl; // ol_num2: -2147483648// 3. 长整型 long (−2,147,483,648 ~ 2,147,483,647)long ol_num3 = 21SEO靠我47483648;cout << "ol_num3: " << ol_num3 << endl; // ol_num3: -2147483648// 4. 长长整型 long long ((−9,22SEO靠我3,372,036,854,775,808 ~ 9,223,372,036,854,775,807))long long ol_num4 = 9223372036854775808;cout << "SEO靠我ol_num4: " << ol_num4 << endl; // ol_num4: -9223372036854775808system("pause");return 0; }作用:利用sizeof关键字可以统计数据类型所占内存的大小。
语法:sizeof(数据类型 / 变量)
示例:
#include<iostream> using namSEO靠我espace std;int main() {/*使用sizeof求出数据类型/变量所占的内存大小*/short num1 = 10;cout << "short占用的内存空间为: " << sizeSEO靠我of(short) << endl; // short占用的内存空间为: 2cout << "num1变量对应的数据类型所占用的内存空间为: " << sizeof(num1) << endl; //SEO靠我 num1变量对应的数据类型所占用的内存空间为: 2int num2 = 10;cout << "int占用的内存空间为: " << sizeof(int) << endl; // int占用的内存空SEO靠我间为: 4long num3 = 10;cout << "long占用的内存空间为: " << sizeof(long) << endl; // long占用的内存空间为: 4long long nuSEO靠我m4 = 10;cout << "long long占用的内存空间为: " << sizeof(long long) << endl; // long long占用的内存空间为: 8system("pSEO靠我ause");return 0; }作用:用于表示小数。
浮点型变量分为两种:
单精度: float双精度: double两者的区别在于表示的有效数字范围不同。
数据类SEO靠我型占用空间有效数字范围float4字节7位有效数字double8字节15~16位有效数字有效数字包含小数点前面和后面的!
需要注意的是,在写float类型时,数字后面加上一个f,例如:
float numSEO靠我 = 3.14f;因为如果不加f,那么编译器看到小数会默认它为double,还需要将double转为为float,这样会多一步。
示例:
#include <iostream> usingSEO靠我 namespace std;int main() {// 1. 单精度 float// 2. 双精度 doublefloat f1 = 3.1415126f; // 一般会在后面写一个f// endSEO靠我l = end linecout << "f1: " << f1 << endl; // f1: 3.14151double d1 = 3.1415126;cout << "d1: " << d1 <SEO靠我< endl; // d1: 3.14151// 统计float和double占用的内存空间cout << "float占用的内存空间: " << sizeof(float) << "字节" << eSEO靠我ndl; // float占用的内存空间: 4字节cout << "double占用的内存空间: " << sizeof(double) << "字节" << endl; // double占用的内存SEO靠我空间: 8字节// 科学计数法float f2 = 3e2f; // 3 * 10^2double d2 = 3e-2; // 3 * 10^-2cout << "f2: " << f2 << endSEO靠我l; // f2: 300cout << "d2: " << d2 << endl; // d2: 0.03system("pause");return 0; }默认情况下,CPP显示SEO靠我一个小数最多显示6位小数。
作用:字符型变量用于显示单个字符
语法:char ch = a;
注意:
在显示字符型变量时,用单引号将字符括起来,不要使用双引号单引号内只能有一个字符,不可以是字符SEO靠我串字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元C和CPP中字符型变量只占用1个字节字节字节,就是一个英文单词所占用的大小,所以对于char,在空间中就是占一个字节SEO靠我。
需要记忆的ASCII码值:
a: 97A: 65示例:
#include<iostream> using namespace std;int main() {// 1. 字符型变量的创建SEO靠我方式char ch = a;cout << "ch: " << ch << endl; // ch: a// 2. 字符型变量所占用内存大小cout << "char所占的内存大小: " << sizSEO靠我eof(char) << "字节" << endl; // char所占的内存大小: 1字节// 3. 字符型变量常见错误// char ch2 = "a"; // 不能用双引号创建字符// charSEO靠我 ch3 = abcdef; // 不能用单引号创建字符串// 4. 字符型变量对应的ASCII编码// (数据类型)变量: 将变量强转为指定的数据类型cout << (int)ch << endl;SEO靠我 // 97cout << (int)A << endl; // 65system("pause");return 0; }ASCII码大致由以下两部分组成:
ASCII非打印控制字符:ASCII表上的数字0 ~ 31分SEO靠我配给了控制字符,用于控制像打印机等一些外围设备。ASCII打印字符:数字32 ~ 126分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。作用:用于表示一些不能显示出来的ASCSEO靠我II字符
现阶段我们常用的转义字符有:
\n\\\t 重要转义字符含义ASCII码值(十进制)\a报警007\b退格(BS), 将当前位置移到前一列008\f换页(FF), 将当前位置移到SEO靠我下页开头012⭐️\n换行(LF), 将当前位置移到下一行开头010⭐️\r回车(CR), 将当前位置移到本行开头013⭐️\t水平制表(HT), 跳到下一个TAB位置009\v垂直制表(VT)011SEO靠我⭐️\\代表一个反斜线字符\092\代表一个单引号(撇号)字符039\"代表一个双引号字符034\0代表一个问号000\ddd8进制转义字符, d范围0~73位8进制\xhh16进制转义字符, h范围SEO靠我0~9, a~f, A~F3位16进制注意:
\r表示将当前的光标移动到行首,但不会移动到下一行;\n表示将光标移动到下一行,但不会移动到行首。单独一个\r或\n都不是一般意义上的回车,\r\n放在一起SEO靠我才是。通常在写程序的时候只要一个\n就可以了,这是因为编译器会自动将\n替换成\r\n。
示例:
#include<iostream> using namespace std;int maSEO靠我in() {// 1. 换行符 \ncout << "hello wolrd";/*hello wolrd请按任意键继续. . .*/cout << "hello wolrd\n";/*hello wSEO靠我olrd请按任意键继续. . .*/// 2. 反斜杠 \\ cout << "\\" << endl; // \ // 3. 水平制表符 \t 可以整齐地输出数据cout << "aSEO靠我aa\thello world" << endl;/*aaa hello world请按任意键继续. . .*/cout << "a\thello world" << endl;cout << "abSEO靠我\thello world" << endl;cout << "abc\thello world" << endl;cout << "abcd\thello world" << endl;/*a heSEO靠我llo worldab hello worldabc hello worldabcd hello world请按任意键继续. . .*/// 4. 回车 \rcout << "abc\rdefg" <SEO靠我< endl; // defg(回车会让光标回到行首,因此defg覆盖掉了abc)cout << "123\r\n"; // \r\n表示开始下一行并回到行首/*\r表示将当前的光标移动到行首,但不会SEO靠我移动到下一行;\n表示将光标移动到下一行,但不会移动到行首。单独一个\r或\n都不是一般意义上的回车,\r\n放在一起才是。通常在写程序的时候只要一个\n就可以了,这是因为编译器会自动将\n替换成\rSEO靠我\n。*/system("pause");return 0; }作用:用于表示一串字符。
两种风格:
C语言风格字符串:char 变量名[] = "字符串值"; -> chSEO靠我ar str1[] = "Hello World";C++语言风格字符串: string 变量名 = "字符串值";注意:
C语言风格的字符串要用双引号括起来C++风格字符串需要加入头文件#includSEO靠我e <string>示例:
#include <iostream> using namespace std; #include <string>int main() {/SEO靠我/ 1. C风格字符串char str_c[] = "Hello World";cout << str_c << endl; // Hello World// 2. C++风格字符串(使用的时候需要引SEO靠我入string头文件)string str_cpp = "Hello World";cout << str_cpp << endl; // Hello World// 看一下两种字符串占空间的大小coSEO靠我ut << "C大小: " << sizeof(str_c) << "字节" << endl; // C大小: 12字节cout << "C++大小: " << sizeof(string) << "SEO靠我字节" << endl; // C++大小: 40字节system("pause");return 0; }作用:布尔数据类型表示真或假的值
bool类型只有两个值:
trSEO靠我ue: 真 (本质是1)false: 假 (本质是0)bool类型占1个字节大小(因为本质上是数字1/0)
语法:bool 变量名 = true/false;
示例:
#include <iostream>SEO靠我, <string> using namespace std;int main() {// 1. 创建bool数据类型bool flag_1 = true;bool flag_2 = SEO靠我false;cout << flag_1 << endl; // 1cout << flag_2 << endl; // 0// 2. 查看bool数据类型占用空间大小cout << "bool数据类SEO靠我型占 " << sizeof(bool) << " 字节" << endl; // bool数据类型占 1 字节system("pause");return 0; }作用:用于从键盘获取数据
关键字:cin
语法:cin >> 变量
示例:
#include<iostream> #include<string> using namespacSEO靠我e std;int main() {// 1. 整型int a = 0;cout << "请给整型变量a赋值: " << endl;cin >> a; // 请给整型变量a赋值:cout << "整型SEO靠我变量a = " << a << endl; // 整型变量a = 100// 2. 浮点型float f = 3.14f;cout << "请给浮点型变量f赋值: " << endl;cin >> fSEO靠我; // 请给浮点型变量f赋值:cout << "浮点型变量f = " << f << endl; // 浮点型变量f = 7.77// 3. 字符型char ch = a;cout << "请给字符SEO靠我型变量ch赋值: " << endl;cin >> ch; // 请给字符型变量ch赋值:cout << "字符型变量ch = " << ch << endl; // 字符型变量ch = b// 4.SEO靠我 字符串型string str = "None";cout << "请给字符串型变量str赋值: " << endl;cin >> str;cout << "字符串型变量str = " << str SEO靠我<< endl; // 字符串型变量str = "Hello"// 5. boolbool flag = false;cout << "请给bool型变量flag赋值: " << endl;cin >SEO靠我> flag; // bool类型只要是非0的值都代表真cout << "bool型变量flag = " << flag << endl; // bool型变量bool = "1"/*请给整型变量a赋SEO靠我值:100整型变量a = 100请给浮点型变量f赋值:3.3浮点型变量f = 3.3请给字符型变量ch赋值:b字符型变量ch = b请给字符串型变量str赋值:Hello字符串型变量str = HelSEO靠我lo请给bool型变量flag赋值:1bool型变量flag = 1*/system("pause");return 0; }作用:用于执行代码的运算。
本章主要讲以下几类运SEO靠我算符:
运算符类型作用算术运算符用于处理四则运算赋值运算符用于将表达式的值赋给变量比较运算符用于表达式的比较,并返回一个真值或假值逻辑运算符用于根据表达式的值返回真值或假值作用:用于处SEO靠我理四则运算。
算术运算符包含以下符号:
运算符术语示例结果注意+正号+33-负号-3-3+加10+515-减10-55*乘10*550/除10/52除数不能是0%取模(取余数)10%31必须是两个整数, SEO靠我除数不能是0++前置递增a=2; b=++a;a=3; b=3;++后置递增a=2; b=a++;a=3; b=2;–前置递减a=2; b=–a;a=1; b=1;–后置递减a=2; b=a–;a=1SEO靠我; b=2; 前置先执行再表达式运算;后置先表达式运算再执行取余操作的被除数可以是0,且结果恒等于0;但除数不能是0,会报错!取余操作的本质就是除法
#include<iostream>SEO靠我 using namespace std;int main() {// 1. 加减乘除int a1 = 10;int b1 = 3;/*因为a和b都是int,因此两个整数做除法仍然是iSEO靠我nt*/cout << a1 + b1 << endl; // 13cout << a1 - b1 << endl; // 7cout << a1 * b1 << endl; // 30cout <<SEO靠我 a1 / b1 << endl; // 3int a2 = 10;int b2 = 20;cout << a2 / b2 << endl; // 0int a3 = 10;int b3 = 0;//SEO靠我 cout << a3 / b3 << endl; // 0 // Integer division by zero。// 两个小数相除double d1 = 0.5;double d2 = 0.22SEO靠我;cout << d1 / d2 << endl; // 2.27273// 整数和小数相除int a4 = 2;double d3 = 3.14;cout << a4 / d3 << endl; /SEO靠我/ 0.636943// 两个不同数据类型的小数相除float f1 = 3.14f;float d4 = 7.11;cout << f1 / d4 << endl; // 0.441632// 2.SEO靠我 取模(取余)int aa1 = 10;int aa2 = 3;cout << aa1 % aa2 << endl; // 1cout << aa2 % aa1 << endl; // 3// 两个小SEO靠我数是不可以取余float ff1 = 3.14f;float ff2 = 1.01f;// cout << ff1 % ff2 << endl; // 表达式必须具有整数或未区分范围的枚举类型(取余操SEO靠我作必须是整数!)// 取余操作的除数不能是0,被除数可以是0且结果恒等于0int aaa1 = 0;int aaa2 = 3;cout << aaa1 % aaa2 << endl; // 0// cSEO靠我out << aaa2 % aaa1 << endl; // Integer division by zero// 3. 前置递增、后置递增、前置递减、后置递减// 3.1 前置递增: 先让变量+1,SEO靠我然后进行表达式运算int a = 10;++a; // 让变量+1cout << "a = " << a << endl; // 11// 3.2 后置递增: 先进行表达式运算,再让变量+1int bSEO靠我 = 10;b++;cout << "b = " << b << endl; // 11// 前置和后置的区别a = 10;b = ++a * 10;cout << "a = " << a << enSEO靠我dl; // a = 11cout << "b = " << b << endl; // b = 110a = 10;b = a++ * 10;cout << "a = " << a << endl;SEO靠我 // a = 11cout << "b = " << b << endl; // b = 100// 3.3 前置递减a = 10;--a;cout << "a = " << a << endl; SEO靠我// 9// 3.4 后置递减b = 10;b--;cout << "b = " << b << endl; // 9// 前置和后置的区别a = 10;b = --a * 10;cout << "aSEO靠我 = " << a << endl; // a = 9cout << "b = " << b << endl; // b = 90a = 10;b = a-- * 10;cout << "a = " SEO靠我<< a << endl; // a = 9cout << "b = " << b << endl; // b = 100system("pause");return 0; }作用:用于将表达式的值赋给变量。
赋值运算符包括以下几个符号:
运算符术语示例结果=赋值a=2; b=3;a=2; b=3;+=加等于a=0; a+=2;a=2;-=减等于a=0; a-=2;aSEO靠我=-2;*=乘等于a=2; a*=3;a=6;/=除等于a=6; a/=3;a=2;%=模等于a=6; a%=4;a=2; #include<iostream> usiSEO靠我ng namespace std;int main() {// =int a = 10;cout << "a = " << a << endl; // a = 10a = 20;cout << "a SEO靠我= " << a << endl; // a = 20// +=a = 10;a += 2; // a = a + 2cout << "a = " << a << endl; // a = 12// SEO靠我-=a = 10;a -= 2;cout << "a = " << a << endl; // a = 8// *=a = 10;a *= 2;cout << "a = " << a << endl;SEO靠我 // a = 20// /=a = 10;a /= 2;cout << "a = " << a << endl; // a = 5// %=a = 10;a %= 2;cout << "a = " SEO靠我<< a << endl; // a = 0system("pause");return 0; }作用:用于表达式的比较,并返回一个真值或假值。
比较运算符有以下符号:SEO靠我
运算符术语示例结果==相等于4==30!=不等于4!=31<小于4<30>大于4>31<=小于等于4<=30>=大于等于4>=31 #include<iostream> SEO靠我 using namespace std;int main() {int a = 10;int b = 20;// ==cout << (a == b) << endl; // 0// !=cout SEO靠我<< (a != b) << endl; // 1// >cout << (a > b) << endl; // 0// <cout << (a < b) << endl; // 1// >=coutSEO靠我 << (a >= b) << endl; // 0// <=cout << (a <= b) << endl; // 1system("pause");return 0; }作用:用于根据表达式的值返回真值或假值
逻辑运算符有以下符号:
运算符术语示例结果!非!a如果a为假,则!a为真;如果a为真,则!a为假&&与a && b如果a和b都为真,则结果为真,否则为假|SEO靠我|与a || b如果a或b有一个为真,则结果为真 #include<iostream> using namespace std;int main() {// 逻辑非 !SEO靠我int a = 10;cout << "!a: " << !a << endl; // !a: 0cout << "!!a: " << !!a << endl; // !!a: 1// 逻辑与 &&iSEO靠我nt b = 20;cout << "a && b: " << (a && b) << endl; // a && b: 1bool c = false;cout << "b && c: " << (SEO靠我b && c) << endl; // b && c: 0int d = 0;cout << "c && d: " << (c && d) << endl; // c && d: 0// 逻辑或 ||SEO靠我cout << "a || b: " << (a || b) << endl; // a || b: 1cout << "b || c: " << (b || c) << endl; // b || SEO靠我c: 1cout << "c || d: " << (c || d) << endl; // c || d: 0system("pause");return 0; }C/C++支持最基本的三种程序执行结构:顺序结构、选择结构、循环结构:
顺序结构:程序按顺序执行,不发生跳转选择结构:依据条件是否满足,有选择的执行相应功能循环结构:依据条件是否满足,循环多次执行某段代SEO靠我码作用:执行满足条件的语句
if语句的三种形式:
单行格式if语句:if(条件){满足条件时执行的语句}多行格式if语句:if(条件){满足条件时执行的语句}else{SEO靠我不满足条件时执行的语句}多条件的if语句:if(条件){条件1满足时执行的语句}else if(条件2){条件2满足时执行的语句}... else{所有条件都不满足时执行的语句}补充:嵌套if语句:在SEO靠我if语句中,可以嵌套使用if语句,达到更精确的条件判断。
示例:
#include<iostream> using namespace std;int main() {// 用户输入分数,SEO靠我如果分数大于600,视为考上一本大学,在屏幕上输出int score = 0;cout << "请输入分数: ";cin >> score;cout << "输入的分数为: " << score <<SEO靠我 "\r\n" << endl;// 1. 单行格式if语句:if(条件){满足条件时执行的语句}cout << "---------1. 单行格式if语句---------" << endl;if SEO靠我(score >= 600) {cout << "恭喜您考上了一本大学!" << endl;}// 2. 多行格式if语句:if(条件){满足条件时执行的语句}else{不满足条件时执行的语句}couSEO靠我t << "\r\n---------2. 多行格式if语句---------" << endl;if (score >= 600) {cout << "恭喜您考上了一本大学!" << endl;}eSEO靠我lse{cout << "很可惜,您没考上一本大学" << endl;}// 3. 多条件的if语句:if(条件){条件1满足时执行的语句}else if(条件2){条件2满足时执行的语句}... eSEO靠我lse{所有条件都不满足时执行的语句}cout << "\r\n---------3. 多条件的if语句---------" << endl;if (score >= 600) {cout << "恭SEO靠我喜您考上了一本大学!" << endl;}else if (score >= 450) {cout << "恭喜您考上了二本大学!" << endl;}else if (score >= 300) {SEO靠我cout << "恭喜您考上了三本大学!" << endl;}else if (score >= 200) {cout << "恭喜您考上了专科大学!" << endl;}else {cout << SEO靠我"很可惜,您的分数不足以考上大学" << endl;}// 补充:在一本分数中,如果大于700分,考入北大,大于650分,考入清华,大于600考入人大。cout << "\r\n---------补充SEO靠我---------" << endl;if (score >= 600) {cout << "恭喜您考上了一本大学!" << endl;if (score > 700) {cout << "您能考上北SEO靠我大!" << endl;}else if (score > 650) {cout << "您能考上清华!" << endl;}else {cout << "您能考上人大!" << endl;}}/*请SEO靠我输入分数: 620输入的分数为: 620---------1. 单行格式if语句---------恭喜您考上了一本大学!---------2. 多行格式if语句---------恭喜您考上了一本大学!SEO靠我---------3. 多条件的if语句---------恭喜您考上了一本大学!---------补充---------恭喜您考上了一本大学!您能考上人大!*/system("pause");retuSEO靠我rn 0; }练习案例:有三只小猪ABC,请分别输入三只小猪的体重,并判断哪只小猪最重。
#include<iostream> using namespace std;iSEO靠我nt main() {// 1. 创建三只小猪的体重int a = 0;int b = 0;int c = 0;// 2. 用户输入三只小猪的重量cout << "请输入小猪A的体重: ";cin >SEO靠我> a;cout << "请输入小猪B的体重: ";cin >> b;cout << "请输入小猪C的体重: ";cin >> c;cout << endl;// 3. 显示三只小猪的体重cout <SEO靠我< "小猪A的体重 = " << a << endl;cout << "小猪B的体重 = " << b << endl;cout << "小猪C的体重 = " << c << endl;cout <<SEO靠我 endl;// 4. 判断哪只最重if (a > b) {if (a > c) {cout << "小猪A最重!" << endl;}}else { // b > aif (b > c) {coutSEO靠我 << "小猪B最重!" << endl;}else{cout << "小猪C最重!" << endl;}}/*请输入小猪A的体重: 10请输入小猪B的体重: 20请输入小猪C的体重: 30小猪A的体SEO靠我重 = 10小猪B的体重 = 20小猪C的体重 = 30小猪C最重!*/system("pause");return 0; }作用:通过三目运算符实现简单的判断
语SEO靠我法:表达式1 ? 表达式2 : 表达式3
解释:
如果表达式1的值为真,执行表达式2,并返回表达式2的结果;如果表达式1的值为假,执行表达式3,并返回表达式3的结果。Python中是 num = 值1 iSEO靠我f 表达式1 else 值2
#include<iostream> using namespace std;int main() {// 创建三个变量 abc// 将a和b作比较,将变量SEO靠我大的值赋值给变量cint a = 10;int b = 20;int c = 0;c = a > b ? a : b;cout << "c = " << c << endl; // c = 20// SEO靠我在C++中,三目运算符返回的是变量,可以继续赋值(a > b ? a : b) = 100;cout << "a = " << a << endl; // a = 10cout << "b = " <SEO靠我< b << endl; // b = 100system("pause");return 0; }作用:执行多条件分支语句
语法:
switch (表达式) SEO靠我{ case 结果1: 执行语句;break; case 结果2: 执行语句;break;...default: 执行语句;break; }注意:
swiSEO靠我tch语句中表达式类型只能是整型或字符型case里如果没有break,那么程序会一直向下执行switch相对if的优缺点: 优点:结构清晰,执行效率高缺点:判断时候只能是整数或字符型,不可以是一个区间SEO靠我示例:
#include<iostream> using namespace std;// switch语句 int main() {/*给电影打分:10 ~ 9:经典8SEO靠我 ~ 7:非常好6 ~ 5:一般5以下:烂片*/// 1. 提出用户给电影打分int score = 0;cout << "请给电影打分: ";cin >> score;// 2. 根据用户输入的分数SEO靠我来提出最终结果cout << "\r\nswitch语句结果:" << endl;switch (score){case 10:cout << "您认为是经典电影" << endl;break;casSEO靠我e 9:cout << "您认为是经典电影" << endl;break;case 8:cout << "您认为是一般电影" << endl;break;case 7:cout << "您认为是一般电SEO靠我影" << endl;break;case 6:cout << "您认为是一般电影" << endl;break;case 5:cout << "您认为是一般电影" << endl;break;defSEO靠我ault:cout << "您认为是烂片" << endl;break;}/*switch相对if的优缺点:优点:结构清晰,执行效率高缺点:判断时候只能是整数或字符型,不可以是一个区间*/cout <SEO靠我< "\r\nif语句结果:" << endl;if (score >= 9) {cout << "您认为是经典电影" << endl;}else if (score >= 5) {cout << "SEO靠我您认为是一般电影" << endl;}else {cout << "您认为是烂片" << endl;}system("pause");return 0; }作用:满足循环条件,执行循环语句
语法:while (循环条件) {循环语句}
解释:只要循环条件的结果为真,就执行循环语句。
注意:在执行循环语句时,程序必须提供跳出循环的出否,否则出现死循SEO靠我环
#include<iostream> using namespace std;int main() {// 在屏幕中打印 0~9 这10个数字int num = 0;while (nSEO靠我um < 10) {cout << num << endl;num += 1;}system("pause");return 0; }while循环练习案例:猜数字
案例描述:系统随机生SEO靠我成一个1到100之间的数字,玩家进行猜测,如果猜错,提示玩家数字过大或过小,如果猜对恭喜玩家胜利,并且退出游戏。
#include<iostream> using namespace sSEO靠我td; // 引入time头文件 #include<ctime>int main() {// 添加随机数种子,利用当前系统时间生成随机数,防止每次随机数都一样(随机本质SEO靠我上是伪随机)srand((unsigned int)time(NULL));// 1. 生成随机数int num = rand() % 100 + 1; // 生成0~99的随机数// 2. 让玩家进SEO靠我行猜测int val = 0; // 玩家输入的数据//限定猜测次数(5次)int times = 5;while (1) {cout << "猜个数: ";cin >> val;times -= 1SEO靠我;// 3. 判断玩家的猜测并给出提示if (times != 0) {if (val > num) {cout << "猜的大了" << endl;}else if (val < num) {couSEO靠我t << "猜的小了" << endl;}else // 猜对了 -> 退出游戏{cout << "猜对了!游戏结束..." << endl;break;}cout << "剩余次数" << timeSEO靠我s << "\n" << endl;}else{cout << "次数用尽,游戏失败..." << endl;break;}}system("pause");return 0;/*猜个数: 50猜的大SEO靠我了剩余次数4猜个数: 30猜的小了剩余次数3猜个数: 35猜对了!游戏结束...*/ }作用:满足循环条件,执行循环语句
语法:do{循环语句} whSEO靠我ile(循环条件);
注意:与while的区别在于do...while会先执行一次循环语句,再判断循环条件
do...while与while循环的区别在于: do...while会先执行一次循环语句,再判SEO靠我断循环条件。
#include<iostream> using namespace std;/*do...while和while的区别:do...while会先执行一次循环(不管条件是否SEO靠我满足) */ int main() {// 在屏幕中输出0~9这10个数字int num = 0;cout << "---------do while---------SEO靠我" << endl;do{cout << num << endl;num += 1;} while (num < 10);cout << "\r\n---------while---------" <SEO靠我< endl;num = 0;while (num < 10) {cout << num << endl;num += 1;}system("pause");return 0; }练习SEO靠我案例:水仙花数
案例描述:水仙花数是指: 一个3位数,它的每个位上的数字的3次幂之和等于它本身
例如: 13+53+33=1531^3 + 5^3 + 3^3 = 15313+53+33=153
请利用doSEO靠我...while语句,求出所有3位数中的水仙花数
#include<iostream> using namespace std; #include<math.h> // SEO靠我引入数学头文件int main() {// 1. 将所有的三位数进行输出(100 ~ 999)int num = 100;int a = 0; // 个位int b = 0; // 十位int c =SEO靠我 0; // 百位int times = 1;// 2. 在所有三位数中找到水仙花数/*e.g. 153获取个位: 153 % 10 = 3 获取十位: 153 / 10 = 15; 15 % 10 SEO靠我= 5 获取百位: 153 / 100 = 1判断:个位**3 + 十位**3 + 百位**3 == 本身*/do{a = num % 10;b = num / 10 % 10;c = num / 1SEO靠我00;if ((pow(a, 3) + pow(b, 3) + pow(c, 3)) == num) {cout << "水仙花数" << times << ": " << num << endl;tSEO靠我imes += 1;}num += 1;} while (num < 1000);/*水仙花数1: 153水仙花数2: 370水仙花数3: 371水仙花数4: 407*/system("pause")SEO靠我;return 0; }作用: 满足循环条件,执行循环语句
语法: for(起始表达式; 条件表达式; 末尾循环体) {循环语句;}
示例:
#include<ioSEO靠我stream> using namespace std;int main() {// 打印数字0~9for (int i = 0; i < 10; i++){cout << i << SEO靠我endl;}system("pause");return 0; }注意:
for循环中的表达式,要用分号进行分割while, do...while, for都是开发中常用的循环语句,foSEO靠我r循环结构比较清晰,比较常用。练习案例:敲桌子
案例描述:从1开始数的数字100,如果数字个位含有7,或者数字十位含有7,或者该数字是7的倍数,我们打印敲桌子,其余数字直接打印输出。
#include<iSEO靠我ostream> using namespace std;int main() {// 1. 先输出1到100for (int i = 1; i <= 100; i++){/*2. 从SEO靠我这100个数字中找到特殊数字,改为"敲桌子"* 特殊数字* 7的倍数: num % 7 == 0* 个位有7: num % 10 == 7* 十位有7: num / 10 == 7*/if (i % SEO靠我7 == 0 || i % 10 == 7 || i / 10 == 7) {cout << "敲桌子" << endl;}else {cout << i << endl;}}system("pausSEO靠我e");return 0; }作用: 在循环体中再嵌套一层循环,解决一些实际问题
例如我们想在屏幕中打印如下图片,就需要利用嵌套循环。
#include<iostreaSEO靠我m> using namespace std;int main() {for (int i = 0; i < 11; i++) // 行{for (int j = 0; j < 11;SEO靠我 j++) // 列{cout << "* ";}cout << endl;}system("pause");return 0; }练习案例:乘法口诀表
案例描述:利角嵌套循环,实现九九SEO靠我乘法表
#include<iostream> using namespace std;int main() {/** 列数 * 行数 = 计算结构* * 条件: 列数 <= 当前行数*/SEO靠我for (int i = 1; i < 10; i++) // 行{for (int j = 1; j <= i; j++) // 列{cout << i << "*" << j << "=" << SEO靠我i * j << "\t";}cout << endl;}/*1*1=12*1=2 2*2=43*1=3 3*2=6 3*3=94*1=4 4*2=8 4*3=12 4*4=165*1=5 5*2=1SEO靠我0 5*3=15 5*4=20 5*5=256*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=367*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=SEO靠我42 7*7=498*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=649*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6SEO靠我=54 9*7=63 9*8=72 9*9=81请按任意键继续. . .*/system("pause");return 0; }作用: 用于SEO靠我跳出选择结构或者循环结构
break使用的时机:
出现在switch条件语句中,作用是终止case并跳出switch出现在循环语句中,作用是跳出当前的循环语句出现在嵌套循环中,跳出最近的内层循环语句示例1SEO靠我:
#include<iostream> using namespace std;// break的使用时机 int main() {// 1. 出现在switch语句中SEO靠我 cout << "------ 1. 出现在switch语句中 ------" << endl;cout << "请选择副本的难度" << endl;cout << "1. 普通" << endl;SEO靠我cout << "2. 中等" << endl;cout << "3. 困难" << endl;int select = 0; // 用户选择结果变量cout << "请选择(1 2 3): ";ciSEO靠我n >> select; // 等待用户输入switch (select){case 1:cout << "您选择的是普通难度" << endl;break;case 2:cout << "您选择的是SEO靠我中等难度" << endl;break;case 3:cout << "您选择的是困难难度" << endl;break;default:cout << "您选择的选择有误!" << endl;breSEO靠我ak;}// 2. 出现在循环语句中cout << "\r\n------ 2. 出现在循环语句中 ------" << endl;for (int i = 0; i < 10; i++){cout SEO靠我<< i << endl;// 如果i==5, 退出循环if (i == 5) {break;}}// 3. 出现在嵌套循环语句中cout << "\r\n------ 3. 出现在嵌套循环语句中 -SEO靠我-----" << endl;for (int i = 0; i < 10; i++){for (int j = 0; j < 10; j++){// 如果j == 5,退出循环if (j == 5)SEO靠我 {break;}cout << "* ";}cout << endl;}system("pause");return 0; }作用: 在循环语句中,跳SEO靠我过本次循环,继续执行下一次循环。
#include<iostream> using namespace std;int main() {for (int i = 0; i <= 100;SEO靠我 i += 1) {if (i % 10 == 0) {cout << endl;}// 如果是奇数则输出if (i % 2 == 1) {cout << i << "\t";}else{continSEO靠我ue;}}/*1 3 5 7 911 13 15 17 1921 23 25 27 2931 33 35 37 3941 43 45 47 4951 53 55 57 5961 63 65 67 69SEO靠我71 73 75 77 7981 83 85 87 8991 93 95 97 99*/system("pause");return 0; }作用: 可以无条件SEO靠我跳转语句
跳转语法: goto 标记; -> goto FLAG; // 跳到标记
标记语法: 标记: -> FLAG: // 表明标记的位置示例:
int main3() {goto FLAG; // 跳SEO靠我转到标记FLAG的位置FLAG: // 确认标记的位置return 0; }解释: 如果标记的名称存在,当程序执行到goto语句时,会跳转到标记的位置
注意:学习goto语句只是为了明白SEO靠我这个语句的作用,我们写代码的时候不要用,跳来跳去的,麻烦且容易出bug.
#include<iostream> using namespace std;// goto语句 SEO靠我 int main() {cout << "1. xxxxxxxx" << endl;cout << "2. xxxxxxxx" << endl;goto FLAG; // 跳转到标记FLAG的位置cSEO靠我out << "3. xxxxxxxx" << endl;cout << "4. xxxxxxxx" << endl;FLAG: // 确认标记的位置cout << "5. xxxxxxxx" << SEO靠我endl;/*1. xxxxxxxx2. xxxxxxxx5. xxxxxxxx请按任意键继续. . .*/system("pause");return 0; }所谓数组(array),就是一个集合,里面存放了相同类型的数据元素,数组有两个特点:
数组中的每个数据元素都是相同的数据类型数组是由连续的内存位置组成的在Python中,list是列表不SEO靠我是数组;Python的list里面可以存放不一样的数据类型,但数组中一定要存放相同的数据类型
一维数组定义的三种方式:
数据类型 数组名 [数组长度];数据类SEO靠我型 数组名[数组长度] = {值1, 值2, ...}; (如果在初始化数据时没有全部填写,则会用0来填补)数据类型 数组名[] = {值1, 值2, ...];C++中没有built-in的方法求数SEO靠我组的长度
总结:
数组名的命名规范与变量名命名规范一致,不要和变量重名数组的下标从0开始索引示例:
#include<iostream> using namespace std;// 一维数SEO靠我组的定义 int main() {// ----- 1. 数据类型 数组名 [数组长度]; -----cout << "----- 1. 数据类型 数组名 [数组长度]; -----"SEO靠我 << endl;int arr1[5]; // 定义数组// 给数组中的元素赋值for (int i = 0; i < 5; i++){arr1[i] = (i + 1) * 10;}// 访问数组SEO靠我元素for (int i = 0; i < 5; i++) {cout << "arr1[" << i << "]: " << arr1[i] << endl;}// ----- 2. 数据类型 数组SEO靠我名[数组长度] = { 值1, 值2, ... }; ----- cout << "\r\n----- 2. 数据类型 数组名[数组长度] = {值1, 值2, ...}; ----- " << enSEO靠我dl;int arr2[5] = { 10, 20, 30, 40, 50 };// 访问数组元素for (int i = 0; i < 5; i++) {cout << "arr2[" << i <SEO靠我< "]: " << arr2[i] << endl;}// ----- 3. 数据类型 数组名[] = {值1, 值2, ...}; -----cout << "\r\n----- 3. 数据类型 SEO靠我数组名[] = {值1, 值2, ...}; -----" << endl;int arr3[] = { 90, 80, 60, 50, 40, 30, 20, 10, 0 };// 访问数组元素foSEO靠我r (int i = 0; i < 9; i++){cout << "arr3[" << i << "]: " << arr3[i] << endl;}/*----- 1. 数据类型 数组名 [数组长SEO靠我度]; -----arr1[0]: 10arr1[1]: 20arr1[2]: 30arr1[3]: 40arr1[4]: 50----- 2. 数据类型 数组名[数组长度] = {值1, 值2, .SEO靠我..}; -----arr2[0]: 10arr2[1]: 20arr2[2]: 30arr2[3]: 40arr2[4]: 50----- 3. 数据类型 数组名[] = {值1, 值2, ...}SEO靠我; -----arr3[0]: 90arr3[1]: 80arr3[2]: 60arr3[3]: 50arr3[4]: 40arr3[5]: 30arr3[6]: 20arr3[7]: 10arr3[SEO靠我8]: 0*/system("pause");return 0; }一维数组名称的用途:
可以统计整个数组在内存中的长度: sizeof(数组名)可以获取数组在SEO靠我内存中的首地址: cout << arr << endl; 单个元素的长度: sizeof(arr[0])整个数组的长度: sizeof(arr)这样我们就可以得到数组中元素的个数,SEO靠我即数组的长度。
C++中没有built-in的方法求数组的长度
#include<iostream> using namespace std;int main() {// 1. 可以统计整SEO靠我个数组在内存中的长度: sizeof(数组名)int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };cout << "arr数组占用内存空间大小为: " << sSEO靠我izeof(arr) << "字节" << endl; // arr数组占用内存空间大小为: 40字节cout << "arr数组每个元素占用内存空间大小为: " << sizeof(arr[0]) SEO靠我<< "字节" << endl; // arr数组每个元素占用内存空间大小为: 4字节cout << "arr数组的元素个数(数组长度)为: " << sizeof(arr) / sizeof(arrSEO靠我[0]) << endl; // arr数组的元素个数(数组长度)为: 10// 2. 可以获取数组在内存中的首地址: cout << arr << endl; cout << "arr数组的首地址为SEO靠我: " << arr << endl; // 000000B955D0F748cout << "arr数组的首地址(十进制)为: " << (int) arr << endl; // 14397581SEO靠我52cout << "arr数组的第一个元素的地址为: " << &arr[0] << endl; // 000000B955D0F748cout << "arr数组的第一个元素的地址(十进制)为: SEO靠我" << (int)&arr[0] << endl; // 1439758152cout << "arr数组的第二个元素的地址为: " << &arr[0] << endl; // 000000B95SEO靠我5D0F748cout << "arr数组的第二个元素的地址(十进制)为: " << (int)&arr[0] << endl; // 1439758152/** 1. &是取址符* * 2. 可以看SEO靠我到,数组的首地址和数组第一个元素的地址是一样的!* * 3. 因为数组在内存空间中是连续的,因此第一个元素的地址和第二个元素的地址差4(int的大小是4字节!)*/// 数组名是常量,不可以进行赋值/SEO靠我/ arr = 100; // IDE报错: 表达式必须是可修改的左值system("pause");return 0; }练习案例1: 五只小猪称体重
案例描述: 在一个数组中记录了五SEO靠我只小猪的体重,如: int arr[5]= { 300, 350, 200, 400, 250 };
找出并打印最重的小猪体重。
#include<iostream> using nameSEO靠我space std;int main() {// 1. 创建5只小猪体重的数组int arr[5] = { 300, 350, 200, 400, 250 };// 2. 定义最大值int max_nSEO靠我um = arr[0];int order = 0;// 3. 逻辑判断for (int i = 1; i < 5; i++){if (arr[i] > max_num) {max_num = arrSEO靠我[i];order = i;}}// 4. 打印最大值cout << "最大值为: " << max_num;cout << "。是第 " << order + 1 << " 只小猪" << endlSEO靠我; // 最大值为: 400。是第 4 只小猪system("pause");return 0; }练习案例2: 数组元素逆置
案例描述: 请声明一个5个元素的数组,并且将元素逆置.
(如SEO靠我原数组元素为: 1, 3, 2, 5, 4; 逆置后输出结果为: 4, 5, 2, 3, 1);
#include<iostream> using namespace std;int mSEO靠我ain() {// 1. 创建数组int arr[] = { 1, 3, 2, 5, 4 };// 2. 实现逆置/*2.1 记录起始下标的位置2.2 记录结束下标的位置2.3 起始下标和结束下标的元SEO靠我素互换2.4 起始位置++; 结束位置++2.5 循环执行2.1操作,直到起始位置 >= 结束位置*/int start = 0;int end = sizeof(arr) / sizeof(arr[SEO靠我0]) - 1;int tmp = 0;while (start < end) {// 元素互换tmp = arr[start];arr[start] = arr[end];arr[end] = tmSEO靠我p;// 更新下标start += 1;end -= 1;}// 3. 打印逆置后的数组cout << "数组元素逆置后: " << endl;for (int i = 0; i < sizeof(aSEO靠我rr) / sizeof(arr[0]); i++){cout << arr[i] << ", "; // 4, 5, 2, 3, 1,}cout << endl;system("pause");reSEO靠我turn 0; }思路2:
#include<iostream> using namespace std;int main() {// 1. 创建数组int arr[] SEO靠我= { 1, 3, 2, 5, 4 };int length = sizeof(arr) / sizeof(arr[0]) - 1;// 2. 具体实现for (int i = 0; i <= lenSEO靠我gth / 2; i++) // 注意只走一半{ int tmp = arr[i];arr[i] = arr[length - i];arr[length - i] = tmp;}// 3. 打印逆置SEO靠我后的数组cout << "数组元素逆置后: " << endl;for (int i = 0; i <= length; i++){cout << arr[i] << ", "; // 4, 5, 2SEO靠我, 3, 1,}cout << endl;system("pause");return 0; }作用: 最常用的排序算法,对数组内元素进行排序
比较相邻的元素。如果第SEO靠我一个比第二个大,就交换他们两个。对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值。重复以上的步骤,每次比较次数-1,直到不需要比较示例: 将数组{ 4, 2, 8, 0, 5, 7, 1, SEO靠我3, 9 }进行升序排序
#include<iostream> using namespace std;int main() {int arr[] = { 4, 2, 8, 0, 5, SEO靠我7, 1, 3, 9 };int n = sizeof(arr) / sizeof(arr[0]) - 1;// 排序前cout << "排序前: " << endl;for (int i = 0; SEO靠我i <= n; i++){cout << arr[i] << " "; // 4 2 8 0 5 7 1 3 9}cout << endl;/*外层: n - 1内层: n - i - 1*/for SEO靠我(int i = 0; i < n - 1; i++) // n - 1轮(外层){for (int j = 0; j < n - i - 1; j++) // 内层{if (arr[j] > arrSEO靠我[j + 1]) {int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}// 排序后cout << "排序后: " << endl;forSEO靠我 (int i = 0; i <= n; i++){cout << arr[i] << " "; // 0 1 2 3 4 5 7 8 9}cout << endl;system("pause");rSEO靠我eturn 0; }二维数组就是在一维数组上,多加了一个维度。
二维数组定义的四种方式:
数据类型 数组名[行数][列数];数据类型 数组名[行SEO靠我数][列数] = { {数据1,数据2},{数据3,数据4 }};数据类型 数组名[行数][列数] = {数据1,数据2,数据3,数据4};数据类型 数组名[][列数] = {数据1,数据2,数据3,SEO靠我数据4};建议: 以上4种定义方式,利用第二种更加直观,提高代码的可读性
在定义二维数组时,如果初始化了数据,可以省略行数
示例:
#include<iostream> using nameSEO靠我space std;int main() {// 1. 数据类型 数组名[行数][列数];int arr1[2][3];// 赋值for (int i = 0; i < 2; i++) {for (iSEO靠我nt j = 0; j < 3; j++){arr1[i][j] = (i + 1) * (j + 1) * 10;}}// 查看cout << "------ 1. 数据类型 数组名[行数][列数]SEO靠我; ------" << endl;for (int i = 0; i < 2; i++) {for (int j = 0; j < 3; j++){cout << arr1[i][j] << " "SEO靠我;}cout << endl;}// 2. 数据类型 数组名[行数][列数] = { {数据1,数据2},{数据3,数据4 }};int arr2[2][3] = { {10, 20, 30}, {4SEO靠我0, 50, 60} };// 查看cout << "\r\n------ 2. 数据类型 数组名[行数][列数] = { {数据1,数据2},{数据3,数据4 }}; ------" << endlSEO靠我;for (int i = 0; i < 2; i++) {for (int j = 0; j < 3; j++){cout << arr2[i][j] << " ";}cout << endl;}/SEO靠我/ 3. 数据类型 数组名[行数][列数] = {数据1,数据2,数据3,数据4};int arr3[2][3] = { 10, 20, 30, 40, 50, 60 };// 查看cout << "SEO靠我\r\n------ 3. 数据类型 数组名[行数][列数] = {数据1,数据2,数据3,数据4}; ------" << endl;for (int i = 0; i < 2; i++) {forSEO靠我 (int j = 0; j < 3; j++){cout << arr2[i][j] << " ";}cout << endl;}// 4. 数据类型 数组名[][列数] = {数据1,数据2,数据SEO靠我3,数据4};int arr4[][3] = { 10, 20, 30, 40, 50, 60 };// 查看cout << "\r\n------ 4. 数据类型 数组名[][列数] = {数据1,SEO靠我数据2,数据3,数据4}; ------" << endl;for (int i = 0; i < 2; i++) {for (int j = 0; j < 3; j++){cout << arr2[SEO靠我i][j] << " ";}cout << endl;}/*------ 1. 数据类型 数组名[行数][列数]; ------10 20 3020 40 60------ 2. 数据类型 数组名[行SEO靠我数][列数] = { {数据1,数据2},{数据3,数据4 }}; ------10 20 3040 50 60------ 3. 数据类型 数组名[行数][列数] = {数据1,数据2,数据3,数据SEO靠我4}; ------10 20 3040 50 60------ 4. 数据类型 数组名[][列数] = {数据1,数据2,数据3,数据4}; ------10 20 3040 50 60*/systSEO靠我em("pause");return 0; }考试成绩统计:
案例描述: 有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表,请分别输出三名同学的总成绩。
姓名语文数学英语张三100100100李四9050100王五607080 SEO靠我 #include<iostream> using namespace std; #include<string>// 二维数组案例 —— 考试成绩统计 SEO靠我 int main() {// 1. 创建二维数组int scores[3][3] = {{100, 100, 100},{90, 50, 100},{60, 70, 80},};strinSEO靠我g names[3] = {"张三","李四","王五",};// 2. 统计每个人的总和分数for (int i = 0; i < 3; i++) // 行{int sum = 0; // 统计SEO靠我分数总和for (int j = 0; j < 3; j++) // 列{sum += scores[i][j];}// 打印每个人的总成绩cout << names[i] << "的总分为: " SEO靠我<< sum << endl;}/*张三的总分为: 300李四的总分为: 240王五的总分为: 210*/system("pause");return 0; }作用: 将一段经常SEO靠我使用的代码封装起来,减少重复代码。
一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。
函数的定义一般主要有5个步骤:
返回值类型函数名参数表列函数体语句return表达式语法SEO靠我:
返回值类型 函数名 (形参1, 形参2, ...) {函数体语句;return表达式; } 返回值类型: 一个函数可以返回一个值。在函数定义中函数名: 给函数起个名称参数列表: 使用该函数时,传SEO靠我入的数据函数体语句: 花括号内的代码,函数内需要执行的语句return表达式: 和返回值类型挂钩,函数执行完后,返回相应的数据示例:
// 加法函数,实现两个整型相加并返回相加的结果 int add(iSEO靠我nt num1, int num2) {int sum = num1 + num2;return sum; }功能: 使用定义好的函数
语法: 函数名(参数1, 参数2, ...)
示例SEO靠我:
#include<iostream> using namespace std;// 加法函数,实现两个整型相加并返回相加的结果 int add(int num1, int num2) {int suSEO靠我m = num1 + num2;return sum; }int main() {int a = 10;int b = 20;int res = add(a, b);cout << "两数之和为: "SEO靠我 << res << endl; // 两数之和为: 30//system("pause"); // 按任意键继续的功能return 0; }void: 中文翻译为“无类型”。常用在程序编写中对定义函数的参数类型、返回值、函数中指针类型进行声明。vSEO靠我oid的字面意思是“无类型”。
常见的函数样式有4种:
无参无返有参无返无参有返有参有返 #include<iostream> using namespace std;// 1. SEO靠我无参无返 void test_01() {cout << "1. 无参无返" << endl; }// 2. 有参无返 void test_02(int a) {cout << "2. 有参无返: "SEO靠我;cout << a << endl; }// 3. 无参有返 float test_03() {cout << "3. 无参有返" << endl;return 3.14f; }// 4. 有参有返SEO靠我 double test_04(float a) {cout << "4. 有参有返" << endl;return a; }int main() {// 1. 无参无返test_01(); // SEO靠我1. 无参无返// 2. 有参无返test_02(10086); // 2. 有参无返 10086// 3. 无参有返float return_param_1 = test_03(); // 3.SEO靠我 无参有返cout << "return_param_1: " << return_param_1 << endl; // return_param_1: 3.14// 4. 有参有返double SEO靠我return_param_2 = test_04(6.17f); // 4. 有参有返cout << "return_param_2: " << return_param_2 << endl; /SEO靠我/ return_param_2: 6.17return 0; }作用: 告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
函数的声明可以多次,但是函数的定义只能有一次 SEO靠我 #include<iostream> using namespace std; // 让我们可以使用cout在屏幕输出// 提前告诉编译器函数的存在,可以利用函数的声明 // 函数的声明可以有多次SEO靠我,但函数的定义只能有一次! int max(int a, int b); int max(int a, int b); int max(int a, int b);int main() {int a SEO靠我= 10;int b = 20;int max_num = max(a, b);cout << "max_num: " << max_num; // max_num: 20return 0; }//SEO靠我 函数的定义只能有一次! int max(int a, int b) {return a > b ? a : b; }作用: 让代码结构更加清晰
函数分文件编写一般有4个步骤:
创SEO靠我建后缀名为.h的头文件 -> swap.h创建后缀名为.cpp的源文件 -> swap.cpp在头文件中写函数的声明在源文件中写函数的定义示例:
指SEO靠我针的作用: 可以通过指针间接访问内存。
内存编号是从0开始记录的,一般用十六进制数字表示可以利用指针变量保存地址简单来说,指针就是一个地址
指针变量定义语法: 数据类型 *变量SEO靠我名;
示例:
#include<iostream> using namespace std;int main() {// 1. 定义指针: 数据类型 *指针变量名int a = 10;int* p;; SEO靠我// 这就定义了一个指针// 让指针*p记录变量a的地址p = &a;cout << "a的地址为: " << &a << endl; // 000000F62119F7C4cout << "指针pSEO靠我为: " << p << endl; // 000000F62119F7C4cout << "*p为: " << *p << endl; // 10// 2. 使用指针// 可以通过解引用的方式来SEO靠我找到指针指向的内存// 指针前加一个*代表解引用,即找到指针指向的内存中的数据*p = 1000;cout << "a = " << a << endl; // 1000cout << "*p = SEO靠我" << *p << endl; // 1000return 0; }提问:指针也是一种数据类型,那么这种数据类型占用多少内存空间?
回答:在32位操作系统下,指针都占用4个SEO靠我字节空间;在64位操作系统下,指针占用8个字节空间。
在IDE中可以修改系统环境的位数:
示例:
#include<iostream> using namespace std;int main() {intSEO靠我 a = 10;int* p = &a;cout << "sizeof(int*) = " << sizeof(int*) << "字节" << endl; // 8字节cout << "sizeoSEO靠我f(int*) = " << sizeof(p) << "字节" << endl; // 8字节cout << "sizeof(float*) = " << sizeof(float*) << "字SEO靠我节" << endl; // 8字节cout << "sizeof(double*) = " << sizeof(double*) << "字节" << endl; // 8字节cout << "SEO靠我sizeof(char*) = " << sizeof(char*) << "字节" << endl; // 8字节cout << "sizeof(long*) = " << sizeof(longSEO靠我*) << "字节" << endl; // 8字节cout << "sizeof(long long*) = " << sizeof(long long*) << "字节" << endl; /SEO靠我/ 8字节/* 32位操作系统sizeof(int*) = 4字节sizeof(float*) = 4字节sizeof(double*) = 4字节sizeof(char*) = 4字节sizeof(SEO靠我long*) = 4字节sizeof(long long*) = 4字节*//* 64位操作系统sizeof(int*) = 8字节sizeof(float*) = 8字节sizeof(double*SEO靠我) = 8字节sizeof(char*) = 8字节sizeof(long*) = 8字节sizeof(long long*) = 8字节*/return 0; }指针不知道指向哪里好,就指向空
0 ~ 255这块内存是系统占用的,我们不可以访问#include<iostreaSEO靠我m> using namespace std;// 空指针 int main() {// 1. 空指针用于给指针变量进行初始化int* p = NULL;cout << "p: " << p << eSEO靠我ndl; // p: 0000000000000000// 2. 空指针是不可以进行访问的(0 ~ 255的内存编号是系统占用的,因此不可以访问)// *p = 100; // 引发了异常: 写入SEO靠我访问权限冲突。p 是 nullptr。return 0; }野指针:指针变量指向非法的内存空间。示例:
#include<iostream> using namespace std;// 野指针:在程序SEO靠我中尽量避免出现野指针 int main() {// 没有申请内存就直接让指针指向这个地址int* p = (int*)0x1100;cout << "p: " << p << endl; // p:SEO靠我 0000000000001100cout << "*p: " << *p << endl; // 引发了异常: 读取访问权限冲突。p 是 0x1100。// 因为我们之前没有申请0x1100这个地SEO靠我址,所以C++程序是没有权限去操作这块地址return 0; }总结:空指针和野指针都不是我们申请的空间,因此不要访问!
const修饰指针有三种情况:
const修饰指针 ->SEO靠我 常量指针 -> const int* p = &a;const修饰常量 -> 指针常量 -> int* const p = &a;const即修饰指针,又修饰常量 -> const int* conSEO靠我st p = &a;记名称:常量=const, 指针=*,这样就好记了
对于常量指针,可以理解为const限制的*,所以 *p 的操作就不可以了
对于指针常量,可以理解为const限制的p,所以 p 的操SEO靠我作就不可以了
const修饰谁,谁就是常量,常量是不可以修改的!const修饰指针 -> 常量指针 -> const int* p = &a;
特点:指针的指向可以修改,但指针指向的值SEO靠我不可以修改,即
int a = 10; int b = 10;// 定义常量指针 const int* p = &a;// 判断 *p = 20; // 不可以,指针不可以修改指向的值 p = &b;SEO靠我 // 可以,指针可以修改指向const修饰常量 -> 指针常量 -> int* const p = &a;
特点:指针的指向不可以改,指针指向的值可以修改。
int a = 10;SEO靠我 int b = 10;// 定义常量指针 int* const p = &a;// 判断 *p = 20; // 可以,指针可以修改指向的值 p = &b; // 不可以,指针不可以修改指向const即修饰指针,又修饰常量 -> const int* const p = &a;
特点:指针的指向和指向的值都不可以改!
int a = 10; int bSEO靠我 = 10;// 定义常量指针 const int* const p = &a;// 判断 *p = 20; // 不可以,指针不可以修改指向的值 p = &b; // 不可以,指针不可以修改指向SEO靠我示例:
#include<iostream> using namespace std;int main() {int a = 10;int b = 20;// 1. const修饰指针 -> 常量指针cSEO靠我onst int* p1 = &a;// *p1 = 20; // 报错:“p1” : 不能给常量赋值 指针p1 = &b; // 不报错// 2. const修饰常量 -> 指针常量int* cSEO靠我onst p2 = &a;*p2 = 20; // 不报错// p2 = &b; // 报错:“p2” : 不能给常量赋值// 3. const修饰指针和常量const int* const p3SEO靠我 = &a;// *p3 = 20; // 报错:表达式必须是可修改的左值// p3 = &b; // 报错:“p3” : 不能给常量赋值return 0; }技巧: 看const右侧紧跟着的是指SEO靠我针还是常量,是指针就是常量指针,是常量就是指针常量
作用:利用指针访问数组中元素
示例:
#include<iostream> using namespace std;int main()SEO靠我 {// 利用指针访问数组中的元素int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };cout << "第一个元素为: " << arr[0] << endl;SEO靠我 // 1int* p = arr; // 数组名就是数组第一个元素的地址(数组的首地址)cout << "利用指针访问第一个元素: " << *p << endl; // 1p += 1; SEO靠我// 让指针向后偏移4个字节cout << "利用指针访问第二个元素: " << *p << endl; // 1 // 2cout << "\r\n--------利用指针遍历数组-------SEO靠我-" << endl;int* p2 = arr;for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){cout << *p2 << " "; SEO靠我 // 1 2 3 4 5 6 7 8 9 10p2 += 1;}cout << endl;return 0; }作用:利用指针作函数参数,可以修改实参的值
#include<iostSEO靠我ream> using namespace std;// 实现两个数字进行交互 void swap_01(int a, int b) {int tmp = a;a = b;b = tmp;cout <SEO靠我< "----形参----" << endl;cout << "[swap_01] a = " << a << endl;cout << "[swap_01] b = " << b << endl; SEO靠我}void swap_02(int* p1, int* p2) {int tmp = *p1;*p1 = *p2;*p2 = tmp;cout << "----形参----" << endl;coutSEO靠我 << "[swap_02] a = " << *p1 << endl;cout << "[swap_02] b = " << *p2 << endl; }int main() {// 1. 值传递:SEO靠我 不会修改实参int a = 10;int b = 20;swap_01(a, b);cout << "----实参----" << endl;cout << "a = " << a << endl;SEO靠我cout << "b = " << b << endl;/*----形参----[swap_01] a = 20[swap_01] b = 10----实参----a = 10b = 20*/// 2SEO靠我. 地址传递: 可以修改实参swap_02(&a, &b);cout << "----实参----" << endl;cout << "a = " << a << endl;cout << "b = SEO靠我" << b << endl;/*----形参----[swap_02] a = 20[swap_02] b = 10----实参----a = 20b = 10*/return 0; }总结:如果不SEO靠我想修改实参,就用值传递;如果想修改实参,就用地址传递
案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序。
例如数组: int arr[10] = { 4, 3, 6,SEO靠我 9, 1, 2, 10, 8, 7, 5 }
#include<iostream> using namespace std;void bubble_sort(int* arr, int n) {/**SEO靠我 arr: 数组的首地址(因为要接收一个地址,所以数据类型是int*)* n: 数组的长度*/for (int i = 0; i < n - 1; i++){for (int j = 0; j < nSEO靠我 - i - 1; j++){if (arr[j] > arr[j + 1]) {int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}} SEO靠我 }void print_array(int* arr, int n) {/** arr: 数组的首地址(因为要接收一个地址,所以数据类型是int*)* n: 数组的长度*/for (inSEO靠我t i = 0; i < n; i++){cout << arr[i] << " ";}cout << endl; }int main8() {// 1. 创建数组int arr[10SEO靠我] = { 4, 3, 6, 9, 1, 2, 10, 8, 7, 5 };int len = sizeof(arr) / sizeof(arr[0]);// 2. 创建函数,实现冒泡排序bubbleSEO靠我_sort(arr, len);// 3. 打印排序后的数组print_array(arr, len); // 1 2 3 4 5 6 7 8 9 10return 0; }结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。
语法: struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
stSEO靠我ruct 结构体名 变量名;struct 结构体名 变量名 = { 成员1值, 成员2值, ... };定义结构体时顺便创建变量注意:
在日常使用时,方法1和方法2用的比较多,第3种用的比较少!在定义结SEO靠我构体变量时,struct关键字可以省略总结:
定义结构体时的关键字是struct,不可省略创建结构体变量时,关键字struct可以省略结构体变量利用操作符 . 访问成员可以看到,C/C++中的结构体和PSEO靠我ython中的class很像。
示例:
#include<iostream> using namespace std; #include<string>// 1. 创建学生SEO靠我数据类型:姓名,年龄,分数 struct Student {// 成员列表string name;int age;int score; };structSEO靠我 Student2 {// 成员列表string name;int age;int score; }s3; // 在创建结构体的时候创建顺便创建变量int main()SEO靠我 {// 2. 通过学生类型创建具体学生// 2.1 struct 结构体名 变量名;struct Student s1;s1.name = "张三";s1.age = 18;s1.score = 1SEO靠我00;// cout << s1 << endl; // 没有与这些操作数匹配的cout << "姓名: " << s1.name << "\t年龄: " << s1.age << "\t分数: " SEO靠我<< s1.score << endl; // 姓名: 张三 年龄: 18 分数: 100// 2.2 struct 结构体名 变量名 = { 成员1值, 成员2值, ... }; Student sSEO靠我2 = { "李四", 19, 80 }; // 在创建结构体变量时struct关键字可以省略cout << "姓名: " << s2.name << "\t年龄: " << s2.age << "\SEO靠我t分数: " << s2.score << endl; // 姓名: 李四 年龄: 19 分数: 80// 2.3 定义结构体时顺便创建变量s3.name = "王五";s3.age = 20;s3.SEO靠我score = 60;cout << "姓名: " << s3.name << "\t年龄: " << s3.age << "\t分数: " << s3.score << endl; // 姓名: 王SEO靠我五 年龄: 20 分数: 60return 0; }作用:将自定义的结构体放入到数组中以方便维护。
语法:struct 结构体名 数组名[元素个数] = { {}, {SEO靠我}, ... }
示例:
#include<iostream> using namespace std; #include<string>// 1. 定义结构体 SEO靠我 struct Student {string name;int age;int score; };int main() {// 2. 创建结构体数组StudentSEO靠我 stuArray[] = {{"张三", 18, 100},{"李四", 20, 99},{"王五", 38, 80},};// 3. 给结构体数组中的元素赋值stuArray[2].name = SEO靠我"赵六";stuArray[2].age = 40;stuArray[2].score = 75;// 4. 遍历结构体数组for (int i = 0; i < 3; i++){cout << "姓SEO靠我名: " << stuArray[i].name << "\t年龄: " << stuArray[i].age << "\t分数: " << stuArray[i].score << endl;}SEO靠我/*姓名: 张三 年龄: 18 分数: 100姓名: 李四 年龄: 20 分数: 99姓名: 赵六 年龄: 40 分数: 75*SEO靠我/return 0; }作用:通过指针访问结构体中的成员
利用操作符 -> 可以通过结构体指针访问结构体属性 struct Student {string name;int age;SEO靠我int score; }> 总结:结构体指针可以通过>操作符来访问结构体中的成员int main() {Student s1 = { "张三", 18, 100 };Student* p = &s1;SEO靠我// 利用 -> 访问结构体中的成员变量cout << p->name << endl;cout << p->age << endl;cout << p->score << endl;return 0SEO靠我; }示例:
#include<iostream> using namespace std; #include<string>// 1. 定义结构体 struct Student {string namSEO靠我e;int age;int score; };int main() {// 2. 创建学生的结构体变量Student s = { "张三", 18, 100 };// 3. 通过指针指向结构体变量//SEO靠我 int* p = &s; // "Student *" 类型的值不能用于初始化Student* p = &s; // 结构体就是我们自定义的数据类型,指针当然也要使用这种数据类型// 4. 通过SEO靠我指针访问结构体变量中的数据cout << "姓名: " << p->name << "\t年龄: " << p->age << "\t分数: " << p->score << endl;// 姓名: SEO靠我张三 年龄: 18 分数: 100return 0; }作用:结构体中的成员可以是另一个结构体。
例子:每个老师辅导一个学员,一个老师的结构体中,记录一个SEO靠我学生的结构体。
示例:
#include<iostream> using namespace std; #include<string>// 1. 定义学生的结构体 struct Student {strSEO靠我ing name;int age;int score; };// 2. 定义老师的结构体 struct Teacher {int id; // 教师编号string name;int age;StuSEO靠我dent stu; // 辅导的学生 };int main() {// 3. 创建老师Teacher t = { 10086, "王老师", 50, {"小王", 16, 60} };/*TeachSEO靠我er t;t.id = 10086;t.name = "王老师";t.age = 50;t.stu.name = "小王";t.stu.age = 16;t.stu.score = 60;*/coutSEO靠我 << "老师姓名: " << t.name << "\t老师编号: " << t.id << "\t老师年龄: " << t.age << "\n辅导的学生的姓名: " << t.stu.name SEO靠我<< "\t辅导的学生的年龄: " << t.stu.age << "\t辅导的学生的分数" << t.stu.score << endl;/*老师姓名: 王老师 老师编号: 10086SEO靠我 老师年龄: 50辅导的学生的姓名: 小王 辅导的学生的年龄: 16 辅导的学生的分数60*/return 0; }作用:将结构体作为参数向函数中传递
传递方式有两种:
值SEO靠我传递: 改变形参不会 改变实参地址传递:改变形参 会 改变实参总结:如果不想修改主函数中的数据,用值传递,反之用地址传递。
示例:
#include<iostream> using namespace std;SEO靠我 #include<string>// 定义学生结构体 struct Student {string name;int age;int score; };// 打印学生信息的函数 // 1. 值传递 SEO靠我void print_student_1(Student stu) {cout << "---------子函数[print_student_1]中打印---------" << endl;stu.nSEO靠我ame = "[值传递修]改后的姓名";cout << "姓名: " << stu.name << "\t年龄: "<< stu.age << "\t分数: " << stu.score<< endlSEO靠我; }// 2. 地址传递 void print_student_2(Student* p) {cout << "---------子函数[print_student_2]中打印---------" SEO靠我<< endl;p->name = "[地址传递]修改后的姓名";cout << "姓名: " << p->name << "\t年龄: "<< p->age << "\t分数: " << p->scSEO靠我ore<< endl; }int main() {Student stu;stu.name = "张三";stu.age = 20;stu.score = 80;// 将学生传入到一个函数中,打印学生SEO靠我身上所有的信息// 1. 值传递print_student_1(stu);cout << "---------main函数中打印---------" << endl;cout << "姓名: " <<SEO靠我 stu.name << "\t年龄: "<< stu.age << "\t分数: " << stu.score<< endl << endl << endl;// 2. 地址传递print_studSEO靠我ent_2(&stu);cout << "---------main函数中打印---------" << endl;cout << "姓名: " << stu.name << "\t年龄: "<< sSEO靠我tu.age << "\t分数: " << stu.score<< endl;/*---------子函数[print_student_1]中打印---------姓名: [值传递修]改后的姓名 SEO靠我 年龄: 20 分数: 80---------main函数中打印---------姓名: 张三 年龄: 20 分数: 80---------子函数[printSEO靠我_student_2]中打印---------姓名: [地址传递]修改后的姓名 年龄: 20 分数: 80---------main函数中打印---------姓名: [地址传递]SEO靠我修改后的姓名 年龄: 20 分数: 80*/return 0; }作用:用const来防止误操作。
示例:
#include<iostream> usiSEO靠我ng namespace std; #include<string>struct Student {string name;int age;int score; };void print_stu_inSEO靠我fo_value_trans(Student stu) {/** 这种值传递的方式会有问题:* 值传递的形参会复制传入的值,因此会带来额外的性能开销。* 如果调用这个函数的次数很多,那么带来的性能开销SEO靠我就会变大!* * 要想减小开销,可以使用地址传递!*/stu.age += 1; // 让年龄增加一岁cout << "姓名: " << stu.name << "\t年龄: " << stu.agSEO靠我e << "\t分数: " << stu.score << endl; }void print_stu_info_pointer_trans(const Student* stu) {/** 值传递因SEO靠我为会复制实参,带来了大量的性能开销,而地址传递* 传入的是指针,一个指针的大小为4字节(32位系统下),因此* 复制指针带来的性能开销明显降低!* * 但是地址传递有一个问题:那就是改变形参会改变实参SEO靠我。* 为了解决这个问题,我们应该使用const关键字!* * 具体实现是给形参加一个const,即const Student+* stu。* const修饰的是*,因此指针指向地址的值是不允许改变的,SEO靠我* 这样stu->age += 1;这行语句写完后就IDE就会报错,告诉* 我们不要修改指针指向地址的值!*///stu->age += 1; // 表达式必须是可修改的左值cout << "姓名:SEO靠我 " << stu->name << "\t年龄: "<< stu->age + 1 << "\t分数: " << stu->score<< endl; }int main() {// 创建结构体变量SEO靠我Student stu = { "张三", 18, 90 };// 通过函数打印结构体变量的信息print_stu_info_value_trans(stu);cout << "-----调用prinSEO靠我t_stu_info_value_trans后-----" << endl;cout << "姓名: " << stu.name << "\t年龄: "<< stu.age << "\t分数: " <SEO靠我< stu.score<< endl << endl << endl;print_stu_info_pointer_trans(&stu);cout << "-----调用print_stu_infoSEO靠我_pointer_trans后-----" << endl;cout << "姓名: " << stu.name << "\t年龄: "<< stu.age << "\t分数: " << stu.scSEO靠我ore<< endl;/*姓名: 张三 年龄: 19 分数: 90-----调用print_stu_info_value_trans后-----姓名: 张三 年龄: SEO靠我18 分数: 90姓名: 张三 年龄: 19 分数: 90-----调用print_stu_info_pointer_trans后-----姓名: 张三 SEO靠我 年龄: 18 分数: 90*/return 0; }案例描述:学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下:
设计学生和老师的结SEO靠我构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员学生的成员有姓名、考试分数创建数组存放3名老师,通过函数给每个老师及所带的学生赋值最终打印出老师数据以及老师所带的学生数据。示例:SEO靠我
#include<iostream> using namespace std; #include<string> #include<ctime>// 定义学生的结构体 struct Student {SEO靠我string stu_name;int stu_score; };// 定义老师的结构体 struct Teacher {string teac_name;// 学生数组Student stu_arrSEO靠我ay[5]; };// 给老师和学生赋值的函数 void allocate_space(Teacher teac_array[], int len) {string name_seed = "ABCDSEO靠我E";for (int i = 0; i < len; i++) // 外层:给老师赋值{teac_array[i].teac_name = "Teacher_";teac_array[i].teaSEO靠我c_name += name_seed[i];for (int j = 0; j < 5; j++) // 内层:给学生赋值{teac_array[i].stu_array[j].stu_name SEO靠我= "Student_";teac_array[i].stu_array[j].stu_name += name_seed[j];int random = rand() % 61 + 40; // SEO靠我40 ~ 100teac_array[i].stu_array[j].stu_score = random;}} }void print_info(Teacher teac_arraySEO靠我[], int len) {for (int i = 0; i < len; i++){cout << "老师姓名: " << teac_array[i].teac_name << endl;for SEO靠我(int j = 0; j < 5; j++){cout << "\t学生姓名: " << teac_array[i].stu_array[j].stu_name << "\t考试分数: " << tSEO靠我eac_array[i].stu_array[j].stu_score << endl;}} }int main() {// 加入随机数种子srand((unsigned int)tiSEO靠我me(NULL));// 1. 创建3名老师的数组Teacher teac_array[3];// 2. 通过函数给3名老师的信息赋值,并给老师带的学生赋值int len = sizeof(teac_SEO靠我array) / sizeof(teac_array[0]);allocate_space(teac_array, len);// 3. 打印所有老师及所带学生的信息print_info(teac_aSEO靠我rray, len);/*老师姓名: Teacher_A学生姓名: Student_A 考试分数: 78学生姓名: Student_B 考试分数: 40学生姓名: Student_C 考试分数: 86SEO靠我学生姓名: Student_D 考试分数: 61学生姓名: Student_E 考试分数: 42老师姓名: Teacher_B学生姓名: Student_A 考试分数: 87学生姓名: StudentSEO靠我_B 考试分数: 61学生姓名: Student_C 考试分数: 100学生姓名: Student_D 考试分数: 68学生姓名: Student_E 考试分数: 48老师姓名: Teacher_C学SEO靠我生姓名: Student_A 考试分数: 88学生姓名: Student_B 考试分数: 83学生姓名: Student_C 考试分数: 53学生姓名: Student_D 考试分数: 79学生姓名:SEO靠我 Student_E 考试分数: 90*/return 0; }案例描述:设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。
通过冒泡排SEO靠我序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。
五名英雄信息如下:
{"盖伦", 23, "男"}, {"卡特", 22, "女"}, {"赵信", SEO靠我30, "男"}, {"嘉文四世", 25, "男"}, {"瑞文", 24, "女"}, {"亚索", 20, "男"}, {"卡莎"SEO靠我, 26, "女"},示例:
#include<iostream> using namespace std; #include<string>// 1. 设计英雄结构体 SEO靠我 struct Hero {string name;int age;string gender; };void bubble_sort_for_hero(SEO靠我Hero hero_arr[], int n) {for (int i = 0; i < n - 1; i++){for (int j = 0; j < n - i - 1; j++){if (herSEO靠我o_arr[j].age > hero_arr[j + 1].age) {Hero tmp = hero_arr[j];hero_arr[j] = hero_arr[j + 1];hero_arr[jSEO靠我 + 1] = tmp;}}} }void print_hero(Hero hero_arr[], int n) {cout << "-------排序后的结果-------" << SEO靠我endl;for (int i = 0; i < n; i++){cout << "姓名: " << hero_arr[i].name << "\t年龄: "<< hero_arr[i].age <<SEO靠我 "\t性别: " << hero_arr[i].gender << endl;} }int main() {// 2. 创建数组存放5名英雄Hero hero_arr[] = {{"SEO靠我盖伦", 23, "男"},{"卡特", 22, "女"},{"赵信", 30, "男"},{"嘉文四世", 25, "男"},{"瑞文", 24, "女"},{"亚索", 20, "男"},{"卡莎SEO靠我", 26, "女"},};int n = sizeof(hero_arr) / sizeof(hero_arr[0]);// 3. 对数组进行排序,按照年龄进行升序排序bubble_sort_forSEO靠我_hero(hero_arr, n);// 4. 将排序后的结果打印输出print_hero(hero_arr, n);/*-------排序后的结果-------姓名: 亚索 年龄: 20SEO靠我 性别: 男姓名: 卡特 年龄: 22 性别: 女姓名: 盖伦 年龄: 23 性别: 男姓名: 瑞文 年龄: 24 SEO靠我 性别: 女姓名: 嘉文四世 年龄: 25 性别: 男姓名: 卡莎 年龄: 26 性别: 女姓名: 赵信 年龄: 30 性别: 男*/rSEO靠我eturn 0; }通讯录是一个可以记录亲人、好友信息的工具。本教程主要利用C++来实现一个通讯录管理系统。系统中需要实现的功能如下:
添加联系人:向通讯录中添加新人SEO靠我,信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录1000人显示联系人:显示通讯录中所有联系人信息删除联系人:按照姓名进行删除指定联系人查找联系人:按照姓名查看指定联系人信息修改联系人:按照姓SEO靠我名重新修改指定联系人清空联系人:清空通讯录中所有信息退出通讯录:退出当前使用的通讯录功能描述:用户选择功能的界面
菜单界面效果如下图:
步骤:
封装函数显示该界面如 voidSEO靠我 showMenu()在main函数中调用封装好的函数代码:
// 菜单界面 void show_menu() {cout << "*****************************" << eSEO靠我ndl;cout << "*****\t1. 添加联系人\t*****" << endl;cout << "*****\t2. 显示联系人\t*****" << endl;cout << "*****SEO靠我\t3. 删除联系人\t*****" << endl;cout << "*****\t4. 查找联系人\t*****" << endl;cout << "*****\t5. 修改联系人\t*****"SEO靠我 << endl;cout << "*****\t6. 清空联系人\t*****" << endl;cout << "*****\t0. 退出通讯录\t*****" << endl;cout << "SEO靠我*****************************" << endl; }功能描述:退出通讯录系统
思路:根据用户不同的选择,进入不同的功能,可以选择switch分支结构,将整个SEO靠我架构进行搭建。
当用户选择0时候,执行退出,选择其他先不做操作,也不会退出程序。
代码:
int main() {int select = 0; // 用户选择输入的变量while (true) // SEO靠我大循环{show_menu();cout << "请选择功能: ";cin >> select;// 根据输入做出判断switch (select){case 1: // 1. 添加联系人breakSEO靠我;case 2: // 2. 显示联系人break;case 3: // 3. 删除联系人break;case 4: // 4. 查找联系人break;case 5: // 5. 修改联系人bSEO靠我reak;case 6: // 6. 清空联系人break;case 0: // 0. 退出通讯录cout << "欢迎下次使用!" << endl;system("pause"); // 请按SEO靠我任意键继续return 0; // main函数的return -> 退出main函数break;default:cout << "您的输入无效!" << endl;break;}}system("SEO靠我pause");return 0; // 返回正常退出值 }功能描述:实现添加联系人功能,联系人上限为1000人,联系人信息包括(姓名、性别、年龄、联系电话、家庭住址SEO靠我)
添加联系人实现步骤:
设计联系人结构体设计通讯录结构体main函数中创建通讯录封装添加联系人函数测试添加联系人功能联系人信息包括:姓名、性别、年龄、联系电话、家庭住址
设计如SEO靠我下:
// 设计联系人结构体 struct Person {string p_name;int p_gender; // 1: 男; 2: 女int p_age;striSEO靠我ng p_phone;string p_address; };设计时候可以在通讯录结构体中,维护一个容量为1000的存放联系人的数组,并记录当前通讯录中联SEO靠我系人数量
设计如下:
// 设计通讯录结构体 struct AddressBooks {// 通信录中保存的联系人数组Person person_arr[MAX];// 初SEO靠我始化通讯录中当前人员个数(最后一个联系人的索引)int p_last_idx; };添加联系人函数封装好后,在main函数中创建一个通讯录变量,这SEO靠我个就是我们需要一直维护的通讯录。
int main() {// 创建通讯录结构体变量AddressBooks abs;// 初始化通讯录中当前人员个数(最后一个联系人的索引)abs.p_last_idxSEO靠我 = 0;}思路:添加联系人前先判断通讯录是否已满,如果满了就不再添加,未满情况将新联系人信息逐个加入到通讯录。
添加联系人代码:
// 1. 添加联系人 SEO靠我void add_person(AddressBooks* abs) {// 判断通讯录是否满了if (abs->p_last_idx == MAX) {cout << "通讯录已满,无法添加!" <SEO靠我< endl;return; // 这里的return表明当前函数结束}else {// 添加具体联系人// 姓名string name;cout << "请输入姓名: ";cin >> name;aSEO靠我bs->person_arr[abs->p_last_idx].p_name = name;// 性别int gender = 0;cout << "请输入性别(1为男性, 2为女性): ";whilSEO靠我e (true){cin >> gender;if (gender == 1 || gender == 2) {abs->person_arr[abs->p_last_idx].p_gender = SEO靠我gender;break; // 停止无限循环}else {cout << "您的输入有误,请重新输入: ";}}// 年龄int age = 0;cout << "请输入年龄: ";while (tSEO靠我rue){cin >> age;if (age <= 0 || age >= 150){cout << "您的输入有误,请重新输入: ";}else{abs->person_arr[abs->p_laSEO靠我st_idx].p_age = age;break; // 停止无限循环}}// 电话cout << "请输入联系电话(移动号码或固定号码): ";string phone;while (true){SEO靠我cin >> phone;if (phone.length() != 11 && phone.length() != 7){cout << "您输入的联系方式有误,请重新输入: ";}else{absSEO靠我->person_arr[abs->p_last_idx].p_phone = phone;break; // 停止无限循环}}// 住址cout << "请输入家庭住址: ";string addrSEO靠我ess;cin >> address;abs->person_arr[abs->p_last_idx].p_address = address;// 添加成功后,让最后一个联系的索引+1cout <<SEO靠我 "联系人[" << name << "]添加成功!" << endl;abs->p_last_idx += 1;// 添加清屏操作system("pause"); // 请按任意键继续system(SEO靠我"cls"); // 清屏操作: cls = clear screen} }测试效果如图:
功能描述:显示通讯录中已有的联系人信息
显示联SEO靠我系人实现步骤:
封装显示联系人函数测试显示联系人功能思路:判断如果当前通讯录中没有人员,就提示记录为空,人数大于0,显示通讯录中信息。
显示联系人代码:
// 2. 显示所有联SEO靠我系人 void show_person(AddressBooks* abs) {// 判断通讯录中人数是否为0if (abs->p_last_idx == 0){cout << "通讯SEO靠我录为空,请添加联系人" << endl;}else{for (int i = 0; i < abs->p_last_idx; i++){ cout << "[" << i + 1 << "]: " <SEO靠我< abs->person_arr[i].p_name << endl;cout << "\t性别: " << (abs->person_arr[i].p_gender == 1 ? "男" : "女SEO靠我") << endl;cout << "\t年龄: " << abs->person_arr[i].p_age << endl;cout << "\t电话: " << abs->person_arr[SEO靠我i].p_phone << endl;cout << "\t住址: " << abs->person_arr[i].p_address << endl;cout << "---------------SEO靠我----------------" << endl;}}system("pause");system("cls"); }功能描述:按照姓名进行删除指定联系人
删除联系人SEO靠我实现步骤:
封装检测联系人是否存在封装删除联系人函数测试删除联系人功能设计思路:删除联系人前,我们需要先判断用户输入的联系人是否存在。
如果存在删除不存在提示用户没有要删SEO靠我除的联系人因此我们可以把检测联系人是否存在封装成一个函数中:
如果存在,返回联系人在通讯录中的位置不存在返回-1。 // 检测联系人是否存在,如果存在则返回对应索引,不存在返回-1 SEO靠我 int is_exist(AddressBooks* abs, string name) {/** abs: 通讯录地址* name: 要删除人的名字*/for (int i = 0; iSEO靠我 < abs->p_last_idx; i++){if (abs->person_arr[i].p_name == name) // 找到了,返回对应的idx{return i;}}// 走完了forSEO靠我循环还是没有找到return -1; }根据用户输入的联系人判断该通讯录中是否有此人查找到进行删除,并提示删除成功
查不到提示查无此人。// 删除指定的联SEO靠我系人 void del_person(AddressBooks* abs) {cout << "请输入您要删除的联系人: ";string delete_name;cin >> delSEO靠我ete_name;int res = is_exist(abs, delete_name);if (res != -1){for (int i = res; i < abs->p_last_idx; SEO靠我i++){// 数据前移abs->person_arr[i] = abs->person_arr[i + 1];}// 更新通讯录最后一个人员的索引abs->p_last_idx -= 1;cout SEO靠我<< "删除成功..." << endl;}else{cout << "查无此人!" << endl;}system("pause");system("cls"); }功能描述:按照姓名查看指定联系人信息
查找联系人实现步骤:
封装查找联系人函数测试查找指定联系人实现思路:判断用户指定的联系人是否存在,如果存在显示信息,不存在则提示查无此SEO靠我人。
查找联系人代码:
// 4. 查找指定联系人信息 void find_person(AddressBooks* abs) {cout << "请输入您要查找的联系人: ";strinSEO靠我g find_name;cin >> find_name;// 判断指定联系人是否存在int res = is_exist(abs, find_name);if (res != -1){cout <<SEO靠我 "[" << res + 1 << "]: " << abs->person_arr[res].p_name << endl;cout << "\t性别: " << (abs->person_arrSEO靠我[res].p_gender == 1 ? "男" : "女") << endl;cout << "\t年龄: " << abs->person_arr[res].p_age << endl;coutSEO靠我 << "\t电话: " << abs->person_arr[res].p_phone << endl;cout << "\t住址: " << abs->person_arr[res].p_addrSEO靠我ess << endl;cout << "-------------------------------" << endl;}else{cout << "查无此人!" << endl;}system(SEO靠我"pause");system("cls"); }功能描述:按照姓名重新修改指定联系人
修改联系人实现步骤
封装修改联系人函数测试修改联系人功能实现思路:查找用户输入的联系人,如果查找成功进行修改操作,查找失败提示查无此人。
修改联系人代码:
// 5. 修改指定联系人信息 void modify_person(AddressSEO靠我Books* abs) {cout << "请输入您要修改的联系人: ";string name;cin >> name;int res = is_exist(abs, name);if (res !SEO靠我= -1){// 姓名string name;cout << "请输入姓名(不修改输入0): ";cin >> name;if (name != "0"){abs->person_arr[res].pSEO靠我_name = name;}// 性别string gender;while (true){cout << "请输入性别(不修改输入0): ";cin >> gender;if (gender != SEO靠我"0"){if (gender == "1"){abs->person_arr[res].p_gender = 1;break;}else if (gender == "2"){abs->personSEO靠我_arr[res].p_gender = 2;break;}else{cout << "您输入的性别有误(请输入1或2)" << endl;}}else{break;}}// 年龄int age;whSEO靠我ile (true){cout << "请输入年龄(不修改输入0): ";cin >> age;if (age == 0){break;}else{if (age <= 0 || age >= 150SEO靠我){cout << "您的输入有误,请重新输入" << endl;}else{abs->person_arr[res].p_age = age;break;}}}// 电话cout << "请输入电话SEO靠我(不修改输入0): ";string phone;while (true){ cin >> phone;if (phone == "0"){break;}if (phone.length() != 1SEO靠我1 && phone.length() != 7){cout << "您输入的联系方式有误,请重新输入(移动号码或固定号码): " << endl;}else{abs->person_arr[res]SEO靠我.p_phone = phone;break; }}// 地址cout << "请输入地址(不修改输入0): ";string address;cin >> address;if (address !SEO靠我= "0"){abs->person_arr[res].p_address = address;}cout << "修改成功!" << endl;}else{cout << "查无此人!" << enSEO靠我dl;}system("pause");system("cls"); }功能描述:清空通讯录中所有信息清空联系人
实现步骤:
封装清空联系人函数测试清空联系人实现思路:将通讯录所有联系人信息清除掉,只要将通讯录记录的联系人数量置为0,做逻辑清空即可。
清空联系人代码:
// 6. 清空所有联系人 void clear_alSEO靠我l_persons(AddressBooks* abs) {abs->p_last_idx = 0;cout << "通讯录已清空..." << endl;system("pause");systemSEO靠我("cls"); }网站备案号:浙ICP备17034767号-2