c++(初始)

目录

1 c++初始

1.1 c++程序的四个步骤

1.1.1 创建项目

1.1.2 创建源文件

1.1.3 编写代码

1.1.4 运行项目

1.2 注释

1.3 变量

1.4 常量

1.5 关键字(标识符)

1.6 标识符命名规则

2 数据类型

2.1 整型

2.2 sizeof关键字

2.3 实型(浮点型)

2.4 字符型

2.5 转义字符

2.6 字符串型

2.7 布尔类型bool

2.8 数据的输入

3 运算符

3.1 算术运算符

3.2 赋值运算符

3.3 比较运算符

3.4 .逻辑运算符

4 程序流程结构

4.1 选择结构

4.1.1 if语句

4.1.2 三目运算符

4.1.3 switch语句

4.2 循环结构

4.2.1 while循环语句

4.2.2 do…while循环语句

4.2.3 for循环语句

4.2.4 嵌套循环

4.3 跳转语句

4.3.1 break语句

4.3.2 continue语句

4.3.3 goto语句

5 数组

5.1 概述

5.2 一维数组

5.2.1 一维数组定义方式

5.2.2 一维数组数组名

5.2.3 冒泡排序

5.3 二维数组

5.3.1 二维数组定义方式

5.3.2 二维数组组名

5.3.3 二维数组应用案例

6 函数

6.1 概述

6.2 函数的定义

6.3 函数的调用

6.4 值传递

6.5 函数的常见样式

6.6 函数的声明

6.7 函数的分文件编写

7 指针

7.1 指针的基本概念

7.2 指针变量的定义和使用

7.3 指针所占内存空间

7.4 空指针和野指针

7.5 const修饰指针

7.6 指针和数组

7.7 指针和函数

7.8 指针、数组、函数

8 结构体

8.1 结构体基本概念

8.2 结构体定义和使用

8.3 结构体数组

8.4 结构体指针

8.5 结构体嵌套结构体

8.6 结构体做函数参数

8.7 结构体中const使用场景

8.8 结构体案例


1 c++初始

1.1 c++程序的四个步骤

① 创建项目② 创建文件③ 编写代码④ 运行程序

1.1.1 创建项目

使用Visual Studio来编写程序创建新项目:选择Visual C++下的空项目,下方填写项目名称、项目路径,确定,项目创建完毕

1.1.2 创建源文件

右键点击源文件选择添加下的新建项,选择C++文件,下方给文件取一个名称,最后点击添加

1.1.3 编写代码
#include <iostream>
using namespace std;
int main()  // main是一个程序的入口,每个程序都必须有这么一个函数(有且仅有一个)
    {
        cout << "hello world" << endl;
        system("pause");
        return 0;
    }
1.1.4 运行项目

点击上方本地Windows调试器即可

1.2 注释

单行注释(//)和多行注释(/* */)

1.3 变量

作用:给一段指定的内存空间起名,方便操作这段内存

语法:数据类型 变量名 = 变量初始值

例:

#include <iostream>
using namespace std;
int main()  
    {
        int a  = 10;
        cout << "a = " << a << endl;  // 运行结果 a = 10
        system("pause");
        return 0;
    }

1.4 常量

作用:用于记录程序中不可更改的数据

C++定义常量的两种方式:

1、#define 宏常量:#define 常量名 常量值(通常在文件上方定义,表示一个常量)

2、const修饰的变量:const 数据类型 常量名 = 常量值(通常在变量定义前加关键字const,修饰该变量为常量,不可修改)

#include <iostream>
using namespace std;
// 1、#define 宏常量
    #define Day 7
    int main()
    {
        cout <<"一周总共有:" << Day << "天" << endl; // 运行结果:一周总共有:7天
          // 2、const修饰的变量
        const int month = 12;
        month = 24;    // 报错,常量是不可以修改的
        cout << "一年总共有:" << month << "个月" << endl; // 运行结果:一年总共有:12个月
        system("pause");
        return 0;
    }

1.5 关键字(标识符)

作用:是C++中预先保留的单词,在定义变量或者常量时,不要用关键字

#include <iostream>
using namespace std;
int main()  
    {
        // 创建变量:数据类型 变量名称 = 变量初始值
        int = 10
        // 不要用关键字给变量或常量取名称
        // int int = 10;  这是错误的,第二个int是关键字,不可以作为变量的名称
        system("pause");
        return 0;
    }

1.6 标识符命名规则

作用:① 标识符不能是关键字

           ② 标识符只能由字母、数字、下划线组成

           ③ 第一个字符必须为字母或下划线

 int abc = 10; // 对 
 int _abc = 20; // 对
 int _123abc = 30; // 对
 int 123abc = 40; // 错

          ④ 标识符中字母区分大小写

int aaa = 100;
cout << aaa << endl; // 对 
cout << AAA << endl; // 错
// 例:
int num1 = 10;
int num2 = 20;
int sum = num1 + num2;
cout << sum << endl;    // 30

2 数据类型

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

数据类型分为:整型、浮点型、字符型、字符串型、布尔型

2.1 整型

作用:整型变量表示的是整数类型的数据,C++中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同

数据类型占用空间取值
short(短整型)2字节(-2^15~2^15-1)
int(整型)4字节(-2^31~2^31-1)
long(长整型)windows为4字节,Linux为4字节(32位)8字节(64位)(取值与整型一样)
long long(长长整型)8字符(-2^63~2^63-1)

整型大小比较:short < int <= long <= long long

2.2 sizeof关键字

作用:利用sizeof关键字可以统计数据类型所占内存大小        

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

记不住数据类型的占用空间没关系,可以用sizeof关键字来统计

#include <iostream>
using namespace std;
int main()
{
    // 短整型
    short num1 = 10;
    cout << "short占用的内存空间为:" << sizeof(num1) << endl;    // 2

    // 整型
    int num2 = 10;
    cout << "int 占用的内存空间为:" << sizeof(num2) << endl;    // 4
    
    // 长整型
    long num3 = 10;
    cout << "long 占用的内存空间为:" << sizeof(num3) << endl;    // 4

    // 长长整型
    long long num4 = 10;
    cout << "long long 占用的内存空间为:" << sizeof(num4) << endl;    // 8

    return 0;
}

2.3 实型(浮点型)

作用:用于表示小数

浮点型变量分为两种:

        ① 单精度float

        ② 双精度double

两者区别在于表示的有效数字范围不同

数据类型 占用空间 有效数字范围

float 4字节 7位有效数字

double 8字节 15-16位有效数字

#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
    // 单精度
    float fl = 3.14f;
    cout << "fl = " << fl << endl;    // 3.14
​
    // 双精度
    double dl = 3.14;
    cout << "dl = " << dl << endl;    // 3.14
​
    // 用sizeof计算占用空间
    cout << "float占用的内存空间: " << sizeof(float) << endl;  // 4字节
​
    cout << "double占用的内存空间: " << sizeof(double) << endl;    // 8字节
​
    // 科学计算法
    float f2 = 3e2; // 3*10^2
    cout << "f2 = " << f2 << endl;  // 300
​
    float f3 = 3e-2;  // 3*0.1^2
    cout << "f3 = " << f3    << endl;   // 0.03
    return 0;
}

