编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 01.基础语法
  • 02.运算符和表达式
  • 03.判断和循环
  • 04.函数实践
  • 05.指针和引用
  • 06.数组和容器
  • 07.类和对象
  • 08.继承和派生
  • 09.多态与虚函数
  • 10.多线程和并发
  • 11.线程安全锁
  • 12.内存分配堆和栈
  • 13.IO流与文件
  • 14.异常处理
  • 15.STL标准模板库

01.基础语法

目录介绍

  • 1.1 C++简单介绍
    • 1.1.1 C++简介
    • 1.1.2 C++四大特性
    • 1.1.3 C++标准库
    • 1.1.4 C++编译器
    • 1.1.5 helloWorld
    • 1.1.6 多种注释
    • 1.1.7 命名空间
    • 1.1.8 头文件名
    • 1.1.9 cout输出
  • 1.2 修饰符和标识符
    • 1.2.1 修饰符
    • 1.2.2 标志符
    • 1.2.3 关键字
  • 1.3 变量和常量
    • 1.3.1 变量
    • 1.3.2 常量
  • 1.4 数据类型
    • 1.4.1 基本类型
    • 1.4.2 整型
    • 1.4.3 浮点型
    • 1.4.4 字符型
    • 1.4.5 布尔类型
    • 1.4.6 sizeof
    • 1.4.7 数据输入
    • 1.4.9 类型转换
  • 1.5 字符串类型
    • 1.5.1 字符串型
    • 1.5.2 字符串拼接
    • 1.5.3 字符串判断
    • 1.5.4 字符串输入
    • 1.5.5 转义字符
  • 1.6 结构体复合类型
    • 1.6.1 基本概念和定义
    • 1.6.2 结构体数组
    • 1.6.3 结构体指针
    • 1.6.4 结构体嵌套结构体
    • 1.6.5 结构体做函数参数
    • 1.6.6 结构体const场景
    • 1.6.7 结构体案例
  • 1.7 其他复用类型
    • 1.7.1 枚举使用
    • 1.7.2 共用体

1.1 C++简单介绍

1.1.1 C++简介

C++ 简介

C++ 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言,支持过程化编程、面向对象编程和泛型编程。

C++ 被认为是一种中级语言,它综合了高级语言和低级语言的特点。

C++ 是由 Bjarne Stroustrup 于 1979 年在新泽西州美利山贝尔实验室开始设计开发的。C++ 进一步扩充和完善了 C 语言,最初命名为带类的C,后来在 1983 年更名为 C++。

C++ 是 C 的一个超集,事实上,任何合法的 C 程序都是合法的 C++ 程序。

注意:使用静态类型的编程语言是在编译时执行类型检查,而不是在运行时执行类型检查。

1.1.2 C++四大特性

完全支持面向对象的程序设计,包括面向对象开发的四大特性:封装,继承,多台,抽象。

封装(Encapsulation):封装是将数据和方法组合在一起,对外部隐藏实现细节,只公开对外提供的接口。这样可以提高安全性、可靠性和灵活性。

继承(Inheritance):继承是从已有类中派生出新类,新类具有已有类的属性和方法,并且可以扩展或修改这些属性和方法。这样可以提高代码的复用性和可扩展性。

多态(Polymorphism):多态是指同一种操作作用于不同的对象,可以有不同的解释和实现。它可以通过接口或继承实现,可以提高代码的灵活性和可读性。

抽象(Abstraction):抽象是从具体的实例中提取共同的特征,形成抽象类或接口,以便于代码的复用和扩展。抽象类和接口可以让程序员专注于高层次的设计和业务逻辑,而不必关注底层的实现细节。

1.1.3 C++标准库

标准的 C++ 由三个重要部分组成:

核心语言,提供了所有构件块,包括变量、数据类型和常量,等等。

C++ 标准库,提供了大量的函数,用于操作文件、字符串等。

标准模板库(STL),提供了大量的方法,用于操作数据结构等。

C++ 的使用场景

在许多行业和领域都有广泛应用,包括:游戏,嵌入式,图形图像等

1.1.4 C++编译器

day1_hello.cpp 案例代码

#include <iostream>

using namespace std;

void test1_1_1_4();

int main() {
    test1_1_1_4();
    return 0;
}

