c++基础入门

1 c++初识

1.1 第一个c++程序

编写一个Hello world 程序:(注意main函数是程序的入口,有且只有一个)

#include <iostream>
using namespace std;
int main(){
cout << "Hello world" << endl;
system("pause");
return 0;
}

或者:

#include <iostream>
int main(){
std::cout << "Hello world" << std::endl;
system("pause");
return 0;
}

**"::"**表示作用域和所属关系:

  • 表示全局作用符(::name)例:(::a)表示调用全局变量a
  • 表示类作用府(class::name)例:(A::a)表示调用class A里的成员变量a
  • 表示命名空间作用符(namespace::name)例:(std::cout)
1.2 注释
  • 行注释:用“//”
  • 块注释:用“/**/”
1.3 变量

变量是给一段内存空间进行命名,之后可通过对变量进行操作从而达到对空间内容进行操作的目的。

1.4 常量

常量是用于记录程序中不可更改的数据,有两种:

  • 宏常量,用#define定义,且通常在文件上方进行定义(#define 常量名 常量值)
#define day 7
  • const修饰的常量,修饰某个变量为常量,且不可修改(const 变量类型 变量名=变量值)
const int day=7;
1.5 关键字

关键字是c++中预先保留的标识符,在定义常量或者变量的时候,不要用关键字

c++基础入门_c++


新增关键字:alignas、alignof、char16_t、char32_t、constexpr、decltype、noexcept、nullptr、static_assert、thread_local。

1.6 标识符的命名规则(尽量做到见名知义)
  • 不能是关键字
  • 区分大小写
  • 由数字(不能作为开头)、字母、下划线组成

2 数据类型

在创建变量或者常量时必须指出相应的数据类型,否则无法给其分配内存

2.1 整型(整数类型的数据)

整型大小比较:short<int<=long(取决于操作系统是Windows还是Linux)<long long

c++基础入门_c++_02


2.2 sizeof关键字

统计数据类型所占内存大小(相当于求解字节大小)

语法:sizeof(数据类型/变量)

int main(){
std::cout << "int类型所占内存空间为:" << std::endl;
system("pause");
return 0;
}

**2.3 实型(浮点型)**表示小数

  • 单精度float
  • 双精度double
    区别在于:表示的有效数字范围不同

    (编译器遇见小数默认为是双精度,但是加上f就可以表示单精度)
int main(){
float a = 3.14;//编译器先默认是双精度,然后再进行转换,比加上f多了一步操作。
float b = 3.14f;
double c = 6.56;
cout << "a= " << a << " " ;
cout << "b= " << b << " " ;
cout << "c= " << c << endl;
system("pause");
return 0;
}

科学计数法表示:e2表示10的平方 e-2表示0.1的平方

float f1 = 3e2; // 3*10^2
cout << "f1= " << f1 << endl;
float f2 = 3e-2; // 3*0.1^2
cout << "f2= " << f2 << endl;

2.4 字符型(用于显示单个字符)

语法:char ch = ‘a’;

c++基础入门_ios_03


c++基础入门_赋值_04


字符型变量对应的ASCII码值:a—97 A—65

#include <iostream>
using namespace std;
int main(){
char ch = 'a';
cout << ch << endl;//要想查看对应的ASCII码值,可以进行int的强制类型转换
cout << (int)ch << endl;//打印出对应的ASCII码值
cout << sizeof(ch) << endl;
cout << sizeof(char) << endl;
system("pause");
return 0;
}

2.5 转义字符
表示一些不能显示出来的ASCII字符,常用的有:\n \ \ \t

  • \n :换行,将当前位置移到下一行开头
  • \\ :代表一个反斜线字符
  • \t : 水平制表(跳到下一个TAB位置)有一个对齐的效果(和前面的多个字符拼接成8位)

2.6 字符串型(表示一串字符)
两种风格:

  • C风格:char 变量名[ ] = “字符串值”(注意[];还有双引号)
#include <iostream>
using namespace std;
int main() {
char str1[] = "hello world";
cout << str1 << endl;
system("pause");
return 0;
}
  • C++风格:string 变量名 = “字符串值”(注意头文件)
#include <iostream>
#include <string> //注意包含头文件
using namespace std;
int main() {
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 flag = false;
cout << flag << " ";
cout << sizeof(bool) << " ";
cout << sizeof(flag) << endl;
system("pause");
return 0;
}

2.8 数据的输入(用于从键盘获取数据)关键字:cin 语法:cin>>变量

#include <iostream>
#include <string>
using namespace std;
int main() {
//1.整型
int a = 0;
cout << "请给整型数a赋值: " << endl;
cin >> a;
cout << "a的值为: " << a << endl;
//2.浮点型
float f = 3.14f;
cout << "请给浮点型数f赋值: " << endl;
cin >> f;
cout << "f的值为: " << f << endl;
//3.字符型
char ch = 'a';
cout << "请给字符型数ch赋值: " << endl;
cin >> ch;
cout << "ch的值为: " << ch << endl;
cout << "ch的值对应的ASCII码值为: " << int(ch) << endl;
//4.字符串型
//c++方法
string str1 = "abv";
cout << "请给字符串型数str1赋值: " << endl;
cin >> str1;
cout << "str1的值为: " << str1 << endl;
//c方法
char str2[] = "abv";
cout << "请给字符串型数str2赋值: " << endl;
cin >> str2;
cout << "str2的值为: " << str2 << endl;
//5.布尔型
bool flag = false;
cout << "请给布尔型数flag赋值: " << endl;
cin >> flag;
cout << "flag的值为: " << flag << endl;
system("pause");
return 0;
}