2.4 字符型

作用:字符型变量用于显示单个字符

语法:char ch = 'a';

注意1:在显示字符型变量时,用单引号将字符括起来,不要用双引号

char ch2 = "b"   // 错误

主意2:单引 号只能有一个字符,不可以是字符串

char ch2 = 'abcdef'  // 错误
  • C和C++中字符型变量只占用一个字符

  • 字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元

    常见的ASCII码:a->97 A->65 空格->32

#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
    char ch = 'a';
    cout << ch << endl;
    // 对应的ASCII编码
    cout << (int)ch << endl;    // 97
​
    cout << "char字符型变量所占内存:" << sizeof(char) << endl;   // 一个字节
    return 0;
}

2.5 转义字符

作用:用于表示一些不能显示出来的ASCII字符,现阶段常用的转移字符有:

  • 换行符:\n

cout << "hello world" << endl;
cout << "hello world\n";
  • 反斜杠:\\

cout << "\\" << endl;   // 输出一个\
  • 水平制表符:\t

作用:整齐输出数据 如下图:

cout << "aaa\thelloworld" << endl;
cout << "aa\thelloworld" << endl;
cout << "aaaaa\thelloworld" << endl;

2.6 字符串型

作用:用于表示一串字符

两种风格:① C风格字符串:char 变量名[] = "字符串值"

                  ② C++风格字符串:string 变量名 = "字符串值"

例:

#include <iostream>
#include <stdio.h>
#include <string>   // 用C++风格字符串时,要包含这个头文件
using namespace std;
int main()
{
    // C风格字符串
    char str[] = "hello world";
    cout << str << endl;
    // C++风格字符串  包含一个头文件 #include <string>
    string str2 = "hello world";
    cout << str2 << endl;
    return 0;
}

2.7 布尔类型bool

作用:布尔数据类型代表真或假的值

bool类型只有两个值:① true(本质是1)        ② false(本质是0)

bool类型占1个字节大小

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
    // 1、创建bool数据类型
    bool flag = true;   // true代表真
    cout << flag << endl;   // 运行结果:1
    flag = false;   // false代表假
    cout << flag << endl;   // 运行结果:0
    
    // 2、查看bool类型所占内存空间
    cout << "bool类型所占内存空间:" << sizeof(bool) << endl;    // 1
    return 0;
}

2.8 数据的输入

作用:用于键盘获取数据

关键字:cin

语法:cin >> 变量

例(整型):

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
   int a = 0;
   cout << "请给整型变量a赋值:" << endl;
   cin >> a;
   cout << "整型变量a=" << a << endl;
   return 0;
}

例(浮点型):

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
   float f = 3.14f;
   cout << "请给浮点型变量f赋值:" << endl;
   cin >> f;
   cout << "浮点型变量f=" << f << endl;
   return 0;
}

例(字符型):

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
    char ch = 'a';
    cout << "请给字符型变量ch赋值:" << endl;
    cin >> ch;
    cout << "字符型变量ch=" << ch << endl;
    return 0;
}

例(字符串型):

#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
int main()
{
    string str = "hello";
    cout << "请给字符串类型str赋值:" << endl;
    cin >> str;
    cout << "字符串类型str=" << str << endl;
    return 0;
}

例(布尔类型):只要是非0的值都代表真(1)

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
    bool flag = false;
    cout << "请给布尔类型flag赋值:" << endl;
    cin >> flag;
    cout << "布尔类型flag=" << flag << endl;
    return 0;
}

3 运算符

作用:用于执行代码的运算

运算符有:① 算术运算符:用于处理四则运算

                  ② 赋值运算符:用于将表达式的值赋值给变量

                  ③ 比较运算符:用于表达式的比较,并返回一个真值或假值

                  ④ 逻辑运算符:用于根据表达式的值返回真值或假值

3.1 算术运算符

算术运算符有以下几种符号:

例:

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
    // 加减乘除
    int a1 = 10;
    int b1 = 3;
    cout << a1+b1 << endl;  // 13
    cout << a1-b1 << endl;  // 7
    cout << a1*b1 << endl;  // 30
    cout << a1/b1 << endl;  // 3,两个整数相除,结果依然是整数,将小数部分去除
    
    int a2 = 10;
    int b2 = 20;
    cout << a2/b2 << endl;  // 0
​
    int a3 = 10;
    int b3 = 0;
    cout << a3/b3 << endl;  // 两个数相除,除数不可以为0,所以这是错误的
    
    // 两个小数也可以相除
    double d1 = 0.5;
    double d2 = 0.22;
    cout << d1/d2 << endl;  // 2.27273 运算的结果也可以是小数
    return 0;
}

取模:

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// ① 取模运算本质:求余数
	// ② 两个小数不能做取模运算
	// ③ 两个数相除不可以为0,所以做不了取模运算
    int a1 = 10;
    int b1 = 3;
    cout << a1%b1 << endl;  // 1

    int a2 = 10;
    int b2 = 20;
    cout << a2%b2 << endl;  // 10
    return 0;
}

递增递减:

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
    // 前置递增
    int a = 10;
    ++a;	// 让变量加1
    cout << "a=" << a << endl;  // 11

    // 后置递增
    int b = 10;
    ++b;	// 让变量加1
    cout << "b=" << b << endl;  // 11

    // 前置和后置的区别
    // 前置递增是先让变量+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
        
    // 前置递减
    int a4 = 10;
	int b4 = --a4 * 2;
    cout << "a4=" << a4 << endl;    // 9
    cout << "b4=" << b4 << endl;    // 18
	// 后置递减
    int a5 = 10;
    int b5 = a5-- * 2;
    cout << "a5=" << a5 << endl;    // 9
    cout << "b5=" << b5 << endl;    // 20
        
    return 0;
}

3.2 赋值运算符

作用:用于表达式的赋值给变量

赋值运算符有以下几种符号:

 例:

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
    // =
    int a = 10;
    a = 10;
    cout << "a=" << a << endl;  // 10
    // +=
    a = 10;
    a += 2; // a = a+2
    cout << "a=" << a << endl;  // 12
    // -=
    a = 10;
    a -= 2; // a = a-2
    cout << "a=" << a << endl;  // 8
    // *=
    a = 10;
    a *= 2; // a = a*2
    cout << "a=" << a << endl;  // 20
    // /=
    a = 10;
    a /= 2; // a = a/2
    cout << "a=" << a << endl;  // 5
    // %=
    a = 10;
    a %= 2; // a = a%2
    cout << "a=" << a << endl;  // 0

    return 0;
}

3.3 比较运算符

作用:用于表达式的比较,并返回一个真值或假值