//1.1.1.4 C++ 编译器编译
void test1_1_1_4() {
    cout << "1.1.1.4 C++ 编译器编译。hello world" << endl;
}

最简单的编译方式:

$ g++ day1_hello.cpp

由于命令行中未指定可执行程序的文件名,编译器采用默认的 a.out。程序可以这样来运行:

$ ./a.out
1.1.1.4 C++ 编译器编译。hello world

通常我们使用 -o 选项指定可执行程序的文件名,以下实例生成一个 day1_hello 的可执行文件:

$ g++ day1_hello.cpp -o day1_hello
$ ./day1_hello
1.1.1.4 C++ 编译器编译。hello world

g++ 有些系统默认是使用 C++98,我们可以指定使用 C++11 来编译 main.cpp 文件:

g++ -g -Wall -std=c++11 main.cpp

1.1.5 helloWorld

让我们看一段简单的代码,可以输出单词 Hello World。

#include <iostream>
using namespace std;
// main() 是程序开始执行的地方 是一个单行注释。
int main() {
    cout << "Hello world" << endl;
    return 0;
}

C++ 语言定义了一些头文件,这些头文件包含了程序中必需的或有用的信息。上面这段程序中,包含了头文件 <iostream>。

下一行 using namespace std; 告诉编译器使用 std 命名空间。命名空间是 C++ 中一个相对新的概念。

下一行 // main() 是程序开始执行的地方 是一个单行注释。单行注释以 // 开头,在行末结束。

下一行 int main() 是主函数,程序从这里开始执行。

下一行 cout << "Hello World"; 会在屏幕上显示消息 "Hello World"。

下一行 return 0; 终止 main( )函数,并向调用进程返回值 0。

1.1.6 多种注释

作用:在代码中加一些说明和解释,方便自己或其他程序员程序员阅读代码

两种格式

  1. 单行注释:// 描述信息
    • 通常放在一行代码的上方,或者一条语句的末尾,==对该行代码说明==
  2. 多行注释: /* 描述信息 */
    • 通常放在一段代码的上方,==对该段代码做整体说明==

提示:编译器在编译代码时,会忽略注释的内容

1.1.7 命名空间

遇到问题:一个中大型软件往往由多名程序员共同开发,会使用大量的变量和函数,不可避免地会出现变量或函数的命名冲突。当所有人的代码都测试通过,没有问题时,将它们结合到一起就有可能会出现命名冲突。

场景例如:您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。

解决办法:因此,引入了命名空间这个概念,可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。

  1. 使用 namespace space名称 可以定义命名空间。通过命名空间可以调用所在区域函数
  2. 使用 using namespace space名称 可以通过该方式引入命名空间。这个指令会告诉编译器,后续的代码将使用指定的命名空间中的名称。
  3. 嵌套的命名空间,命名空间可以嵌套,可以在一个命名空间中定义另一个命名空间。可以通过使用 :: 运算符来访问嵌套的命名空间中的成员。
//定义命名空间
namespace first_space {
    void fun() {
        cout << "Inside first_space" << endl;
    }
}
namespace second_space {
    void fun() {
        cout << "Inside second_space" << endl;
    }
}
void test1() {
    cout << "定义命名空间" << endl;
    // 调用第一个命名空间中的函数
    first_space::fun();
    // 调用第二个命名空间中的函数
    second_space::fun();
}

//using 指令
using namespace first_space;
//using 指令引入的名称遵循正常的范围规则。名称从使用 using 指令开始是可见的,直到该范围结束。此时,在范围以外定义的同名实体是隐藏的。
void test2() {
    cout << "using 指令" << endl;
    fun();
}

//嵌套的命名空间
namespace first_sp{
    void funSp() {
        cout << "Inside first_sp,逗比充1" << endl;
    }
    namespace second_sp {
        void funSp() {
            cout << "Inside second_sp,逗比充2" << endl;
        }
    }
}
using namespace first_sp::second_sp;


void test3() {
    cout << "嵌套的命名空间" << endl;
    // 调用第二个命名空间中的函数
    funSp();
}

int main() {
    test1();
    test2();
    test3();
    return 0;
}

1.1.8 头文件名

1.1.9 cout输出

1.2 修饰符和标识符

1.2.1 修饰符