3 运算符

3.1 算术运算符(处理四则运算)
  • 两个整数相除,结果仍是整数,小数被去除了
  • 两个数相除,除数不为0
  • 两个数相除,有一个是浮点数,结果就可以是浮点数
  • % 取模运算(取余数)例:10%3=1
  • 两个小数之间不能取模,只有整型变量才可以做取模运算
  • 注意(++a/- - a)和(a++/a- -)的区别在于表达式的值不一样
3.2 赋值运算符(将表达式的值赋给变量)
  • = 赋值
  • += /-= 加/减等于
  • *= / /= 乘/除等于
  • %= 取模等于
3.3 比较运算符(用于表达式的比较,并返回一个真值或者假值)

c++基础入门_ios_05

3.4 逻辑运算符(根据表达式的值返回真值或假值)

c++基础入门_ios_06

4 程序流程结构

C/C++都支持三种基本的程序运行结构:

  • 顺序结构:程序按顺序执行,不跳转
  • 选择结构:依据条件是否满足,有选择地执行相应的功能
  • 循环结构:依据条件是否满足,循环多次执行某段代码

4.1 选择结构

4.1.1 if语句
  • 单行格式if语句:if(条件){条件满足执行的语句}
    if条件表达式后不要加分号
#include <iostream>
using namespace std;
int main() {
int score = 0;
cout << "请输入一个分数: " << endl;
cin >> score;
cout << "您输入的分数是: " << score << endl;
if (score > 600) {
cout << "恭喜你考上一本大学"<< endl;
}
cout << endl;
system("pause");
return 0;
}
  • 多行格式if语句:if(条件){条件满足执行的语句} else{条件不满足执行的语句}
#include <iostream>
using namespace std;
int main() {
int score = 0;
cout << "请输入一个分数: " << endl;
cin >> score;
cout << "您输入的分数是: " << score << endl;
if (score > 600) {
cout << "恭喜您考上一本大学"<< endl;
}
else
{
cout << "很遗憾,您未考上一本大学" << endl;
}
cout << endl;
system("pause");
return 0;
}
  • 多条件的if语句:if(条件1){条件1满足执行的语句} else if(条件2满足执行的语句)… else {条件都不满足执行的语句};
#include <iostream>
using namespace std;
int main() {
int score = 0;
cout << "请输入一个分数: " << endl;
cin >> score;
cout << "您输入的分数是: " << score << endl;
if (score > 600) {
cout << "恭喜您考上一本大学"<< endl;
}
else if (score > 520) {
cout << "恭喜您考上二本大学" << endl;
}
else
{
cout << "很遗憾,您未考大学" << endl;
}
cout << endl;
system("pause");
return 0;
}

嵌套if语句:if语句里再包含了if

c++基础入门_赋值_07

#include <iostream>
using namespace std;
int main() {
int score = 0;
cout << "请输入一个分数: " << endl;
cin >> score;
cout << "您输入的分数是: " << score << endl;
if (score > 600) {
if (score > 700)
{
cout << "恭喜您考上清华大学" << endl;
}
else if (score > 650)
{
cout << "恭喜您考上北京大学" << endl;
}
else if (score > 600)
{
cout << "恭喜您考上中国人民大学" << endl;
}
else {
cout << "恭喜您考上一本大学" << endl;
}
}
else if (score > 500) {
cout << "恭喜您考上二本大学" << endl;
}
else if (score > 400) {
cout << "恭喜您考上三本大学" << endl;
}
else
{
cout << "很遗憾,您未考上本科" << endl;
}
system("pause");
return 0;
}
4.1.2 三目运算符

语法结构:表达式1?表达式2:表达式3

  • 表达式1为真则执行表达式2否则执行表达式3
#include <iostream>
using namespace std;
int main() {
//创建三个变量 a b c
//将a b 进行比较,将大的那个值赋值给变量c
int a = 20;
int b = 30;
int c = 0;
c = a > b ? a : b;
cout << "c的值为: " << c << endl;
system("pause");
return 0;
}
#include <iostream>
using namespace std;
int main() {
//在C++中三目运算符返回的是变量,可以继续赋值
int a = 20;
int b = 30;
(a > b ? a : b) = 50;
cout << "a的值为: " << a << "\n";
cout << "b的值为: " << b << endl;
system("pause");
return 0;
}
4.1.3 switch语句

优点:结构清晰,执行效率高
缺点:判断的时候只能是整型或者字符型而不能是一个区间

  • 作用:执行多条件分支语句
  • 语法:

switch(表达式)
{
case 结果1: 执行语句;break;
case 结果2: 执行语句;break;

default:执行语句;break;
}

#include <iostream>
using namespace std;
int main() {
//给电影打分(9-10 经典;7-8 非常好;5-6 一般; 5分以下 烂片)
//1.提示用户给电影打分
cout << "请输入对电影的评分: " << endl;
//2.用户开始输入分数
int score = 0;
cin >> score;
cout << "您输入的分数为: " << 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;
}
system("pause");
return 0;
}

4.2 循环结构

4.2.1 while循环结构
  • 作用:满足循环条件,执行循环语句
  • 语法:while(循环条件){ 循环语句 }
  • 解释:只要循环条件为真,就执行循环语句
