C++基础从0到1入门编程(三)

系统学习C++
方便自己日后复习,错误的地方希望积极指正
往期文章:
C++基础从0到1入门编程(一)
C++基础从0到1入门编程(二)
参考视频:
1.黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难
2.系统化学习C++

1 简单链表 共同体 枚举

链表

在这里插入图片描述
单链表:节点之间只能单向的联系
双链表:可以双向联系

struct st_girl
{
	int bo;
	string name;
	struct st_girl* next; // 下一个超女节点的地址,如果本节点是最后一条记录,填nullptr
};

简单的链表操作
1.分配节点
2.遍历链表
3.删除链表

#include <iostream>         // 包含头文件。
#include <cstring>
using namespace std;        // 指定缺省的命名空间。

struct st_girl
{
    int no;
    string name;      // 超女姓名。
    struct st_girl* next;
};

int main()
{
    // head 头指针 tail 尾指针 tmp 临时指针
    st_girl* head = nullptr, *tail = nullptr, *tmp = nullptr;
    // 分配第一个节点
    tmp = new st_girl({1, "BigDavid", nullptr});
    head = tail = tmp;
    // 分配第二个节点
    tmp = new st_girl({6, "LiuXueJin", nullptr});
    tail->next = tmp;
    tail = tmp;

    // 分配第三个节点
    tmp = new st_girl({3, "as", nullptr});
    tail->next = tmp;
    tail = tmp;

    // 遍历链表
    tmp = head;
    while (tmp!=nullptr)
    {
        cout << tmp->no << ' ' << tmp->name << tmp->next << endl;
        tmp = tmp->next;
    }
    // 释放
    while (head!=nullptr)
    {
        tmp = head;       // 让临时节点指向头节点
        head = head->next;// 头节点后移
        delete tmp;       // 删除临时节点
    }
}
共同体

能存储不同数据类型,但同一时间只能存储一个

union udata
{
	int a;
	double b;
	char c[21];
};

应用场景:
(1)当数据项使用两种或多种格式(但不会同时使用),可节省空间(嵌入式系统)
(2)回调函数的参数

Tip:

  1. 共同体占用内存的大小是它最大的成员占用内存的大小(内存对齐)
  2. 全部成员共用一块内存
  3. 共同体中的值为最后被赋值的成员的值
  4. 匿名共同体没有名字,可以在定义的时候创建匿名共同体变量(VS和Linux有差别),也可以嵌入结构体中。
#include <iostream>         // 包含头文件。
#include <cstring>
using namespace std;        // 指定缺省的命名空间。

//union udata
//{
//    int a;
//    double b;
//    char c[21];
//};

struct st_girl
{
    int no;
    union
    {
        int a;
        double b;
        char c[21];
    };
};
int main()
{
//    udata data;

//    cout << sizeof(data) << endl; // 24 对齐到8的整数倍
//    cout << (void*)&data.a << endl; // 0x8e5bfff820
//    cout << (void*)&data.b << endl; // 0x8e5bfff820
//    cout << (void*)&data.c << endl; // 0x8e5bfff820
//
//    data.a = 3;
//    data.b = 8.8;
//    strcpy(data.c, "asd");
//    cout << data.a << endl;
//    cout << data.b << endl;
//    cout << data.c << endl;
      struct st_girl girl;
      cout << (void*)&girl.no << endl;
      cout << (void*)&girl.a << endl;
      cout << (void*)&girl.b << endl;
      cout << (void*)&girl.c << endl;
}
枚举

枚举:创建符号常量
语法:
enum 枚举名 { 枚举量1, 枚举量2, 枚举量3, ... ,枚举量n };

// colors 成了一种新的枚举类型的名称,可以用它创建枚举变量
enum colors { red, yellow, blue }; // 0 1 2

枚举

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

int main()
{
    enum colors {red , yellow, green}; // 0 1 2
    colors cc = green; // 2
    // colors cc = colors(1);
    cout << red << ' ' << yellow << ' ' << green << ' ' << cc;
}

2 引用

2.1 引用基本概念