比较运算符有一下几种符号:

 例:

#include <iostream>
#include <stdio.h>
//#include <string>
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.4 .逻辑运算符

作用:用于根据表达式的值返回真值或假值

逻辑运算符有以下几种符号:

例:

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// 逻辑非	总结:真变假,假变真
    int a = 10;
    // 在C++中除了0 其余都为真
    cout << !a << endl;     // 0
    cout << !!a << endl;    // 1
    // 逻辑与	总结:同真为真,其余为假(有0则0)
    int a2 = 10;
    int b2 = 10;
    cout << (a2 && b2) << endl; // 1

    a2 = 0;
    b2 = 10;
    cout << (a2 && b2) << endl; // 0

    a2 = 0;
    b2 = 0;
    cout << (a2 && b2) << endl; // 0
    // 逻辑或	总结:同假为假,其余为真
    int a3 = 10;
    int b3 = 10;
    cout << (a3 || b3) << endl; // 1

    a3 = 0;
    b3 = 10;
    cout << (a3 || b3) << endl; // 1

    a3 = 0;
    b3 = 0;
    cout << (a3 || b3) << endl; // 0
    return 0;
}

4 程序流程结构

C/C++支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构

        ① 顺序结构:程序按顺序执行,不发生跳转

        ② 选择结构:依据条件是否满足 ,有选择的执行相应功能

        ③ 循环结构:依据条件是否满足,循环多次执行某段代码

4.1 选择结构

4.1.1 if语句

作用:执行满足条件的语句

if语句的三种形式:

  • 单行格式if语句

  • 多行格式if语句

  • 多条件的if语句

1、单行格式if语句:if(条件){ 条件满足执行的语句 }

例:

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// 选择结构 单行if语句
	// 用户输入分数,如果分数大于600,视为考上一本大学,在屏幕上输出
	// 1、用户输入分数
	int score = 0;
	cout << "请输入一个分数:" << endl;
	cin >> score;
	// 2、打印用户输入的分数
	cout << "您输入的分数为:" << score << endl;
	// 3、判断分数是否大于600,如果大于那么输出,小于则不输出
	// 注意:if条件后面不要加分号
	if (score > 600) {
		cout << "恭喜您考上了一本大学" << endl;
	}
	return 0;
}

2、多行格式if语句:if(条件){ 条件满足执行的语句 } else { 条件不满足执行的语句 }

 例:

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// 选择结构 多行if语句
	// 输入考试分数,如果分数大于600,视为考上一本大学,在屏幕上输出,如果没考上一本大学,打印未考上一本大学
	// 1、输入考试分数
	int score = 0;
	cout << "请输入一个考试分数:" << endl;
	cin >> score;
	// 2、提示用户输入的分数
	cout << "您输入的分数为:" << score << endl;
	// 3、判断:如果大于600,打印考上一本,否则打印未考上一本
	if (score > 600)	// 大于600分执行if后大括号中的内容
	{
		cout << "恭喜考上一本大学" << endl;
	}
	else	// 小于600分执行else后大括号的内容
	{
		cout << "未考上一本大学" << endl;
	}
	return 0;
}

3、多条件的if语句:if(条件1) { 条件1满足执行的语句 } else if { 条件2 } { 条件2满足执行的语句 } …… else { 都不满足执行的语句 }

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// 选择结构 多条件if语句
	// 输入一个考试分数,如果大于600分,视为考上一本大学,在屏幕输出;如果大于500,视为考上二本大学,在屏幕输出;如果大于400分,视为考上三本大学,在屏幕输出,如果小于等于400分,视为没考上本科,在屏幕输出
	// 1、用户输入分数
	int score = 0;
	cout << "请输入考试分数:" << endl;
	cin >> score;
	// 2、提示用户输入的分数
	cout << "您输入的考试分数为:" << score << endl;
	// 3、判断:如果大于600,考上一本;如果大于500,考上二本;如果大于400,考上三本;如果前三个都没满足,则未考上本科
	if (score > 600)	// 第一个条件判断
	{
		cout << "恭喜您考上一本大学" << endl;
	}
	else if (score > 500)	// 第二个条件判断
	{
		cout << "恭喜您考上二本大学" << endl;
	}
	else if (score > 400)	// 第三个条件判断
	{
		cout << "恭喜您考上三本大学" << endl;
	}
	else	// 最后一个条件判断
	{
		cout << "未考上本科大学,请再接再厉" << endl;
	}
	return 0;
}

4、嵌套if语句:在if语句中,可以嵌套使用if语句,达到更精确的条件判断

例:① 提示用户输入一个高考考试分数,根据分数做如下判断

        ② 分数如果大于600分视为考上一本,大于500分视为考上二本,大于400分视为考上三本,其余视为未考上本科

        ③ 在一本分数中,如果大于700分,考上北大,大于650分,考上清华,大于600考入人大

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// 1、提示输入高考分数
	int score = 0;
	cout << "请输入高考分数:" << endl;
	cin >> score;
	// 2、显示高考分数
	cout << "您输入的分数是:" << score << endl;
	// 3、判断:
	if (score > 600)
	{
		cout << "恭喜您考入一本大学" << endl;
		if (score > 700)
		{
			cout << "您能考上北大" << endl;
		}
		else if (score > 650)
		{
			cout << "您能考上清华" << endl;
		}
		else
		{
			cout << "您能考上人大" << endl;
		}
	}
	else if (score > 500)
	{
		cout << "恭喜您考入二本大学" << endl;
	}
	else if (score > 400)
	{
		cout << "恭喜您考入三本大学" << endl;
	}
	else
	{
		cout << "未考上本科,请再接再厉哦" << endl;
	}
	return 0;
}

练习案例:

有三只小猪ABC,请分别输入三只小猪的体重,并且判断哪只小猪最重

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// 1、创建三只小猪的体重变量
	int num1 = 0;
	int num2 = 0;
	int num3 = 0;

	// 2、让用户输入三只小猪的重量
	cout << "请输入小猪A的体重" << endl;
	cin >> num1;
	cout << "请输入小猪B的体重" << endl;
	cin >> num2;
	cout << "请输入小猪C的体重" << endl;
	cin >> num3;
	cout << "小猪A的体重为:" << num1 << endl;
	cout << "小猪B的体重为:" << num2 << endl;
	cout << "小猪C的体重为:" << num3 << endl;

	// 3、判断哪种小猪重
	// 先判断A和B的重量
	if (num1 > num2)	// A比B重
	{
		if (num1 > num3)	// A比C重
		{
			cout << "小猪A最重" << endl;
		}
		else   // C比A重
		{
			cout << "小猪C最重" << endl;
		}
	}
	else   // B比A重
	{
		if (num2 > num3)
		{
			cout << "小猪B最重" << endl;
		}
		else   // C比B重
		{
			cout << "小猪C最重" << endl;
		}
	}
	return 0;
}
4.1.2 三目运算符

作用:通过三目运算符实现简单的判断

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