using namespace std;
int main() {
//while循环
//在屏幕中打印 0-9 这10个数
int num = 0;
while (num <= 9) {
cout << num << " ";
num++;
}
cout << endl;
system("pause");
return 0;
}

实例练习:猜数字
案例描述:系统随机生成1到100之间的数字,玩家进行猜测,如果猜错,提示玩家数字过大或者过小,如果猜对,恭喜玩家胜利,并且退出游戏。

#include <iostream>
using namespace std;
//time系统时间头文件包含
#include <ctime>
int main() {
//此处的随机数是一个伪随机数,值一直都是一样的,要想使其真正的随机,方法如下:
//添加随机数种子,利用当前系统时间生成随机数,防止每次随机数都是一样的
srand((unsigned int)time(NULL));
//1.系统生成随机数
int num = rand() % 100 +1; //rand()%100 是生成0-99的随机数 如果要生成1-100可以直接在后面加1
cout << "这个随机数的值为:" << num << endl;
//2.玩家进行猜测
int val = 0;//玩家输入猜测值
while (!(val==num))
{
cout << "请输入您的猜测:" << endl;
cin >> val;
//3.判断玩家的猜测
if (val > num) {
cout << "您猜测的数值为" << val << "偏大" << endl;
}
else if( val < num)
{
cout << "您猜测的数值为" << val << "偏小" << endl;
}
else
{
cout << "您猜测的数值为" << val << "正确" << endl;
}
}
//猜对 退出游戏
//猜错 提示玩家过大或者过小 重新返回第二步
system("pause");
return 0;
}
4.2.2 do…while循环结构
  • 语法:do{ 循环语句 } while( 循环条件 );
  • 注意:与while的区别就在于do…while会先执行一次循环语句,在判断循环条件。
#include <iostream>
using namespace std;
int main() {
//do...while语句
//在屏幕上输出0到9这十个数字
int num = 0;
do{
cout << num << " ";
num++;
} while (num < 10);
cout << endl;
system("pause");
return 0;
}

案例练习:水仙花数
案例描述:
水仙花数是指一个三位数,它每个位上的数字的3次幂之和等于它本身 例如:1 ^ 3 + 5 ^ 3 +3 ^ 3 = 153
请利用do…while语句,求出所有三位数中的水仙花数。

#include <iostream>
using namespace std;
int main() {
int num = 100;
do {
int a = 0;
int b = 0;
int c = 0;
a = num % 10;//表示个位数
b = num / 10 % 10;//表示十位数
c = num / 100;//表示百位数
if (a*a*a + b*b*b + c*c*c == num) {
cout << num << endl;
}
num++;
} while (num<1000);
system("pause");
return 0;
}
4.2.3 for循环结构
  • for(起始表达式;条件表达式;末尾循环体 ) { 循环语句;}
#include <iostream>
using namespace std;
int main() {
for (int i = 0; i <= 3; i++) {
cout << i << " ";
}
cout << endl;
system("pause");
return 0;
}

练习案例:敲桌子
案例描述:从一开始到数字100,如果数字个位含有7,或者数字十位含有7,或者该数字是7的倍数,我们打印敲桌子,其余数字直接打印输出。

#include <iostream>
using namespace std;
int main() {
//1.先打印1-100的数
//2.判断这个数个位是否含有7,或者数字十位是否含有7,或者该数字是否是7的倍数
//3.将其结果打印输出
for (int num = 1; num <= 100; num++) {
if (num % 10 == 7 || num / 10 % 10 == 7 || num % 7 == 0) {
cout << "敲桌子" << endl;
}
else
{
cout << num << endl;
}
}
system("pause");
return 0;
}
4.2.4 嵌套循环
  • 在循环体中再裹一层循环,解决一些实际问题
  • 例如,打印下图:
#include <iostream>
using namespace std;
int main() {
//打印矩阵式的星图
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
cout << "*" << " ";
}
cout << endl;
}
//1.先打印一行
//2.嵌套循环打印多行
system("pause");
return 0;
}

案例练习:乘法口诀表
案例描述:利用嵌套循环,实现九九乘法表

#include <iostream>
using namespace std;
int main() {
//实现九九乘法表
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
cout << i << "x" << j <<"="<< i*j << "\t";
}
cout << endl;
}
system("pause");
return 0;
}

4.3 跳转语句

4.3.1 break语句

作用:用于跳出选择结构或者循环结构

  • 出现在switch条件语句中,作用是终止case并跳出switch
  • 出现在循环语句中,作用就是跳出当前循环语句
  • 出现在嵌套循环中,跳出最近的内层循环语句
4.3.2 continue语句

作用:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环

#include <iostream>
using namespace std;
int main() {
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0) {
continue;
}
cout << i << " ";
}
cout << endl;
system("pause");
return 0;
}
4.3.3 goto语句
  • 作用:可以无条件跳转
  • 语法:goto 标记
  • 解释:如果标记的名称存在,执行到goto语句时,会跳转到标记的位置
#include <iostream>
using namespace std;
int main() {
//goto语句
cout << "1.xxxxx" << endl;
cout << "2.xxxxx" << endl;
goto FLAG;
cout << "3.xxxxx" << endl;
FLAG:
cout << "4.xxxxx" << endl;
cout << "5.xxxxx" << endl;
system("pause");
return 0;
}

5 数组

5.1 概述

  • 数组:存放了相同数据类型的数据元素的一个集合
  • 特点1:数组中的每个数据元素都是相同的数据类型
  • 特点2:数组是由连续的内存位置组成的
  • 对于数组的下标,我们可以通过下标访问数组中的元素