引用就是变量的别名
主要用途:函数的形参和返回值
语法:数据类型 &引用名 = 原变量名;
Tip:
(1)引用数据类型要与原变量名类型相同
(2)引用名和原变量名可以互换,值和内存单元是相同的
(3)必须在声名引用的时候初始化,否则编译报错

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

int main()
{
    int a = 3;
    int& ra = a; // 创建引用
    // long long& b = a; 错误的
    cout << a << ' ' << ra << endl;
    cout << &a << ' ' << &ra << endl; // 地址和值都是相同的

    ra = 8;
    cout << a << ' ' << ra << endl;
    cout << &a << ' ' << &ra << endl;

    int b = 5;
    ra = b; // ra = 5
    cout << &ra << ' ' << &b << endl;
    cout << a << ' ' << ra << endl;
    cout << &a << ' ' << &ra << endl;
}

引用是指针常量的伪装

2.2 引用用于函数的参数

把函数的形参声明为引用,调用函数的时候,形参将成为实参的别名(传引用)
最主要的用途:函数的参数
(1)传引用代码更简洁
(2)传引用不必使用二级指针
回顾二级指针

#include <stdio.h>

int main()
{
	int a = 10;
	int b = 20;
	int *p = &a;
	int** s = &p;

	//一次解引用*s 此时类型int*
	*s = &b;
	//二次解引用**s 此时类型int
	**s = 200;
	return 0;
}

二级指针s解引用操作:

一次解引用
s的类型变成了(int)(代表着一级指针p)间接改变了p的指向,从a的地址变成了b的地址;
二次解引用
s的类型变成了int (代表着变量b),此时s = 200;(等价于b = 200;)

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。
void fun1(int** p)
{
    *p = new int(3);// p是二级指针,存放指针的地址
    cout << *p << ' ' << **p << endl; // 0x1b4b87218c0 3
}
void fun2(int* &p)
{
    p = new int(3); // p是指针的别名
    cout << p << ' ' << *p << endl; // 0x1b4b87218c0 3
}
int main()
{
    int *p = nullptr; // 存放子函数动态分配内存的地址
    fun1(&p);         // 传地址,实参填指针p的地址
    fun2(p);      // 传引用,实参填指针p
}

(3)引用的属性和特别之处

传值:修改形参不会影响实参
传地址:修改形参会影响实参
传引用:修改形参会影响实参

2.3 引用的形参和const

如果引用的数据对象类型不匹配,当引用为const,C++会创建临时变量,让引用指向临时变量
创建临时变量
(1)引用是const
(2)数据对象的类型是正确的,但不是左值

左值:可以被引用的数据对象,可以通过地址访问(变量,数组元素,结构体成员,引用和解引用的指针)
非左值:字面常量(双引号的字符串除外)和包含多项的表达式

(3)数据对象类型不正确,但可以转换为正确的类型
如果函数的实参不是左值或与const引用形参的类型不匹配,那么C++将创建正确类型的匿名变量,将实参的值传递给匿名变量,并让形参来引用该变量

引用形参声明为const原因:

  1. 避免无意修改数据的编程错误
  2. 用const能使函数处理const和非const实参,否则只能接受非const实参
  3. 使用const,函数能正确生成并使用临时变量
#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。
void fun(const int& no, const string& str)
{
    cout << no << ' ' << str << endl;
}
int main()
{
    fun('s', "asd");
    int bh = 1;
    string a = "sadasd";
    fun(bh, a);
}
2.4 引用用于函数的返回值

函数的返回值被拷贝到一个临时位置(寄存器或栈)
如果返回引用不会拷贝内存
语法:返回值数据类型& 函数名(形参列表);
Tip:
(1)如果返回局部变量的引用,本质是野指针
(2)可以返回函数的引用形参、类的成员、全局变量、静态变量
(3)返回引用的函数是被引用的变量的别名,将const用于引用的返回类型

#include <iostream>
using namespace std;

const int& fun(int &ra)
{
    ra++;
    cout << &ra << ' ' << ra << endl;
    return ra;
}

int main()
{
    int a = 3;
    const int& b = fun(a);

    cout << &a << ' ' << &b << ' ' << endl;
    cout << a << ' ' << b << endl;
    
//    fun(a) = 3; // 返回引用的函数是被引用变量的别名
}
2.5 各种形参的使用场景