解释:如果表达式1的值为真,执行表达式2,并返回表达式2的结果;

如果表达式1的值为假,执行表达式3,并返回表达式3的结果

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// 创建三个变量abc
	// 将a和b作比较,将变量大的值赋值给变量c
	int a = 10;
	int b = 20;
	int c = 30;
	c = (a > b ? a : b);
	cout << "c=" << c << endl;	// 20

	// 在C++中三目运算符返回的是变量,可以继续赋值
	(a > b ? a : b) = 100;
	cout << "a=" << a << endl;	// 10
	cout << "b=" << b << endl;	// 100
	return 0;
}
4.1.3 switch语句

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

语法如下:

 例:

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// 给电影打分
	// 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;
	}

	return 0;

注意:

① switch语句中表达式类型只能是整型或字符型

② case里面如果没有break,那么程序会一直向下执行

③ 与if语句比,对于多条件判断时,switch的结构清晰,执行效率高,缺点是switch不可以判断区间

4.2 循环结构

4.2.1 while循环语句

作用:满足循环条件,执行循环语句

语法:while(循环条件){ 循环语句 }

解释:只要循环条件的结果为真,就执行循环语句

#include <iostream>
#include <stdio.h>
//#include <string>
using namespace std;
int main()
{
	// while循环
	// 在屏幕中打印0-9这十个数字
	int num = 0;
	// while()中填入循环条件
	// 注意:在写循环时一定要避免死循环的出现
	while (num < 10)
	{
		cout << "num=" << num << endl;
		num++;
	}

	return 0;
}

while循环练习:

系统随机生成一个1到100之间的数字,玩家进行猜测,如果猜错,提示玩家过大或过小,如果猜对,恭喜玩家胜利,并且退出游戏

#include <iostream>
#include <stdio.h>
// time系统时间头文件包含
#include <ctime>

//#include <string>
using namespace std;
int main()
{
	// 添加随机数种子,作用是利用当前系统时间生成随机数,防止每次随机数都一样
	srand((unsigned int)time(NULL));
	// 1、系统生成随机数
	int num =  rand() % 100 + 1;	// rand() % 100是生成0-99的随机数
	// 2、玩家进行猜测
	int val = 0;	// 玩家输入的数据
	
	while (1)
	{
		cin >> val;
		// 3、判断玩家的猜测
		// 猜错:提示猜的结果 过大或过小,重新返回第二步
		if (val > num)
		{
			cout << "猜测过大" << endl;
		}
		else if(val < num)
		{
			cout << "猜测过小" << endl;
		}
		else
		{
			cout << "恭喜您猜对了" << endl;
			// 猜对:退出游戏
			break;	// 可以利用该关键字来退出当前循环
		}
	}
	
	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 << endl;
		num++;
	} while (num < 10);
}
return 0;

练习案例:水仙花数

水仙花数是指一个3位数,它的每个位上的3次幂之和等于它本身

例如:1^3+5^3+3^3=153

请利用do…while语句求出所有3位数中的水仙花数

分析:

#include <iostream>
using namespace std;

int main()
{
	// 1、先打印所有的3位数
	int num = 100;
	do {
		// 2、从所有3位数中找到水仙花数
		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);
	return 0;
}
4.2.3 for循环语句

作用:满足循环条件,执行循环语句

语法:for(起始表达式;条件表达式;末尾表达式) { 循环语句 }

#include <iostream>
using namespace std;

int main()
{
	// 从数字0打印到数字9
	for (int i = 0; i < 10; i++) {

		cout << i << endl;
	}
	return 0;
}

注意:for循环中的表达式要用分号进行分隔

总结:while,do…while,for都是开发中常用的循环语句,for循环结构比较清晰,比较常用

练习案例:敲桌子

从1开始数到数字100,如果数字个位含有7,或者数字十位含有7,或者该数字是7的倍数,我们打印敲桌子,其余数字直接打印输出

分析:

#include <iostream>
using namespace std;

int main()
{
	// 1、先输入1-100的数字
	for (int i = 1; i <= 100; i++) 
	{
		// 2、从100个数字中找到特殊数字,打印“敲桌子”
		// 如果是7的倍数、个位有7或者十位有7,打印敲桌子
		if (i % 7 == 0 || i % 10 == 7 || i / 10 == 7)
		{		// 如果是特殊数字,打印敲桌子
			cout << "敲桌子" << endl;
		}
		else   // 如果不是特殊数字,才打印数字
		{	
			cout << i << endl;
		}
	}

	return 0;
}
4.2.4 嵌套循环

作用:在循环中再嵌套一层循环,解决一些实际问题

例如我们想在屏幕中打印如下图片,就需要利用嵌套循环

#include <iostream>
using namespace std;

int main()
{
	// 打印一行星图
	// 外层循环
    // 外层循环执行一次,内层循环执行一轮
	for (int i = 0; i < 10; i++)
	{
		// 内层循环
		for (int j = 0; j < 10; j++)
		{
			cout << "* ";
		}
		cout << endl;
	}

	return 0;
}

练习案例:

利用嵌套循环,实现九九乘法表(列数*行数=计算结果)

#include <iostream>
using namespace std;

int main()
{
	// 打印行数    i表示行数,j表示列数
	for (int i = 1; i <= 9; i++)
	{
        // j <= i:列数<=行数
		for (int j = 1; j <= i; j++)
		{
			cout << j << "*" << i << "=" << j * i << "\t";
		}
		cout << endl;
	}

	return 0;
}

4.3 跳转语句

4.3.1 break语句

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

break使用的时机:

  • 出现在switch条件语句中,作用是终止case并跳出switch

  • 出现在循环语句中,作用是跳出当前的循环语句

  • 出现在嵌套语句中,跳出最近的内层循环语句

① 出现在switch条件语句中:

#include <iostream>
using namespace std;

int main()
{
	cout << "请选择副本难度" << endl;
	cout << "1、普通" << endl;
	cout << "2、中等" << endl;
	cout << "3、困难" << endl;
	int select = 0;	// 创建选择结果的变量
	cin >> select;	// 等待用户输入
	switch (select)
	{
	case 1:
		cout << "您选择的是普通难度" << endl;
		break;
	case 2:
		cout << "您选择的是中等难度" << endl;
		break;
	case 3:
		cout << "您选择的是困难难度" << endl;
		break;
	default:
		break;
	}

	return 0;
}

② 出现在循环语句中

#include <iostream>
using namespace std;

int main()
{
	// 出现在循环语句中
	for (int i = 0; i < 10; i++)
	{
		if (i == 5)
		{
			break;	// 退出循环
		}
		cout << i << endl;
	}

	return 0;
}

③ 出现在嵌套语句中

#include <iostream>
using namespace std;

int main()
{
	// 出现在嵌套语句中
	for (int i = 0; i < 10; i++)
	{
		// 内层循环
		for (int j = 0; j < 10; j++)
		{
			if (j == 5)
			{
				break;	// 退出内层循环
			}
			cout << "* ";
		}
		cout << endl;
	}

	return 0;
}
4.3.2 continue语句

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