5.2 一维数组

练习案例1:五只小猪称体重
案例描述:
在一个数组中记录了五只小猪的体重如:
int arr[5]={300,350,200,400,250};
找出并打印最重的小猪体重

#include <iostream>
using namespace std;
int main() {
//五只小猪称体重
//使用的是冒泡排序法
//1.先用一个数组记录5只小猪的体重
int arr[5] = {300,350,200,400,250};
int temp = 0;
int i = 0;
//2.将小猪的体重显示在屏幕上
cout << "五只小猪的体重分别是: ";
while (i < 5) {
cout << arr[i] << " ";
i++;
}
cout << endl;
for (int index = 0; index < 5; index++) {
//3.比较5只小猪的体重,找出最重的
for (int index1 = index + 1; index1 < 5; index1++) {
if (arr[index] > arr[index1]) {
temp = arr[index];
arr[index] = arr[index1];
arr[index1] = temp;
}
}
}
//4.打印输出最重的小猪体重
cout << "最重的小猪体重为: " << arr[4] << endl;
system("pause");
return 0;
}
#include <iostream>
using namespace std;
int main() {
//五只小猪称体重
//1.先用一个数组记录5只小猪的体重
int arr[5] = {300,350,200,400,250};
//设置一个最重的体重为max
int max = 0;
int i = 0;
//2.将小猪的体重显示在屏幕上
cout << "五只小猪的体重分别是: ";
while (i < 5) {
cout << arr[i] << " ";
i++;
}
cout << endl;
for (int index = 0; index < 5; index++) {
//3.比较5只小猪的体重,找出最重的
if (arr[index] > max) {
max = arr[index];
}
}
//4.打印输出最重的小猪体重
cout << "最重的小猪体重为: " << max << endl;
system("pause");
return 0;
}

练习案例2:数组元素逆置
案例描述:
请声明一个5个元素的数组,并且将元素逆置。
(如原数组元素为:1,3,2,5,4 逆置后结果为:4,5,2,3,1);

#include <iostream>
using namespace std;
int main() {
//数组元素逆置
//1.声明一个5个元素的数组
int arr[5];
int index = 0;
int temp = 0;
//2.提示用户进行输入
cout << "请输入5个整数: " << endl;
while(index<5)
{
cin >> arr[index];
index++;
}
//3.打印输出输入的数组元素
cout << "您输入的数组元素为: ";
for (int i = 0; i < 5; i++) {
cout << arr[i] << " ";
}
cout << endl;
//4.将数组的元素进行逆置
for (int j = 0; j < 2; j++) {
temp = arr[j];
arr[j] = arr[4 - j];
arr[4 - j] = temp;
}
//5.输出逆置后的数组元素
cout << "逆置后的数组为: " << endl;
for (int i = 0; i < 5; i++) {
cout << arr[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
#include <iostream>
using namespace std;
int main() {
//数组元素逆置
//1.声明一个5个元素的数组
int arr[5] = {98,97,58,99,63};
//2.打印输出逆置前的数组元素
cout << "逆置前数组元素为: ";
for (int i = 0; i < 5; i++) {
cout << arr[i] << " ";
}
cout << endl;
//3.将数组的元素进行逆置
/*逆置的具体方法:原理就是前面和后面的元素位置互换
1.先找到最前面的元素和最后一个元素的角标
2.交换两元素的值,交换的时候不能忘记有中间变量temp
(start++而对应的end--)
3.直到前后两个角标相等时,停止交换
*/
int temp = 0;
int start = 0;
int end = sizeof(arr) / sizeof(arr[0]) - 1;
while (!(start == end)) {
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
//4.输出逆置后的数组元素
cout << "逆置后数组元素为: ";
for (int i = 0; i < 5; i++) {
cout << arr[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
5.2.1 一维数组定义方式

三种定义数组的方法:

  1. 数据类型 数组名[ 数组长度 ];
  2. 数据类型 数组名[ 数组长度 ] = { 值1, 值2, … };
  3. 数据类型 数组名[] = { 值1, 值2, … };

c++基础入门_c++_08


c++基础入门_赋值_09

#include <iostream>
using namespace std;
int main() {
//数组
/*
1. 数据类型 数组名[ 数组长度 ];
2. 数据类型 数组名[ 数组长度 ] = { 值1, 值2, ... };
3. 数据类型 数组名[] = { 值1, 值2, ... };
*/
//1. 数据类型 数组名[数组长度];
int arr[5];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
for (int index = 0; index < 5; index++) {
cout << arr[index] << " ";
}
cout << endl;
//2. 数据类型 数组名[数组长度] = { 值1, 值2, ... };
int arr[5] = { 10,20,30,40,50 };
for (int index = 0; index < 5; index++) {
cout << arr[index] << " ";
}
cout << endl;
//3. 数据类型 数组名[] = { 值1, 值2, ... };
int arr[] = { 10,20,30,40,50 };
for (int index = 0; index < 5; index++) {
cout << arr[index] << " ";
}
cout << endl;
system("pause");
return 0;
}
5.2.2 一维数组数组名
  • 可以通过数组名统计整个数组在内存中的长度 sizeof( arr )
  • 数组名是常量,不可以进行赋值操作
  • 获取数组元素的地址可以使用(&arr[index]),其中index为索引
  • 可以获取数组在内存中的首地址(arr)
int  arr[ 5 ] = {1,2,3,4,5};

c++基础入门_#include_10

#include <iostream>
using namespace std;
int main() {
//数组名的用途
//1.可以通过数组名统计数组所占的内存空间
int arr[] = { 1,2,3,4,5 };
cout << "arr数组所占内存空间为: " << sizeof(arr) << endl;
//2.可以找到数组的地址
cout << "arr数组的地址为: " << arr << endl;
system("pause");
return 0;
}

c++基础入门_ios_11

对于数组的角标(索引)可以利用sizeof来表示:

  • start索引值为0
  • 数组长度:sizeof(arr) / sizeof(arr[0])
  • end索引值:sizeof(arr) / sizeof(arr[0])-1
5.2.3 冒泡排序
  • 比较相邻的两个元素,如果第一个比第二个大就交换
  • 对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值
  • 重复以上的步骤,每次比较次数减一,直到不需要比较
#include <iostream>
using namespace std;
int main() {
//将数组(4,2,8,0,5,7,1,3,9)进行升序排序
int arr[] = {4,2,8,0,5,7,1,3,9};
//定义中间变量temp暂存数组元素的值
int temp = 0;
//1.输出排序前的数组
cout << "排序前数组为: " << endl;
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
cout << arr[i] << " ";
}
cout << endl;
//2.将数组元素进行比较交换位置排序
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
for (int j = i+1; j < (sizeof(arr) / sizeof(arr[0])); j++) {
if (arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
//3.输出排序后的数组
cout << "排序后数组为: " << endl;
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
cout << arr[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
//2.将数组元素进行比较交换位置排序
for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])-1); i++) //比较的次数,9个数比较8次{
for (int j = 0; j < (sizeof(arr) / sizeof(arr[0]))-1-i; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}

5.3 二维数组

5.3.1 二维数组定义方式

二维数组定义的四种方式:

  • 数据类型 数组名 [ 行数 ] [ 列数 ] ;
  • 数据类型 数组名 [ 行数 ] [ 列数 ] = { { 数据1,数据2} ,{数据3 , 数据4} };
  • 数据类型 数组名 [ 行数 ] [ 列数 ] = { 数据1,数据2,数据3 ,数据4 };
  • 数据类型 数组名 [ ] [ 列数 ] = { 数据1,数据2,数据3 ,数据4 };
    第二种方式更加直观,提高代码的可读性
    方式一
#include <iostream>
using namespace std;
int main() {
//方式1
//数组类型 数组名[行数][列数];
int arr[2][2];
arr[0][0] = 1;
arr[0][1] = 2;
arr[1][0] = 3;
arr[1][1] = 4;
//输出数组值
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
cout << arr[i][j] << " ";
}
}
cout << endl;
system("pause");
return 0;
}

方式二

#include <iostream>
using namespace std;
int main() {
//方式2
//数组类型 数组名[行数][列数] = { { 数据1,数据2} ,{数据3 , 数据4} };
int arr[2][2] = { {1,2} ,{3,4} };
//输出数组值
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
cout << arr[i][j] << " ";
}
}
cout << endl;
system("pause");
return 0;
}

方式三

#include <iostream>
using namespace std;
int main() {
//方式3
//数组类型 数组名[行数][列数] = { 数据1,数据2,数据3 ,数据4};
int arr[2][2] = { 1,2,3,4 };
//输出数组值
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
cout << arr[i][j] << " ";
}
}
cout << endl;
system("pause");
return 0;
}