什么是修饰符,修饰符(modifiers)是用于修改基本数据类型的关键字。它们可以改变数据类型的行为、范围或存储方式。

const:用于声明常量,表示变量的值在初始化后不能被修改。

volatile:用于声明易变变量,表示变量的值可能会在未知的时间被改变,通常用于多线程或硬件相关的编程。

signed 和 unsigned:用于整数类型,指定变量是否可以表示负数。

short 和 long:用于整数类型,指定变量的范围。short表示短整数,long表示长整数

static:用于变量和函数,表示变量在整个程序执行期间保持其值,函数在当前文件中可见。

extern:用于变量和函数,表示变量或函数在其他文件中定义或声明。

1.2.2 标志符

作用:C++规定给标识符(变量、常量)命名时,有一套自己的规则

C++ 标识符是用来标识变量、函数、类、模块,或任何其他用户自定义项目的名称。

  • 标识符不能是关键字
  • 标识符只能由字母、数字、下划线组成
  • 第一个字符必须为字母或下划线
  • 标识符中字母区分大小写

建议:给标识符命名时,争取做到见名知意的效果,方便自己和他人的阅读

有效标志符,一个标识符以字母 A-Z 或 a-z 或下划线 _ 开始,后跟零个或多个字母、下划线和数字(0-9)。

无效标志符,C++ 标识符内不允许出现标点字符,比如 @、& 和 %。C++ 是区分大小写的编程语言。

1.2.3 关键字

作用:关键字是C++中预先保留的单词(标识符)

  • 在定义变量或者常量时候,不要用关键字

C++关键字如下:

asmdoifreturntypedef
autodoubleinlineshorttypeid
booldynamic_castintsignedtypename
breakelselongsizeofunion
caseenummutablestaticunsigned
catchexplicitnamespacestatic_castusing
charexportnewstructvirtual
classexternoperatorswitchvoid
constfalseprivatetemplatevolatile
const_castfloatprotectedthiswchar_t
continueforpublicthrowwhile
defaultfriendregistertrue
deletegotoreinterpret_casttry

提示:在给变量或者常量起名称时候,不要用C++得关键字,否则会产生歧义。

1.3 变量和常量

1.3.1 变量

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

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

示例:

#include <iostream>
using namespace std;

int main() {
    //变量的定义
    //语法:数据类型  变量名 = 初始值
    int a = 10;
    cout << "a = " << a << endl;
    return 0;
}

注意:C++在创建变量时,必须给变量一个初始值,否则会报错

1.3.2 常量

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

C++定义常量两种方式

  1. #define 宏常量: #define 常量名 常量值

    • ==通常在文件上方定义==,表示一个常量
  2. const修饰的变量 const 数据类型 常量名 = 常量值

    • ==通常在变量定义前加关键字const==,修饰该变量为常量,不可修改

示例:

#include <iostream>
using namespace std;

//1.宏常量
#define day = 7;

int main() {
    //cout << "一周里总共有 %d" << day << " 天" << endl;
    //printf("一周里总共有:%d\n",day);
    //day = 8;  //报错,宏常量不可以修改
    //2、const修饰变量
    const int month = 12;
    cout << "一年里总共有 " << month << " 个月份" << endl;
    //month = 24; //报错,常量是不可以修改的
    return 0;
}

1.4 数据类型

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

1.4.1 基本类型

1.4.2 整型

作用:整型变量表示的是==整数类型==的数据

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

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

1.4.3 浮点型

作用:用于==表示小数==

浮点型变量分为两种:

  1. 单精度float
  2. 双精度double

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

数据类型占用空间有效数字范围
float4字节7位有效数字
double8字节15~16位有效数字

示例:

int main() {
    float f1 = 3.14;
    float f2 = 3.14f;
    double d1 = 3.14;
    double d2 = 3.14f;
    cout << f1 << endl;
    cout << f2 << endl;
    cout << d1<< endl;
    cout << d2<< endl;
    cout << "float  sizeof = " << sizeof(f1) << endl;
    cout << "float  sizeof = " << sizeof(f2) << endl;
    cout << "double sizeof = " << sizeof(d1) << endl;
    cout << "double sizeof = " << sizeof(d2) << endl;

    //科学计数法
    float f3 = 3e2; // 3 * 10 ^ 2
    cout << "f3 = " << f2 << endl;
    float f4 = 3e-2;  // 3 * 0.1 ^ 2
    cout << "f3 = " << f3 << endl;
    return 0;
}
//3.14
//3.14
//3.14
//3.14
//float  sizeof = 4
//float  sizeof = 4
//double sizeof = 8
//double sizeof = 8
//f3 = 3.14
//f3 = 300