#include <iostream>
using namespace std;

int main()
{
	// continue语句
	for (int i = 0; i <= 100; i++)
	{
		// 如果是奇数输出,偶数不输出
		if (i % 2 == 0)
		{
			continue;	// 可以筛选条件,执行到此就不再向下执行,执行下一次循环
			// break会退出循环,而continue不会退出循环
		}
		cout << i << endl;
	}

	return 0;
}
4.3.3 goto语句

作用:可以无条件跳出语句

语法:goto 标记;

解释:如果标记的名称存在,执行到goto语句时,会跳转到标记的位置

#include <iostream>
using namespace std;

int main()
{
	// go to语句
	cout << "1、xxx" << endl;
	cout << "2、xxx" << endl;
	cout << "3、xxx" << endl;
	goto FLAG;
	cout << "4、xxx" << endl;
	cout << "5、xxx" << endl;
	FLAG:
	cout << "6、xxx" << endl;

	return 0;
}

运行结果:

注意:在程序中尽量不要使用goto语句,以免造成流程混乱

5 数组

5.1 概述

所谓数组就是一个集合,里面存放了相同类型的数据元素

        特点1:数组中的每个数据元素都是相同的数据类型

        特点2:数组是由连续的内存位置组成的

5.2 一维数组

5.2.1 一维数组定义方式

一维数组有三种定义方式:

        ① 数据类型 数组名[ 数组长度 ]

#include <iostream>
using namespace std;

int main()
{
	int arr[5];
	// 给数组中的元素赋值
	// 数组元素的下标是从0开始索引的
	arr[0] = 10;
	arr[1] = 20;
	arr[2] = 30;
	arr[3] = 40;
	arr[4] = 50;
	// 访问数组元素
	cout << arr[0] << endl;
	cout << arr[1] << endl;
	cout << arr[2] << endl;
	cout << arr[3] << endl;
	cout << arr[4] << endl;

	return 0;
}

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

#include <iostream>
using namespace std;

int main()
{
	// 如果在初始化数据时没有全部填写完,会用0来填补剩余数据
	int arr[5] = { 10,20,30,40,50 };
	// cout << arr[0] << endl;
	// cout << arr[1] << endl;
	// cout << arr[2] << endl;
	// cout << arr[3] << endl;
	// cout << arr[4] << endl;
	// 利用循环输出数组中的元素
	for (int i = 0; i < 5; i++)
	{
		cout << arr[i] << endl;
	}

	return 0;
}

        ③ 数据类型 数组名[ ] = { 值1,值2…… }

#include <iostream>
using namespace std;

int main()
{
	// 定义数组时,必须有初始长度
	int arr[] = { 10,20,30,40,50 };
	for (int i = 0; i < 5; i++)
	{
		cout << arr[i] << endl;
	}

	return 0;
}
5.2.2 一维数组数组名

用途:可以统计整个数组在内存中的长度和首地址

#include <iostream>
using namespace std;

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	cout << "整个数组占用的内存空间为:" << sizeof(arr) << endl;	// 40
	cout << "每个元素占用的内存空间为:" << sizeof(arr[4] ) << endl;	// 4
	cout << "数组中元素的个数为:" << sizeof(arr) / sizeof(arr[0]) << endl;	//	10

	cout << "数组的首地址为:" << (int)arr << endl;
	cout << "数组中第一个元素地址为:" << (int)&arr[0] << endl;
	cout << "数组中第二个元素地址为:" << (int)&arr[1] << endl;

	return 0;
}

练习案例1:五只小猪称体重

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

#include <iostream>
using namespace std;

int main()
{
	// 1、创建五只小猪体重的数组
	int arr[5] = { 300,350,200,400,250 };
	// 2、从数组中找到最大值
	int max = 0;
	for (int i = 0; i < 5; i++)
	{
		// cout << arr[i] << endl;
		// 如果访问的数组中的元素比我认定的最大值还要大,更新最大值
		if (arr[i] > max)
		{
			max = arr[i];
		}
	}
	// 3、打印最大值
	cout << "最重的小猪体重为:" << max << endl;

	return 0;
}

练习案例2:数组元素逆置

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

#include <iostream>
using namespace std;

int main()
{
	// 实现数组元素逆置
	// 1、创建数组
	int arr[5] = { 1,3,2,5,4 };
	cout << "数组逆置前:" << endl;
	for (int i = 0; i < 5; i++)
	{
		cout << arr[i] << endl;
	}
	// 2、实现逆置
	// ① 记录起始下标位置
	// ② 记录结束下标位置
	// ③ 起始下标与结束下标的元素互换
	// ④ 起始位置++,结束位置--
	// ⑤ 循环执行①操作,直到起始位置>=结束位置
	int start = 0;	// 起始下标 
	int end = sizeof(arr) / sizeof(arr[0]) - 1;

	while (start < end)
	{
		// 实现元素互换
		int temp = arr[start];
		arr[start] = arr[end];
		arr[end] = temp;

		// 下标更新
		start++;
		end--;
	}

	// 3、打印逆置后的数组
	cout << "数组元素逆置后:" << endl;
	for (int i = 0; i < 5; i++)
	{
		cout << arr[i] << endl;
	}
	return 0;
}
5.2.3 冒泡排序

作用:最常见的排序算法,对数组内元素进行排序

1、比较相邻的元素,如果第一个比第二个大,就交换他们两个

2、对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值

3、重复以上的步骤,每次比较次数-1,直到不需要比较

#include <iostream>
using namespace std;

int main()
{
	// 利用冒泡排序实现升序序列
	int arr[10] = { 4,2,8,0,6,5,7,1,3,9 };
	cout << "排序前:" << endl;
	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;

	// 开始冒泡排序
	// 总共排序轮数为:元素个数-1
	for (int i = 0; i < 10 - 1; i++)
	{
		// 内层循环对比,次数=元素个数-当前轮数-1
		for (int j = 0; j < 10 - i - 1; j++)
		{
			// 如果第一个数字,比第二个数字大,交换两个数字
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}

	// 排序后结果
	cout << "排序后:" << endl;
	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;

	return 0;
}

5.3 二维数组

二维数组就是在一堆数组上,多加一个维度

5.3.1 二维数组定义方式

二维数组有以下四种方式:

① 数据类型 数组名[ 行数 ][ 列数 ];

#include <iostream>
using namespace std;

int main()
{
	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;

	// cout << arr[0][0] << endl;
	// cout << arr[0][1] << endl;
	// cout << arr[0][2] << endl;
	// cout << arr[1][0] << endl;
	// cout << arr[1][1] << endl;
	// cout << arr[1][2] << endl;

	// 外层循环打印行数,内层循环打印列数
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cout << arr[i][j] << endl;
		}
	}

	return 0;
}

        ② 数据类型 数组名[ 行数 ][ 列数 ] = { { 数据1,数据2 },{ 数据3,数据4 } };