方式四

#include <iostream>
using namespace std;
int main() {
//方式4
//数组类型 数组名[][列数] = { 数据1,数据2,数据3 ,数据4};
int arr[][2] = { 1,2,3,4 };
//输出数组值
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
cout << arr[i][j] << " ";
}
}
cout << endl;
system("pause");
return 0;
}
5.3.2 二维数组数组名
  • 查看二维数组所占内存空间
  • 获取二维数组首地址
#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 << "二维数组首地址: " << &arr[0][0] << endl;
system("pause");
return 0;
}
5.3.3 二维数组应用案例

考试成绩统计:

案例描述:
有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表,请分别输出三名同学的总成绩

科目/姓名

语文

数学

英语

张三

100

100

100

李四

90

50

100

王五

60

70

80

#include <iostream>
using namespace std;
int main() {
int score[3][3] = {
{100,100,100},
{90,50,100},
{60,70,80}
};
cout << "张三的总成绩为: " << score[0][0]+ score[0][1]+score[0][2] << endl;
cout << "李四的总成绩为: " << score[1][0] + score[1][1] + score[1][2] << endl;
cout << "王五的总成绩为: " << score[2][0] + score[2][1] + score[2][2] << endl;
system("pause");
return 0;
}
#include <iostream>
using namespace std;
int main() {
int score[3][3] = {
{100,100,100},
{90,50,100},
{60,70,80}
};
for (int i = 0; i < 3; i++) {
int sum = 0;
//计算单个人的总成绩
for (int j = 0; j < 3 ; j++) {
sum += score[i][j];
}
switch (i) {
case 0: cout << "张三的总成绩为: " << sum << endl; break;
case 1: cout << "李四的总成绩为: " << sum << endl; break;
case 2: cout << "王五的总成绩为: " << sum << endl; break;
}
}
system("pause");
return 0;
}

6 函数

6.1 概述

作用:将一段经常使用的代码封装起来,减少重复代码
一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。

6.2 函数的定义

函数的定义一般有5个步骤:

  • 返回值类型
  • 函数名
  • 参数表列
  • 函数体语句
  • return表达式
    语法:

返回值类型 函数名 { 参数列表 } {

函数体语句return表达式

}

例如:实现一个加法的函数
功能是:传入两个整型数据,计算数据相加的结果,并且返回。

#include <iostream>
using namespace std;
int sum(int a, int b);//函数的声明
//函数定义在调用之后要进行声明,在之前则可以直接调用
int main() {
int value = 0;
int num1 = 0;
int num2 = 0;
cout << "请输入第一个数的值:" << endl;
cin >> num1;
cout << "请输入第二个数的值:" << endl;
cin >> num2;
value = sum(num1, num2);
cout << num1 << "和" << num2 << "的和是" << value << endl;
system("pause");
return 0;
}
int sum(int a, int b) {
int sum = a + b;
return sum;
}

6.3 函数的调用

功能:使用定义好的函数
语法:函数名(参数)

6.4 值传递

  • 所谓值传递,就是函数调用时实参将数值传入给形参
  • 值传递时,如果形参发生变化,并不会影响实参
#include <iostream>
using namespace std;
void swap(int, int);
int main() {
int a = 1;
int b = 2;
//调用交换函数
swap(a, b);
cout << "a的值为: " << a << " ";
cout << "b的值为: " << b << endl;
system("pause");
return 0;
}
//定义交换函数
void swap(int num1, int num2) {
cout << "交换前: " << endl;
cout << "num1的值: " << num1 << " ";
cout << "num2的值: " << num2 << endl;

int temp = num1;
num1 = num2;
num2 = temp;

cout << "交换后: " << endl;
cout << "num1的值: " << num1 << " ";
cout << "num2的值: " << num2 << endl;
}

6.5 函数的常见样式

  • 无参无返
  • 有参无返
  • 无参有返
  • 有参有返
    示例:
#include <iostream>
using namespace std;

//函数常见样式
//1.无参无返
void test1() {
cout << "你好好看!" << endl;
}
//2.有参无返
void test2(int a,int b) {
//交换a,b的值
int temp = a;
a = b;
b = temp;
}
//3.无参有返
int test3() {
int arr[3] = { 1,2,3 };
return arr[0];
}
//4.有参有返
int test4(int a, int b) {
int sum = a + b;
return sum;
}
int main() {
system("pause");
return 0;
}

6.6 函数的声明

  • 作用:告诉编译器函数名称及如何调用函数,函数的实际主体可以单独定义
  • 函数的声明可以多次,但是函数的定义只能有一次
#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() {
//调用函数max()
int result = max(6, 8);
cout << "较大值为:" << result << endl;
system("pause");
return 0;
}

6.7 函数的分文件编写

作用:让代码结构更加清晰
函数分文件编写一般有4个步骤

  • 创建后缀名为.h的头文件
  • 创建后缀名为.cpp的源文件
  • 在头文件中写函数的声明
  • 在源文件中写函数的定义
//swap.h文件
#include <iostream>
using namespace std;
//.h文件里是函数的声明

//实现两个数字交换的函数声明
void swap(int a, int b);
//swap.cpp文件
#include "swap.h"
#include <iostream>
using namespace std;
//swap函数定义
void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}

7 指针

7.1 指针的基本概念

指针的作用:可以通过指针间接访问内存

  • 内存编号是从0开始记录的,一般用十六进制数字表示
  • 可以利用指针变量保存地址

7.2 指针变量的定义和使用

指针变量定义语法:数据类型 *变量名
示例:

#include <iostream>
using namespace std;
int main() {
//1.定义指针变量
int a = 0;//定义整型变量
int *b;
b = &a;//定义指针变量b为a的地址
cout << "b的值为: " << b << endl;
system("pause");
return 0;
}

7.3 指针所占内存空间

指针也是一种数据类型,那么这种数据类型占用多少内存空间呢?

  • 在32位操作系统下:占用4个字节空间,64位下占8个字节
#include <iostream>
using namespace std;
int main() {
//1.定义指针变量
int a = 0;//定义整型变量
int *b;
b = &a;//定义指针变量b为a的地址
cout << *b << endl;//解引用,b指向地址所保存的值
cout << sizeof(b) << endl;
cout << sizeof(int *) << endl;
cout << sizeof(char *) << endl;
cout << sizeof(float *) << endl;
cout << sizeof(double *) << endl;
system("pause");
return 0;
}

7.4 空指针和野指针

  • 空指针:指针变量指向内存中编号为0的空间
  • 用途:初始化指针变量
  • 注意:空指针指向的内存是不可以访问的
    示例1:空指针
#include <iostream>
using namespace std;
int main() {
//指针变量p指向内存中编号为0的空间
int *p = NULL;
//访问空指针报错
//内存编号0~255为系统占用内存,不允许用户访问
cout << *p << endl;
system("pause");
return 0;
}
  • 野指针:指针变量指向非法的(不是用户申请的)内存空间
    示例2:野指针
#include <iostream>
using namespace std;
int main() {
//指针变量p指向内存中编号为0x1100的空间
int *p = (int *)0x1100;
//访问野指针报错
cout << *p << endl;
system("pause");
return 0;
}

7.5 const修饰指针

const修饰的指针有三种情况:

  • const修饰指针 ——常量指针
  • const修饰常量 ——指针常量
  • const即修饰指针,又修饰常量
#include <iostream>
using namespace std;
int main() {
int a = 0;
// const修饰指针,指针指向可以改,但是指向的值不可以改
const int *p = 0;
//*p = 1;//错误
p = &a;
//const修饰常量,指针指向不可以改,但指向的值可以改
int * const q = 0;
//q=&a;//错误
*q = 9;
system("pause");
return 0;
}