1.4.4 字符型

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

语法:char ch = 'a';

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

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

  • C和C++中字符型变量只占用==1个字节==。
  • 字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元

示例:

int main() {
    char ch = 'a';
    cout << ch << endl;
    cout << sizeof(char) << endl;
    //ch = "abcde"; //错误,不可以用双引号
    //ch = 'abcde'; //错误,单引号内只能引用一个字符
    cout << (int) ch << endl;  //查看字符a对应的ASCII码
    ch = 97; //可以直接用ASCII给字符型变量赋值
    cout << ch << endl;
    return 0;
}
//a
//1
//97
//a

ASCII码表格:

ASCII值控制字符ASCII值字符ASCII值字符ASCII值字符
0NUT32(space)64@96、
1SOH33!65A97a
2STX34"66B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL39,71G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383S115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92/124|
29GS61=93]125}
30RS62>94^126`
31US63?95_127DEL

ASCII 码大致由以下两部分组成:

  • ASCII 非打印控制字符: ASCII 表上的数字 0-31 分配给了控制字符,用于控制像打印机等一些外围设备。
  • ASCII 打印字符:数字 32-126 分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。

1.4.5 布尔类型

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

bool类型只有两个值:

  • true --- 真(本质是1)
  • false --- 假(本质是0)

bool类型占==1个字节==大小

示例:

int main() {
    bool flag = true;
    cout << flag << endl; // 1
    flag = false;
    cout << flag << endl; // 0
    cout << "size of bool = " << sizeof(bool) << endl; //1
    return 0;
}
//1
//0
//size of bool = 1

1.4.6 sizeof

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

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

示例:

int main() {
    cout << "short 类型所占内存空间为: " << sizeof(short) << endl;
    cout << "int 类型所占内存空间为: " << sizeof(int) << endl;
    cout << "long 类型所占内存空间为: " << sizeof(long) << endl;
    cout << "long long 类型所占内存空间为: " << sizeof(long long) << endl;
    return 0;
}
//short 类型所占内存空间为: 2
//int 类型所占内存空间为: 4
//long 类型所占内存空间为: 8
//long long 类型所占内存空间为: 8

整型结论:==short < int <= long <= long long==

1.4.7 数据输入

作用:用于从键盘获取数据

**关键字:**cin

语法: cin >> 变量

示例:

int main() {
    //整型输入
    int a = 0;
    cout << "请输入整型变量:" << endl;
    cin >> a;
    cout << a << endl;

    //浮点型输入
    double d = 0;
    cout << "请输入浮点型变量:" << endl;
    cin >> d;
    cout << d << endl;

    //字符型输入
    char ch = 0;
    cout << "请输入字符型变量:" << endl;
    cin >> ch;
    cout << ch << endl;

    //字符串型输入
    string str;
    cout << "请输入字符串型变量:" << endl;
    cin >> str;
    cout << str << endl;

    //布尔类型输入
    bool flag = true;
    cout << "请输入布尔型变量:" << endl;
    cin >> flag;
    cout << flag << endl;
    return 0;
}

1.4.9 类型转换

1.5 字符串使用

1.5.1 字符串型

作用:用于表示一串字符

两种风格

  1. C风格字符串: char 变量名[] = "字符串值"

示例:

int main() {
  char str1[] = "hello world";
  cout << str1 << endl;
  return 0;
}

注意:C风格的字符串要用双引号括起来

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

示例:

int main() {
  string str = "hello world";
  cout << str << endl;
  return 0;
}

注意:C++风格字符串,需要加入头文件==#include<string>==

1.5.4 字符串输入

cin.getline() 是在输入一段字符完成后开始读取数据(注意,是输入完成后,以Enter为结束标志)

语法: cin.getline()

示例:

int main() {
    int N = 100;
    char X[N];
    cin.getline(X,N);   //以cin.getline形式输入
    int a ,b;
    for (int i = 0; i < N; ++i) {
        if (X[i] == '#') {
            break;
        } else if (X[i] >= 0 && X[i] <=9) {
            a++;
        } else if ((X[i] >= 'a' && X[i] <= 'z') || (X[i] >= 'A' && X[i] <= 'Z')) {
            b++;
        }
    }
    cout << "数字的个数:" << a << ",字母的个数:" << b << endl;
    return 0;
}

1.5.5 转义字符

作用:用于表示一些==不能显示出来的ASCII字符==

现阶段我们常用的转义字符有: \n \\ \t

转义字符含义ASCII码值(十进制)
\a警报007
\b退格(BS) ,将当前位置移到前一列008
\f换页(FF),将当前位置移到下页开头012
\n换行(LF) ,将当前位置移到下一行开头010
\r回车(CR) ,将当前位置移到本行开头013
\t水平制表(HT) (跳到下一个TAB位置)009
\v垂直制表(VT)011
\\代表一个反斜线字符""092
'代表一个单引号(撇号)字符039
"代表一个双引号字符034
?代表一个问号063
\0数字0000
\ddd8进制转义字符,d范围0~73位8进制
\xhh16进制转义字符,h范围0~9,a~f,A~F3位16进制

示例:

int main() {
	cout << "\\" << endl;
	cout << "\tHello" << endl;
	cout << "\n" << endl;
	return 0;
}

1.6 结构体复合类型

1.6.1 基本概念和定义

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

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

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

  • struct 结构体名 变量名
  • struct 结构体名 变量名 = { 成员1值 , 成员2值...}
  • 定义结构体时顺便创建变量

示例:

//结构体定义
struct student {
    //成员列表
    string name;  //姓名
    int age;      //年龄
    int score;    //分数
} stu3; //结构体变量创建方式3

int main() {
    //结构体变量创建方式1
    struct student stu1; //struct 关键字可以省略
    stu1.name = "张三";
    stu1.age = 18;
    stu1.score = 100;
    cout << "姓名:" << stu1.name << " 年龄:" << stu1.age  << " 分数:" << stu1.score << endl;
    //结构体变量创建方式2
    struct student stu2 = { "李四",19,60 };
    cout << "姓名:" << stu2.name << " 年龄:" << stu2.age  << " 分数:" << stu2.score << endl;
    //结构体变量创建方式3
    stu3.name = "王五";
    stu3.age = 18;
    stu3.score = 80;
    cout << "姓名:" << stu3.name << " 年龄:" << stu3.age  << " 分数:" << stu3.score << endl;
    return 0;
}

总结1:定义结构体时的关键字是struct,不可省略

总结2:创建结构体变量时,关键字struct可以省略

总结3:结构体变量利用操作符 ''.'' 访问成员

1.6.2 结构体数组

**作用:**将自定义的结构体放入到数组中方便维护

语法: struct 结构体名 数组名[元素个数] = { {} , {} , ... {} }

示例:

//结构体定义
struct student3 {
    //成员列表
    string name;  //姓名
    int age;      //年龄
    int score;    //分数
};

int main() {
    //结构体数组
    struct student3 arr[3] =
            {
                    {"张三", 18, 80},
                    {"李四", 19, 60},
                    {"王五", 20, 70}
            };
    for (int i = 0; i < 3; i++) {
        cout << "姓名:" << arr[i].name << " 年龄:" << arr[i].age << " 分数:" << arr[i].score << endl;
    }
    return 0;
}

1.6.3 结构体指针

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

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

示例:

//结构体定义
struct student4 {
    //成员列表
    string name;  //姓名
    int age;      //年龄
    int score;    //分数
};

int main() {
    struct student4 stu = {"张三", 18, 100,};
    struct student4 *p = &stu;
    p->score = 80; //指针通过 -> 操作符可以访问成员
    cout << "姓名:" << p->name << " 年龄:" << p->age << " 分数:" << p->score << endl;
    return 0;
}

总结:结构体指针可以通过 -> 操作符 来访问结构体中的成员

1.6.4 结构体嵌套结构体

作用: 结构体中的成员可以是另一个结构体

**例如:**每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体

示例:

//学生结构体定义
struct student {
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};

//教师结构体定义
struct teacher {
    //成员列表
	int id; //职工编号
	string name;  //教师姓名
	int age;   //教师年龄
	struct student stu; //子结构体 学生
};

int main() {
	struct teacher t1;
	t1.id = 10000;
	t1.name = "老王";
	t1.age = 40;
	t1.stu.name = "张三";
	t1.stu.age = 18;
	t1.stu.score = 100;
	cout << "教师 职工编号: " << t1.id << " 姓名: " << t1.name << " 年龄: " << t1.age << endl;
	cout << "辅导学员 姓名: " << t1.stu.name << " 年龄:" << t1.stu.age << " 考试分数: " << t1.stu.score << endl;
	return 0;
}

总结:在结构体中可以定义另一个结构体作为成员,用来解决实际问题

1.6.5 结构体做函数参数

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

传递方式有两种:

  • 值传递
  • 地址传递

示例:

//学生结构体定义
struct student {
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};

//值传递
void printStudent(student stu) {
	stu.age = 28;
	cout << "子函数中 姓名:" << stu.name << " 年龄: " << stu.age  << " 分数:" << stu.score << endl;
}

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

int main() {
	student stu = { "张三",18,100};
	//值传递
	printStudent(stu);
	cout << "主函数中 姓名:" << stu.name << " 年龄: " << stu.age << " 分数:" << stu.score << endl;
	cout << endl;
	//地址传递
	printStudent2(&stu);
	cout << "主函数中 姓名:" << stu.name << " 年龄: " << stu.age  << " 分数:" << stu.score << endl;
	return 0;
}

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

1.6.6 结构体const场景

作用:用const来防止误操作

示例:

//学生结构体定义
struct student {
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};

//const使用场景
//加const防止函数体中的误操作
void printStudent(const student *stu) {
	//stu->age = 100; //操作失败,因为加了const修饰
	cout << "姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;
}

int main() {
	student stu = { "张三",18,100 };
	printStudent(&stu);
	return 0;
}

1.6.7 结构体案例

案例1学生成绩,案例描述:

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

设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员

学生的成员有姓名、考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值

最终打印出老师数据以及老师所带的学生数据。

示例:

struct Student
{
	string name;
	int score;
};
struct Teacher
{
	string name;
	Student sArray[5];
};

void allocateSpace(Teacher tArray[] , int len)
{
	string tName = "教师";
	string sName = "学生";
	string nameSeed = "ABCDE";
	for (int i = 0; i < len; i++)
	{
		tArray[i].name = tName + nameSeed[i];
		
		for (int j = 0; j < 5; j++)
		{
			tArray[i].sArray[j].name = sName + nameSeed[j];
			tArray[i].sArray[j].score = rand() % 61 + 40;
		}
	}
}

void printTeachers(Teacher tArray[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << tArray[i].name << endl;
		for (int j = 0; j < 5; j++)
		{
			cout << "\t姓名:" << tArray[i].sArray[j].name << " 分数:" << tArray[i].sArray[j].score << endl;
		}
	}
}

int main() {
	srand((unsigned int)time(NULL)); //随机数种子 头文件 #include <ctime>
	Teacher tArray[3]; //老师数组
	int len = sizeof(tArray) / sizeof(Teacher);
	allocateSpace(tArray, len); //创建数据
	printTeachers(tArray, len); //打印数据
	return 0;
}

案例2英雄排名,案例描述:

设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。

通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。

五名英雄信息如下:

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

示例:

//英雄结构体
struct hero
{
	string name;
	int age;
	string sex;
};
//冒泡排序
void bubbleSort(hero arr[] , int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - 1 - i; j++)
		{
			if (arr[j].age > arr[j + 1].age)
			{
				hero temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
//打印数组
void printHeros(hero arr[], int len) {
	for (int i = 0; i < len; i++) {
		cout << "姓名: " << arr[i].name << " 性别: " << arr[i].sex << " 年龄: " << arr[i].age << endl;
	}
}

int main() {
	struct hero arr[5] = {
		{"刘备",23,"男"},
		{"关羽",22,"男"},
		{"张飞",20,"男"},
		{"赵云",21,"男"},
		{"貂蝉",19,"女"},
	};
	int len = sizeof(arr) / sizeof(hero); //获取数组元素个数
	bubbleSort(arr, len); //排序
	printHeros(arr, len); //打印
	return 0;
}
贡献者: yangchong211
下一篇
02.运算符和表达式