#include <iostream>
using namespace std;

int main()
{
	int arr[2][3] =
	{
		{1,2,3},
		{4,5,6}
	};
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cout << arr[i][j] << " ";
		}
		cout << endl;
	}

	return 0;
}

        ③ 数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4 };

#include <iostream>
using namespace std;

int main()
{
	int arr[2][3] = { 1,2,3,4,5,6 };
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cout << arr[i][j] << " ";
		}
		cout << endl;
	}

	return 0;
}

        ④ 数据类型 数组名[  ][ 列数 ]= { 数据1,数据2,数据3,数据4 };

#include <iostream>
using namespace std;

int main()
{
	int arr[][3] = { 1,2,3,4,5,6 };
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cout << arr[i][j] << " ";
		}
		cout << endl;
	}

	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;    // 24
	cout << "二维数组第一行占用内存为:" << sizeof(arr[0]) << endl;    // 12
	cout << "二维数组第一个元素占用内存为:" << sizeof(arr[0][0]) << endl;    // 4

	cout << "二维数组行数为:" << sizeof(arr) / sizeof(arr[0]) << endl;    // 2
	cout << "二维数组列数为:" << sizeof(arr[0]) / sizeof(arr[0][0]) << endl;    // 3

	// 获取二维数组首地址
	cout << "二维数组首地址为:" << (int)arr << endl;
	cout << "二维数组第一行首地址为:" << (int)arr[0] << endl;
	cout << "二维数组第二行首地址为:" << (int)arr[1] << endl;
	// 访问具体元素的地址要加&才可以
	cout << "二维数组第一个元素首地址为:" << (int)&arr[0][0] << endl;
	cout << "二维数组第二个元素首地址为:" << (int)&arr[0][1] << endl;

	return 0;
}
5.3.3 二维数组应用案例

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

语文数学英语
张三100100100
李四9050100
王五607080
#include <iostream>
using namespace std;
#include <string>

int main()
{
	// 1、创建二维数组
	int score[3][3] =
	{
		{100,100,100},
		{90,50,100},
		{60,70,80}
	};
	string name[3] = { "张三","李四","王五" };
	// 2、统计每个人的总和分数
	for (int i = 0; i < 3; i++)
	{
		int sum = 0;	// 统计分数总和变量
		for (int j = 0; j < 3; j++)
		{
			sum += score[i][j];
			// cout << score[i][j] << "\t";
		}
		cout << name[i] << "的总分为:" << sum << endl;
	}

	return 0;
}

6 函数

6.1 概述

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

6.2 函数的定义

函数的定义一般分为5个步骤

        ① 返回值类型:一个函数可以返回一个值,在函数定义中

        ② 函数名:给函数取个名称

        ③ 参数表列:使用该函数时,传入的数据

        ④ 函数体语句:花括号内的代码,函数内需要执行的语句

        ⑤ return表达式:和返回值类型挂钩,函数执行完后,返回相应的数据

语法:

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

函数体语句

return表达式

}

#include <iostream>
using namespace std;
// #include <string>

// 返回值类型 函数名 (参数列表){ 函数体语句 return表达式 }
// 加法函数,实现两个整型相加,并且将相加的结果进行返回
int add(int num1, int num2)
{
	int sum = num1 + num2;
	return sum;
}

int main()
{
	return 0;
}

6.3 函数的调用

功能:使用定义好的函数

语法:函数名 (参数)

#include <iostream>
using namespace std;
// #include <string>

// 定义加法函数
// 函数定义的时候,num1和num2并不是真的数据,它只是一个形式上的参数,简称形参
int add(int num1, int num2)
{
	int sum = num1 + num2;
	return sum;
}

int main()
{
	// 函数中调用add函数
	int a = 10;
	int b = 20;
	// 函数调用语法:函数名称(参数)
	// a和b称为实际参数,简称实参,当调用函数时,实参会传递给形参
	int c = add(a, b);
	cout << "c=" << c << endl;
	return 0;
}

总结:函数定义里小括号内称为形参,函数调用时传入的参数称为实参

6.4 值传递

  • 值传递就是函数调用时实参将数值传入给形参

  • 值传递时,如果形参发生,并不会影响实参

#include <iostream>
using namespace std;
// #include <string>

// 值传递
// 定义函数,实现两个数字进行交换函数
// 如果函数不需要返回值,声明时可以写void
void swap(int num1, int num2)
{
	cout << "交换前:" << endl;
	cout << "num1=" << num1 << endl;
	cout << "num2=" << num2 << endl;

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

	cout << "交换后:" << endl;
	cout << "num1=" << num1 << endl;
	cout << "num2=" << num2 << endl;
	// return;	返回值不需要时可以不写return
}
int main()
{
	int a = 10;
	int b = 20;
	// 当我们做值传递时,函数的形参发生改变,并不会影响实参
	swap(a, b);
	return 0;
}

6.5 函数的常见样式

函数的常见样式有四种:

        ① 无参无返

        ② 有参无返

        ③ 无参有返

        ④ 有参有返

#include <iostream>
using namespace std;
// #include <string>

// 函数的常见样式:
// ① 无参无返
void test01()
{
	cout << "this is test01" << endl;    // this is test01
}
// ② 有参无返
void test02(int a)
{
	cout << "this is test02 a=" << a << endl;    // this is test02 a=100
}
// ③ 无参有返
int test03()
{
	cout << "this is test03" << endl;    // this is test03
	return 99;
}
// ④ 有参有返
int test04(int a)
{
	cout << "this is test04 a=" << a << endl;    // this is test04 a=1000
	return a;
}

int main()
{
	// 无参无返的函数调用
	test01();
	// 有参无返的函数调用
	test02(100);
	// 无参有返的函数调用
	int num1 = test03();
	cout << "num1=" << num1 << endl;    // num1=99
	// 有参有返的函数调用
	int num2 = test04(1000);
	cout << "num2=" << num2 << endl;    // num2=1000

	return 0;
}

6.6 函数的声明

作用:告诉编译器函数名称及如何调用函数,函数的实际主体可以单独定义

  • 函数的声明可以多次,但是函数的定义只能有一次

#include <iostream>
using namespace std;
// #include <string>

// 函数的声明
// 比较函数,实现两个整型数字进行比较,返回较大的值
// 提前告诉编译器函数的存在,可以利用函数的声明
// 函数的声明 声明可以写多次,定义只能有一次
int max(int a, int b);

// 定义
int max(int a, int b)
{
	return a > b ? a : b;
}

int main()
{
	int a = 10;
	int b = 20;
	cout << max(a, b) << endl;    // 20
	return 0;
}

6.7 函数的分文件编写

作用:让代码结构更加清晰

函数分文件编写一般有四个步骤:

        ① 创建后缀名为.h的头文件

        ② 创建后缀名为.cpp的源文件

        ③ 在头文件中写函数的声明

        ④ 在源文件中写函数的定义

 主源文件里面代码:

#include <iostream>
using namespace std;
#include "swap.h";

int main()
{
	int a = 10;
	int b = 20;
	swap(a, b);
	return 0;
}

合并一个文件如下:

#include <iostream>
using namespace std;

// 函数的声明
void swap(int a, int b);

// 函数的定义
void swap(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
	cout << "a = " << a << endl;    // a = 20
	cout << "b = " << b << endl;    // b = 10
}

int main()
{
	int a = 10;
	int b = 20;
	swap(a, b);

	return 0;
}

7 指针

7.1 指针的基本概念

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

  • 内存编号是从0开始记录的,一般用十六进制数字表示

  • 可以利用指针变量保存地址

7.2 指针变量的定义和使用

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

#include <iostream>
using namespace std;

int main()
{
	// 1、定义指针
	int a = 10;
	// 指针定义的语法:数据类型 * 指针变量名
	int* p;
	// 让指针记录变量a的地址
	p = &a;	// &是取址符号
	cout << "a的地址为:" << &a << endl;

	// 2、使用指针
	// 可以通过解引用的方式来找到指针指向的内存
	// 指针前加*代表解引用,找到指针指向的内存中的数据
	*p = 100;
	cout << "a=" << a << endl;
	cout << "*p=" << *p << endl;

	return 0;
}

7.3 指针所占内存空间

#include <iostream>
using namespace std;

int main()
{
	// 指针所占空间
	int a = 10;
	int* p = &a;
	// 在64位操作系统下,指针是占8个字节空间大小,不管什么数据类型都是
	cout << "sizeof(int *)=" << sizeof(int *) << endl;
	cout << "sizeof(int *)=" << sizeof(float *) << endl;
	cout << "sizeof(int *)=" << sizeof(double *) << endl;
	cout << "sizeof(int *)=" << sizeof(char *) << endl;

	return 0;
}

7.4 空指针和野指针

空指针:指针变量指向内存中编号为0的空间

用途:初始化指针变量

注意:空指针指向的内存是不可以访问的

 野指针:指针变量指向非法的内存空间

 总结:空指针和野指针都不是我们申请的空间,因此不要访问

7.5 const修饰指针

const修饰指针有三种情况

        ① const修饰指针——常量指针

        ② const修饰常量——指针常量

        ③ const既修饰指针,又修饰常量

#include <iostream>
using namespace std;

int main()
{
	// 1、const修饰指针——常量指针
	int a = 10;
	int b = 10;
	const int* p = &a;
	// 指针指向的值不可以改,指针的指向可以改
	// *p = 20;	//错误的
	p = &b;	// 正确的

	// 2、const修饰常量——指针常量
	// 指针的指向不可以改变,指针指向的值可以改变
	int* const p2 = &a;
	*p2 = 100;	// 正确的
	// p2 = &b;	//错误
	// 3、const修饰指针和常量
	const int* const p3 = &a;
	// 指针的指向和指针指向的值都不可以改
	// *p3 = 100;	// 错误
	// p3 = &b;	// 错误

	return 0;
}

技巧:看const右侧紧跟着的是指针还是常量,是指针就是常量指针,是常量就是指针常量

7.6 指针和数组

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

#include <iostream>
using namespace std;

int main()
{
	// 利用指针访问数组中的元素
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	cout << "第一个元素为:" << arr[0] << endl;

	int * p = arr;	// arr就是数组首地址
	cout << "利用指针访问第一个元素:" << *p << endl;
	p++;	// 让指针向后偏移四个字节
	cout << "利用指针访问第二个元素:" << *p << endl;

	cout << "利用指针遍历数组" << endl;
	int * p2 = arr;
	for (int i = 0; i < 10; i++)
	{
		cout << *p2 << endl;
		p2++;
	}

	return 0;
}

7.7 指针和函数

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

#include <iostream>
using namespace std;

// 实现两个数字进行交换
void swap01(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
	cout << "swap01 a=" << a << endl;
	cout << "swap01 b=" << b << endl;
}

void swap02(int *p1, int *p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;

}

int main()
{
	// 指针和函数
	// 1、值传递
	int a = 10;
	int b = 20;
	// swap01(a, b);
	// 2、地址传递
	// 如果是地址传递可以修饰实参
	swap02(&a, &b);

	cout << "a=" << a << endl;
	cout << "b=" << b << endl;

	return 0;
}

总结:如果不想修改实参,就用值传递,如果想修改实参,就用地址传递

7.8 指针、数组、函数

案例:封装一个函数,利用冒泡排序,实现对整型数组的升序排序

例如数组:int arr[10] = { 4,6,2,1,7,8,9,3,5,0 };

#include <iostream>
using namespace std;

// 冒泡排序函数 参数1:数组的首地址	参数2:数组长度
void bubbleSort(int * arr, int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			// 如果j > j + 1的值,交换数字
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}

// 打印数组
void printArray(int * arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << endl;
	}
}

int main()
{
	// 1、先创建数组
	int arr[10] = { 4,6,2,1,7,8,9,3,5,0 };
	// 数组长度
	int len = sizeof(arr) / sizeof(arr[0]);
	// 2、创建函数,实现冒泡排序
	bubbleSort(arr, len);
	// 3、打印排序后的数组
	printArray(arr, len);

	return 0;
}

8 结构体

8.1 结构体基本概念

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

8.2 结构体定义和使用

语法:struct 结构体名{ 结构体成员列表 };

通过结构体创建变量的方式有三种:

        ① struct 结构体名 变量名

        ② struct 结构体名 变量名 = { 成员1值,成员2值…… }

        ③ 定义结构体时顺便创建变量

#include <iostream>
using namespace std;
#include <string>

// 1、创建学生数据类型 : 学生包括(姓名、年龄、分数)
// 自定义数据类型,一些数据集合组成的一个类型
// 语法:struct 类型名称 { 成员列表 }
struct Student
{
	// 成员列表
	// 姓名
	string name;
	// 年龄
	int age;
	// 分数
	int score;
}s3;	// 顺便创建结构体变量

// 2、通过学生类型创建具体学生
int main()
{
	// 第一种
	struct Student s1;	// 这里struct关键字可以省略
	// 给s1属性赋值,通过.访问结构体变量中的属性
	s1.name = "张三";
	s1.age = 18;
	s1.score = 100;
	cout << "姓名:" << s1.name << "年龄:" << s1.age << "分数:" << s1.score << endl;

	// 第二种
	struct Student s2 = { "李四",18,90 };
	cout << "姓名:" << s2.name << "年龄:" << s2.age << "分数:" << s2.score << endl;

	// 第三种
	s3.name = "王五";
	s3.age = 20;
	s3.score = 88;
	cout << "姓名:" << s3.name << "年龄:" << s3.age << "分数:" << s3.score << endl;

	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 stuArray[3] =
	{
		{ "张三",18,80 },
		{ "李四",20,90 },
		{ "王五",21,66}
	};
// 3、给结构体数组中的元素赋值
	stuArray[2].name = "赵六";
	stuArray[2].age = 19;
	stuArray[2].score = 100;
// 4、遍历结构体数组
	for (int i = 0; i < 3; i++)
	{
		cout << "姓名:" << stuArray[i].name << "年龄:" << stuArray[i].age << "分数:" << stuArray[i].score << endl;
	}
	return 0;
}