7.6 指针和数组

作用:利用指针访问数组中的元素
示例:

#include <iostream>
using namespace std;
int main() {
int arr[] = { 1,2,3,4,5,6 };
int *p = arr;//定义p指针指向数组
cout << "第一个元素: " << arr[0] << endl;
cout << "指针访问第一个元素: " << *p << endl;
//利用指针遍历数组
for(int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
cout << *p << " ";
p++;
}
cout << endl;
system("pause");
return 0;
}

7.7 指针和函数

作用:利用指针作函数参数,可以修改实参的值

#include <iostream>
using namespace std;
//实现两个数字进行交换
void swap1(int a, int b) {
int temp = a;
a = b;
b = temp;
cout << "swap1 a,b的值分别为: " << a << " " << b << endl;
}
void swap2(int *p, int *q) {
int temp = *p;
*p = *q;
*q = temp;
cout << "swap2 a,b的值分别为: " << *p << " " << *q << endl;
}
int main() {
//指针和函数
//1.值传递
int a = 10;
int b = 20;
swap1(a, b);
cout << "交换后a,b的值分别为: " << a << " " << b << endl;
//2.指针传递
swap2(&a, &b);
cout << "交换后a,b的值分别为: " << a << " " << b << endl;
system("pause");
return 0;
}

c++基础入门_ios_12

7.8 指针、数组、函数

案例描述: 封装一个函数,利用冒泡排序,实现对整型数组的升序排序
例如数组:int arr[ 10 ] = { 4,3,6,9,1,2,10,8,7,5 }