重要
(1)如果不需要在函数中修改实参

  1. 如果实参很小,就值传递
  2. 如果实参是数组,用const指针,因为是唯一的选择(没有为数组建立引用)
  3. 实参是比较大的结构,使用const指针或const引用
  4. 如果实参是类,则使用const引用,传递类的标准方式是按引用传递

(2)如果需要在函数中修改实参

  1. 如果实参是内置数据类型,使用指针。只要看到fun(&x)的调用,表示函数将修改x
  2. 如果实参是数组,则只能使用指针
  3. 如果实参是结构体,则使用指针或者引用
  4. 如果实参是类,则使用引用

3 函数的默认参数

语法:返回值 函数名(数据类型 参数 = 值,数据类型 参数 = 值,...);

#include <iostream>
using namespace std;

void fun(const string &message = "BigDavid")
{
    cout << message << endl;
}

int main()
{
    fun("Liu");  // Liu
    fun();               // BigDavid
}

Tip:
(1)函数的声明和定义分开写的,在函数的声名里写默认参数,函数的定义里不能写默认参数

#include <iostream>
using namespace std;

void fun(const string &message = "BigDavid");
int main()
{
    fun("Liu");  // Liu
    fun();               // BigDavid
}

//void fun(const string &message = "BigDavid")
//{
//    cout << message << endl;
//}
void fun(const string &message)
{
    cout << message << endl;
}

(2)函数必须右到左设置默认参数。如果为某个参数设置默认值,则它后面所有的参数都设置默认值

#include <iostream>
using namespace std;

void fun(int no, const string& name = "Big", int bh = 8)
{
    cout << no << ' ' << name << ' ' << bh << endl;
}

int main()
{
    fun(1);
}

(3)调用函数的时候,如果指定某个参数的值,该参数前面的值都需要指定

#include <iostream>
using namespace std;

void fun(int no, const string& name = "Big", int bh = 8)
{
    cout << no << ' ' << name << ' ' << bh << endl;
}

int main()
{
    //fun(1,8);
    fun(1,"as");
}

4 函数重载

函数重载(函数多态)是指设计一系列同名函数,完成相似的工作
C++允许定义名称相同的函数,条件是特征不同

特征:形参个数,数据类型,排列顺序

int fun(short a, string b);
int fun(int a, int b);
int fun(short a, string b, double c);
int fun(string b, short a);

需求重载各种数据类型,不要重载功能不同的函数
注意事项:
(1)使用重载函数时,如果数据类型不匹配,C++尝试使用类型转换与形参进行匹配,如果转换后有多个函数能匹配上,编译将报错

void fun(short a, string b)
{
	cout << a << ' ' << b << endl;
}
void fun(int a, string b)
{	
	cout << a << ' ' << b << endl;
}
int main()
{
	long bh = 0;
	// 有多个函数能匹配上,编译将报错
	fun(bh,"sas");   // long->short 会丢失精度
}

(2)引用可以作为函数重载的条件,但是,调用重载函数的时候,如果实参是变量,编译器将形参类型的本身和类型引用视为同一特征

#include <iostream>
using namespace std;
void show(int bh, string a)
{
	cout << bh << ' ' << a << endl;
}
void show(int& bh, string a)
{
	cout << bh << ' ' << a << endl;
}
int main()
{
	int a = 0;
	show(a, "asd"); // 报错
	show(10, "sd");
}

(3)如果重载函数有默认参数,调用函数时,可能导致匹配失败

#include <iostream>
using namespace std;
void show(int bh, string a)
{
	cout << bh << ' ' << a << endl;
}
void show(int bh, string a, string c = "sad")
{
	cout << bh << ' ' << a << ' ' << c << endl;
}
int main()
{
	show(1,"asd");// 可能导致匹配失败
}

(4)const不能作为函数重载的特征

#include <iostream>
using namespace std;
void show(int bh, string a)
{
	cout << bh << ' ' << a << endl;
}
void show(const int bh, string a)
{
	cout << bh << ' ' << a << endl;
}
int main()
{
	show(1,"asd");// 报错,函数已有主体
}

(5)返回值的数据类型不同不能作为函数重载的特征
(6)C++的名称修饰:编译时,对每个函数名进行加密,替换成不同名的函数。