8.4 结构体指针

作用:通过指针访问结构体中的成员

  • 利用操作符->可以通过结构体指针访问结构体属性

#include <iostream>
using namespace std;
#include <string>

// 结构体数组
// 1、定义结构体
struct student
{
	// 姓名
	string name;
	// 年龄
	int age;
	// 分数
	int score;
};

int main()
{
	// 1、创建学生结构体变量
	student s = { "张三",18,100 };
	// 2、通过指针指向结构体变量
	student * p = &s;
	// 3、通过指针访问结构体变量中的数据
	// 通过结构体指针,访问结构体中的属性,需要利用'->'
	cout << "姓名:" << p->name << "年龄:" << p->age << "分数:" << p->score << endl;

	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()
{
	// 结构体嵌套结构体
	// 创建老师
	teacher t;
	t.id = 10011;
	t.name = "老王";
	t.age = 38;
	t.stu.name = "小明";
	t.stu.age = 18;
	t.stu.score = 80;
	cout << "老师姓名:" << t.name << "老师编号:" << t.id << "老师年龄:" << t.age << "老师辅导的学生姓名:" << t.stu.name << "老师辅导学生的年龄:" << t.stu.age << "老师辅导学生的成绩:" << t.stu.score << endl;

	return 0;
}

8.6 结构体做函数参数

作用:将结构体作为参数向函数中传递

传递方式有两种:

  • 值传递

  • 地址传递

#include <iostream>
using namespace std;
#include <string>

// 定义学生结构体
struct student
{
	string name;
	int age;
	int score;
};

// 打印学生信息函数
// 1、值传递
void printStudent1(struct student s)
{
	cout << "在子函数中 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;
}

// 地址传递
void printStudent2(struct student * p)
{
	// p->age = 50;
	cout << "子函数中 姓名:" << p->name << "年龄:" << p->age << "分数:" << p->score << endl;
}

int main()
{
	// 结构体做函数参数
	// 将学生传入到一个参数中,打印学生身上的所有信息
	// 创建结构体变量
	struct student s;
	s.name = "小徐";
	s.age = 18;
	s.score = 100;
	// printStudent1(s);
	printStudent2(&s);
	// cout << "main函数中打印 姓名:" << s.name << "年龄:" << s.age << "分数:" << s.score << endl;

	return 0;
}

总结:如果不想修改主函数中的数据,用值传递,反之用地址传递

8.7 结构体中const使用场景

作用:用const来防止误操作

#include <iostream>
using namespace std;
#include <string>

// const的使用场景
struct student
{
	string name;
	int age;
	int score;
};

// 将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
void printStudents(const student * s)
{
	// s->age = 60;	// 加入const之后,一但有修改的操作就会报错,可以防止我门的误操作
	cout << "姓名:" << s->name << "年龄:" << s->age << "分数:" << s->score << endl;
}

int main()
{
	// 创建结构体变量
	struct student s = { "张三",18,90 };
	// 通过函数打印结构体变量信息
	printStudents(&s);

	return 0;
}

8.8 结构体案例

案例1:学校正在做毕设,每名老师带领5个学生,总共有3名老师,需求如下:

设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组,作为成员学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值,最终打印出老师数据以及老师所带的学生数据

#include <iostream>
using namespace std;
#include <string>

// 学生的结构体
struct Student
{
	string sName;
	int score;
};

// 老师的结构体定义
struct Teacher
{
	string tName;
	// 学生数组
	struct Student sArray[5];
};

// 给老师和学生赋值的函数
void setValue(struct Teacher tArray[], int len)
{
	string nameSeed = "ABCDE";
	// 给老师开始赋值
	for (int i = 0; i < len; i++)
	{
		tArray[i].tName = "Teacher_";
		tArray[i].tName += nameSeed[i];
		// 通过循环给每名老师所带的学生赋值
		for (int j = 0; j < 5; j++)
		{
			tArray[i].sArray[j].sName = "Student_";
			tArray[i].sArray[j].sName += nameSeed[j];
			int random = rand() % 61 + 40;	// 40-100
			tArray[i].sArray[j].score = random;
		}
	}
};

// 打印所有信息
void printInfo(struct Teacher tArray[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << "老师姓名:" << tArray[i].tName << endl;
		for (int j = 0; j < 5; j++)
		{
			cout << "\t学生姓名:" << tArray[i].sArray[j].sName << " 考试分数:" << tArray[i].sArray[j].score << endl;
		}
	}
}

int main()
{
	// 随机数种子
	srand((unsigned int)time(NULL));
	// 1、创建3名老师的数组
	struct Teacher tArray[3];
	// 2、通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
	int len = sizeof(tArray) / sizeof(tArray[0]);
	setValue(tArray, len);
	// 3、打印所有老师及所带学生信息
	printInfo(tArray, len);

	return 0;
}

运行结果:

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

#include <iostream>
using namespace std;
#include <string>

// 1、设计英雄结构体
// 英雄的结构体
struct Hero
{
	string name;
	int age;
	string sex;
};
// 冒泡排序
void bubbleSort(struct Hero heroArray[], int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			// 如果j下标的元素年龄大于j+1下标的元素年龄,交换两个元素
			if (heroArray[j].age > heroArray[j + 1].age)
			{
				struct Hero temp = heroArray[j];
				heroArray[j] = heroArray[j + 1];
				heroArray[j + 1] = temp;
			}
		}
	}
}

// 打印排序后数组中的信息
void printHero(struct Hero heroArray[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << "姓名:" << heroArray[i].name << "年龄:" << heroArray[i].age << "性别:" << heroArray[i].sex << endl;
	}
}

int main()
{
	// 2、创建数组存放5名英雄
	struct Hero heroArray[5] = 
	{
		{"刘备",38,"男"},
		{"张飞",30,"男"},
		{"关羽",33,"男"},
		{"赵云",28,"男"},
		{"貂蝉",20,"女"},
	};

	int len = sizeof(heroArray) / sizeof(heroArray[0]);
	cout << "排序前打印:" << endl;
	for (int i = 0; i < len; i++)
	{
		cout << "姓名:" << heroArray[i].name << "年龄:" << heroArray[i].age << "性别:" << heroArray[i].sex << endl;
	}
	// 3、对数组进行排序,按照年龄进行升序排序
	bubbleSort(heroArray, len);

	cout << "排序后打印:" << endl;
	// 4、将排序后结果打印输出
	printHero(heroArray, len);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值