#include <iostream>
using namespace std;
//冒泡排序
void bubbleSort(int * arr,int length ) {//定义了一个指向数组的指针,传实参时就传地址
for (int i = 0; i < length-1; i++) {
for (int j = 0; j < length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main() {
int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
cout << "调用bubbleSort函数前的数组元素: " << endl;
for (int i = 0; i < 10; i++) {
cout << arr[i] << " ";
}
cout << endl;
bubbleSort(&arr[0], 10);
cout << "调用bubbleSort函数后的数组元素: " << endl;
for (int i = 0; i < 10; i++) {
cout << arr[i] << " ";
}
cout << endl;
system("pause");
return 0;
}

8 结构体

8.1 结构体基本概念

结构体是用户自己定义的数据类型,允许用户存储不同的数据类型

8.2 结构体定义和使用

语法: struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的三种方式:

  • struct 结构体名 变量名
  • struct 结构体名 变量名 = { 成员1值, 成员2值…}
  • 定义结构体时顺便创建变量
#include <iostream>
using namespace std;
#include <string>
//1.创建学生数据类型:学生包括(姓名、年龄、分数)
struct student {
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
}s3;//2.3 在定义结构体的时候创建变量
int main() {
//2.通过学生类型创建具体学生
//2.1 struct student s1
struct student s1;
s1.name = "李华";
s1.age = 18;
s1.score = 99;
cout << s1.name << "的年龄是: " << s1.age << ", " << "分数是: " << s1.score << endl;
//2.2 struct student s2{ ... }
struct student s2 { "韩梅梅", 20, 89 };
cout << s2.name << "的年龄是: " << s2.age << ", " << "分数是: " << s2.score << endl;
s3.name = "王五";
s3.age = 22;
s3.score = 87;
cout << s3.name << "的年龄是: " << s3.age << ", " << "分数是: " << s3.score << endl;
system("pause");
return 0;
}

8.3 结构体数组

  • 作用: 将自定义的结构体放入到数组中方便维护
  • 语法: struct 结构体名 数组名[ 元素个数 ] = { { } ,{ } ,… { } }
    示例:
#include <iostream>
using namespace std;
#include <string>
//1.创建学生数据类型:学生包括(姓名、年龄、分数)
struct student {
//成员列表
//姓名
string name;
//年龄
int age;
//分数
int score;
};
int main() {
//2.通过学生类型创建具体学生数组
struct student arr[3] =
{
{ "张三", 20, 89 },
{ "李四", 22, 90 },
{ "王二", 24, 91 }
};
for (int i = 0; i < 3; i++) {
cout << arr[i].name << "的年龄是: " << arr[i].age << ", " << "分数是: " << arr[i].score << endl;
}
system("pause");
return 0;
}

8.4 结构体指针

  • 通过指针访问结构体中的成员
  • 利用操作符 -> 可以通过结构体指针访问结构体属性
#include <iostream>
using namespace std;
#include <string>
//结构体指针
struct student {
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
int main() {
//创建学生结构体变量
struct student s = { "张三", 20, 89 };
//通过指针指向结构体变量
struct student * p = &s;
//通过指针访问结构体变量中的数据
cout << "姓名:" << p->name << endl;
system("pause");
return 0;
}

8.5 结构体嵌套结构体

  • 结构体中的成员可以是另一个结构体
  • 例如:每个老师辅导一个学生,一个老师的结构体中,记录一个学生的结构体
    示例:
#include <iostream>
using namespace std;
#include <string>
//学生结构体定义
struct student {
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
//老师结构体定义
struct teacher {
//成员列表
int id;//职工编号
string name;//教师姓名
int age;//教师年龄
struct student stu;//子结构体学生
};
int main() {
//结构体嵌套结构体
//创建老师结构体变量
struct student stu = { "张三", 20, 89 };
struct teacher tea;
struct student *p = &stu;
tea.id = 15;
tea.name = "lili";
tea.age = 58;
tea.stu.age = p->age;
tea.stu.name = p->name;
tea.stu.score = p->score;
cout << tea.name << "的年龄是: " << tea.age << ", " << "学生的分数是: " << tea.stu.score << endl;
system("pause");
return 0;
}

8.6 结构体做函数参数

  • 作用: 将结构体作为函数参数向函数中传递
  • 传递方式有两种: 1.值传递 2.地址传递
#include <iostream>
using namespace std;
#include <string>
//学生结构体定义
struct student {
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
//1.值传递
void printStuname(student stu) {
cout <<"值传递时: "<< stu.name << "的年龄是: " << stu.age << ", " << "分数是: " << stu.score << endl;
}
//2.地址传递
void printStuname1(student *stu) {
cout << "地址传递时: " << stu->name << "的年龄是: " << stu->age << ", " << "分数是: " << stu->score << endl;
}
int main() {
student a = { "张三", 20, 89 };
printStuname(a);
printStuname1(&a);
system("pause");
return 0;
}

8.7 结构体中const使用场景

作用: 用const来防止误操作
示例:

#include <iostream>
using namespace std;
#include <string>
//学生结构体定义
struct student {
//成员列表
string name; //姓名
int age; //年龄
int score; //分数
};
//const使用场景
void printStuname1(student const *stu) {//用const来防止误操作
//stu->age = 98;//操作失败,因为加了const修饰
cout << "地址传递时: " << stu->name << "的年龄是: " << stu->age << ", " << "分数是: " << stu->score << endl;
}
int main() {
student a = { "张三", 20, 89 };
printStuname1(&a);
system("pause");
return 0;
}

8.8 结构体案例

8.8.1 案例1

案例描述:
学校正在做毕设项目,每名老师带领5个学生,总共有三名老师,需求如下:

  • 设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员
  • 学生的成员有姓名、考试分数、创建数组存放三名老师,通过函数给每个老师及所需的学生赋值
  • 最终打印输出老师数据以及老师所需的学生数据
    示例:
#include <iostream>
using namespace std;
#include <string>
#include <ctime>
//学生结构体定义
struct student {
string sname;//姓名
int score;//考试分数
};
//老师结构体定义
struct teacher {
string tname;//老师姓名
struct student sarr[5];
};
//给三位老师赋值的函数
void allocateSpace(struct teacher teach[], int length) {
//给老师赋值
srand((unsigned int)time(NULL));//以系统时间为随机来设置
string nameSeed = "ABCDE";
for (int i = 0; i < length; i++) {
teach[i].tname = "teacher_";
teach[i].tname += nameSeed[i];
//给学生赋值
for (int j = 0; j < 5; j++) {
teach[i].sarr[j].sname = "student_";
teach[i].sarr[j].sname += nameSeed[j];
teach[i].sarr[j].score = rand() % 40 + 60;//0~39之间的随机数+60
}
}
}
//打印信息
void printinfo(struct teacher teach[], int length) {
for (int i = 0; i < length; i++) {
cout << teach[i].tname << "的五个学生是: " << endl;
for (int j = 0; j < 5; j++) {
cout << teach[i].sarr[j].sname << " ";
cout << "分数是: " << teach[i].sarr[j].score << endl;
}
}
}
int main() {
//创建3名老师的数组
struct teacher teach[3];
//通过函数给3名老师赋值并老师所带的学生赋值
int length = sizeof(teach) / sizeof(teach[0]);
allocateSpace(teach, length);
printinfo(teach,length);
system("pause");
return 0;
}
8.8.2 案例2

案例描述:

  • 设计一个英雄的结构体,包括成员姓名、年龄、性别;
  • 创建结构体数组,数组中存放5名英雄
  • 通过冒泡排序的算法,将数组中的英雄按年龄进行升序排序,最终打印排序后的结果
    五名英雄信息如下:

{“刘备”,23,“男”},
{“关羽”,22,“男”},
{“张飞”,20,“男”},
{“赵云”,21,“男”},
{“貂蝉”,19,“女”},

#include <iostream>
#include <string>
using namespace std;
//创建一个英雄的结构体
struct hero {
string name;//姓名
int age;//年龄
string sex;//性别
};
//冒泡排序函数
void bubblesort(struct hero SG[], int len) {
for (int i = 0; i < len; i++) {
//冒泡排序前的年龄
cout << SG[i].name << "的年龄是: " << SG[i].age << endl;
for (int j = 0; j < len - 1 - i; j++) {
if (SG[j].age > SG[j + 1].age) {
int temp = SG[j].age;
SG[j].age = SG[j + 1].age;
SG[j + 1].age = temp;
}
}
}
}
int main() {
//创建结构体数组,数组中存放5名英雄
struct hero SG[5] =
{
{ "刘备",23,"男" },
{ "关羽",22,"男" },
{ "张飞",20,"男" },
{ "赵云",21,"男" },
{ "貂蝉",19,"女" },
};
//调用冒泡排序函数,将数组中的英雄按年龄进行升序排序
int len = sizeof(SG) / sizeof(SG[0]);
bubblesort(&SG[0],len );
//打印排序后的结果
cout << "升序排序后的年龄是: " << endl;
for (int i = 0; i < len ; i++) {
cout << SG[i].age << " ";
}
cout << endl;
system("pause");
return 0;
}

9 综合练习

通讯录管理系统

c++基础入门_ios_13