5 内联函数

用途:提高程序运行的速度
语法:在函数声名和定义前加上关键字inline
常见的做法是将函数声名和定义写在一起
Tip:
(1)内联函数节省时间,但消耗内存
(2)如果函数过大,编译器可能不将其作为内联函数
(3)内联函数不能递归

#include <iostream>
using namespace std;

inline void show(const int bh, const string& message)
{
    cout << bh << ' ' << message << endl;
}

int main()
{
    show(1,"sd");
    show(2, "qwe");
    show(4, "asaaa");
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/166132.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开源与闭源:大模型发展的双重走向

目录 前言开源和闭源的优劣势比较开源的优势闭源的优势 开源和闭源对大模型技术发展的影响对技术发展的影响对数据共享的影响对业务拓展的影响 开源与闭源的商业模式比较开源的商业模式闭源的商业模式 处在大模型洪流中&#xff0c;向何处去&#xff1f;结语 前言 随着人工智能…

python趣味编程-5分钟实现一个俄罗斯方块游戏(含源码、步骤讲解)

Python俄罗斯方块游戏是一款基于GUI的标题匹配益智游戏,非常容易理解和使用。说到游戏玩法,一切都和真实的一样。 用户必须管理俄罗斯方块的随机序列。在这个Python 俄罗斯方块游戏项目中,我将教您如何使用 Python 制作俄罗斯方块游戏。 Python 代码中的俄罗斯方块游戏:项目…

如何在虚拟机的Ubuntu22.04中设置静态IP地址

为了让Linux系统的IP地址在重新启动电脑之后IP地址不进行变更&#xff0c;所以将其IP地址设置为静态IP地址。 查看虚拟机中虚拟网络编辑器获取当前的子网IP端 修改文件/etc/netplan/00-installer-config.yaml文件&#xff0c;打开你会看到以下内容 # This is the network conf…

开源WIFI继电器之硬件电路

一、原理图 源文件 二、原理图说明 1、器件说明 U4&#xff1a;ESP8285模块 U6&#xff1a;触发器 U3&#xff1a;继电器 2、继电器状态检测说明 检测继电器线圈是否通电来判断继电器是否导通&#xff0c;当Q1不导通时&#xff0c;Q1集电极的电压为3.3V&#xff0c;经…

【运维篇】Redis常见运维命令详解

文章目录 1. 前言2. 连接管理命令详解2.1 AUTH命令2.2 PING命令2.3 SELECT命令2.4 QUIT命令 3. 服务器管理命令详解3.1 FLUSHALL命令3.2 SAVE/BGSAVE命令3.3 SHUTDOWN命令 4. 安全管理命令详解4.1 CONFIG命令4.1.1 CONFIG SET命令用法4.1.2 CONFIG GET命令用法 4.2 AUTH命令 5.…

T10 数据增强

文章目录 一、准备环境和数据1.环境2. 数据 二、数据增强&#xff08;增加数据集中样本的多样性&#xff09;三、将增强后的数据添加到模型中四、开始训练五、自定义增强函数六、一些增强函数 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f…

【算法】滑动窗口题单——2.不定长滑动窗口(求最长/最大)

文章目录 3. 无重复字符的最长子串1493. 删掉一个元素以后全为 1 的最长子数组904. 水果成篮1695. 删除子数组的最大得分2841. 几乎唯一子数组的最大和2024. 考试的最大困扰度1004. 最大连续1的个数 III1438. 绝对差不超过限制的最长连续子数组2401. 最长优雅子数组解法1——维…

[AutoSar]导出task mapping 表到excel

目录 关键词平台说明背景实现方法 关键词 嵌入式、C语言、autosar 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 背景 为了做文档输出&#xff0c;要导出task mapping 到excel。 实现方法 1.按住shift&#xf…

IDEA自动注解设置(中文版)

IDEA自动注解设置 1、添加类自动注释 文件 - 设置 - 编辑器 - 文件和代码模板 - Include - File Header /** *description&#xff1a;TODO *author&#xff1a; ${USER} *create&#xff1a; ${DATE} ${TIME} */2、添加类方法自动注释 文件 - 设置 - 编辑器 - 实时模版 - …

NSS [NCTF 2018]小绿草之最强大脑

NSS [NCTF 2018]小绿草之最强大脑 题目要求我们输入一个位数>21的正数&#xff0c;带入表达式并且计算结果。 查看源码发现hint&#xff0c;有源码泄露。 拿dirsearch扫一下。扫到了一个备份文件。 python dirsearch.py -u http://node4.anna.nssctf.cn:28805/访问/index.…

SpringCloud 微服务全栈体系(十四)

第十一章 分布式搜索引擎 elasticsearch 四、RestAPI ES 官方提供了各种不同语言的客户端&#xff0c;用来操作 ES。这些客户端的本质就是组装 DSL 语句&#xff0c;通过 http 请求发送给 ES。官方文档地址&#xff1a;https://www.elastic.co/guide/en/elasticsearch/client/…

H110主板搭配魔改QNCW升级小记

最近搬家完毕&#xff0c;翻出来一块闲置已久的qncw&#xff0c;隐约记得是买的主板套装&#xff0c;现在主板早已不知踪影&#xff0c;剩下孤零零一个CPU&#xff0c;一起翻出来一个G3900T亮机CPU&#xff0c;应该是同时代的产物。 qncw百度上一搜&#xff0c;发现参数还行&am…

iTerm2+oh-my-zsh搭个Mac电脑上好用好看终端

根据苹果网站上介绍&#xff0c;bash是 macOS Mojave 及更早版本中的默认Shell&#xff0c;从 macOS Catalina 开始&#xff0c;zsh(Z shell) 是所有新建用户帐户的默认Shell。 1. 安装Oh my zsh sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzs…

代码随想录算法训练营第二十八天| 78 子集 90 子集|| 93 复原IP地址

78 子集 由题意可知数组中的元素互不相同&#xff0c;所以在dfs中我们可以将当前的path直接加入到res中。 class Solution {List<List<Integer>>res new ArrayList<>();List<Integer>path new LinkedList<>();public List<List<Integer…

计算机网络的标准化工作及相关组织

一、国际化组织 计算机网络的标准化工作由一些主要的组织来进行管理和推动。以下是几个主要的计算机网络标准化的国际组织及其相关的标准&#xff1a; 1. 国际标准化组织&#xff08;ISO&#xff09;&#xff1a;国际标准化组织负责制定各种行业的标准&#xff0c;包括计算机…

【Kingbase FlySync】命令模式:部署双轨并行,并实现切换同步

【Kingbase FlySync】命令模式:安装部署同步软件&#xff0c;实现Oracle到KES实现同步 双轨并行方案说明一.准备工作二.环境说明三.目标实操(1).准备安装环境Orcle服务器(Oracle40)1.上传所有工具包2.操作系统配置a.增加flysync 用户、设置密码b.配置环境变量c.调整limits.conf…

Django+Vue项目创建 跑通

参考链接&#xff1a; 【精选】DjangoVue项目构建_django vue-CSDN博客 一、背景 主要介绍如何使用后端Django 前端Vue 的技术栈快速地搭建起一套web项目的框架。 为什么使用Django和Vue? Django是Python体系下最成熟的web框架之一&#xff0c;由于Python语言的易用…

GIT无效的源路径/URL

ssh-add /Users/haijunyan/.ssh/id_rsa ssh-add -K /Users/haijunyan/.ssh/id_rsa

nodejs+vue实验室上机管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

用户&#xff1a;管理员、教师、学生 基础功能&#xff1a;管理课表、管理机房情况、预约机房预约&#xff1b;权限不同&#xff0c;预约类型不同&#xff0c;教师可选课堂预约和个人&#xff1b;课堂预约。 在实验室上机前&#xff0c;实验室管理员需要对教务处发来的上机课表…

交易机器人-微信群通知

微信公众号:大数据高性能计算 1 背景 背景是基于人工去做交易本身无法做到24小时无时无刻的交易,主要是虚拟币本身它是24小时交易,人无法做到24小时盯盘,其次就是如果你希望通过配置更加复杂的规则甚至需要爬取最新的信息走模型进行量化交易的时候,就需要自己去做一些量化…