C++初阶篇----新手进村

目录

  • 一、什么是C++
  • 二、C++关键字
  • 三、命名空间
    • 3.1命名空间的定义
    • 3.2命名空间的使用
  • 四、C++输入和输出
  • 五、缺省参数
    • 5.1缺省参数的概念
    • 5.2缺省参数的分类
  • 六、函数重载
    • 6.1函数重载的概念
    • 6.2函数重载的原理----名字修饰
  • 七、引用
    • 7.1引用概念
    • 7.2引用特性
    • 7.3常引用
    • 7.4引用的使用
    • 7.5传值、传引用效率比较
    • 7.6引用和指针的区别
    • 7.7引用与指针的不同点
  • 八、内联函数
    • 8.1内联函数概念
    • 8.2 特性
  • 九、auto关键字
    • 9.1类型别名思考
    • 9.2 auto简介
    • 9.3 auto的使用细则
    • 9.4 auto不能推导的场景
  • 十、C++范围的for循环(C++11)
    • 10.1范围for的语法
    • 10.2范围for的使用条件
  • 十一、nullptr指针空值(C++11)

一、什么是C++

二、C++关键字

相较于C语言,C语言有32个关键字,而C++则有63个关键字

在这里插入图片描述

三、命名空间

在C/C++中,变量、函数等的类都是大量存在的,这些变量、函数和类的名称将都存
在于全局作用域中,可能会导致很多冲突。
使用命名空间的目的是对标识符的名称进行本地化,
以避免命名冲突或名字污染,**namespace**关键字的出现就是针对这种问题的

3.1命名空间的定义

命名空间的普通定义

//命名空间的普通定义
namespace bit
{int rand = 10;int scanf = 2;int Add(int x, int y){return x + y;}
}

命名空间的嵌套定义

//命名空间的嵌套定义、
namespace bit1
{int rand = 10;int scanf = 2;int Add(int x, int y){return x + y;}namespace bit2{int c;int d;int Sub(int left, int right){return left + right;}}
}

同一个命名空间的合并
同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中

3.2命名空间的使用

作用域:

符号**“::”**在C++中叫做作用域限定符,我们通过“命名空间名称::命名空间成员”便可以访问到命名空间中相应的成员

加命名空间名称及作用域限定符,嵌套调用可以用"xxx::bbb::"

	std::cin >> i;cout << "xxxx" << endl;cout << bit::rand << endl;

使用using将命名空间中某个成员引入

using std::cout;
using std::endl;

使用using namespace 命名空间名称 引入

using namespace bit;
int main()
{int i = 0;std::cin >> i;cout << "xxxx" << endl;cout << bit::rand << endl;Add();
}

四、C++输入和输出

std是C++标准库的命名空间名,C++将标准库的定义实现都放在这个命名空间中

使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
以及按命名空间使用方法使用std。

输出流:cout和endl,其中endl表示换行输出.他们都包含在的头文件中 输入流:cin
<<是流插入运算符,>>是流提取运算符

在C++的输入输出可以自动识别变量类型
在这里插入图片描述

五、缺省参数

5.1缺省参数的概念

缺省参数是声明或定义函数时为函数的一个参数指定一个缺省值,在调用函数的时候,如果没有传参(也就是没有指定的实参)则采用该形参的缺省值
在这里插入图片描述

5.2缺省参数的分类

全缺省参数

void myq(int x=5,int y=2,int z=5)
{cout << "x=" << x << endl;cout << "y=" << y << endl;cout << "z=" << z << endl;}

半缺省参数

void fun(int x, int y = 10)
{cout << x << y << endl;
}
  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现

六、函数重载

同一个函数名可以定义为多个不同类型的函数

6.1函数重载的概念

函数重载是指在同一个作用域内,可以定义多个具有相同名称但参数列表不同的函数。C++通过函数的参数个数、类型或顺序的不同来实现函数重载。

通过使用相同的函数名来实现不同的功能和操作

//1.参数类型不同
int max(int x, int y)
{if (x > y)return x;elsereturn y;
}double max(double x, double y)
{if (x - y > 0)return x;else return y;
}
//2.参数个数不同
void max()
{cout << "max()" << endl;
}//3.参数类型的顺序
void min(int x, char y)
{cout << x << y << endl;
}void min(char x, int y)
{cout << x << y << endl;
}int main()
{max(1, 4);max(1.2, 4.2);max();min(6, 'm');min('m', 5);return 0;
}

在这里插入图片描述

6.2函数重载的原理----名字修饰

C/C++中,一个程序在运行中都需要经历这四个阶段:预处理、编译、汇编、链接
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  1. 编译后链接前,a.o的目标 文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。那么 怎么办呢?
  2. 链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。
  3. 在c中的链接,函数是通过函数名来寻找函数的地址
  4. 而C++中的链接,会通过函数名和函数参数的类型来寻找

七、引用

7.1引用概念

引用不是新定义一个变量,而是给已有的变量去一个别名,本质上就是同一个变量的不同叫法。
因此编译器不会为引用变量开辟内存空间,他和它引用的变量共用同一块内存空间

类型& 引用变量名(对象名) = 引用实体;
在这里插入图片描述

注意:引用类型必须和引用实体为同一种类型

7.2引用特性

  1. 引用在定义是必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体

7.3常引用

在这里插入图片描述

int main()
{const int a = 10;const int& ma = a;//int& fa = a;        //编译出错double b = 3.14;double & fa = b;const int& c = 10;double d = 12.34;//int& rd = d; // 该语句编译时会出错,类型不同const int& rd = d;cout << b << endl << c << endl;return 0;	
}

7.4引用的使用

参数引用

void Swap(int& x, int& y)
{int tmp = x;x = y;y = tmp;
}

返回值引用

int& count()
{static int x = 0;x++;return x;
}

引用函数返回值的作用
避免不必要的对象拷贝开销,提高程序的性能;支持连续赋值和链式调用,使代码更加简洁和易读;同时允许函数返回修改后的对象,增加了程序的灵活性。因此,在设计函数接口时,如果函数返回的是一个非基本数据类型的对象,考虑返回值引用通常是一个不错的选择。

7.5传值、传引用效率比较

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void TestRefAndValue()
{A a;// 以值作为函数参数size_t begin1 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc1(a);size_t end1 = clock();// 以引用作为函数参数size_t begin2 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc2(a);size_t end2 = clock();// 分别计算两个函数运行结束后的时间cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}

在这里插入图片描述
传值和指针在作为传参以及返回值类型上效率相差很大

7.6引用和指针的区别

语法的概念上,引用就是一个别名,没有独立空间,同引用实体共用一块空间
而在编译器实现的底层上,实际是有空间的,因为引用也是按照指针方式来实现的,只是较于c来说,把事情的重复性交给了底层,来提高效率

7.7引用与指针的不同点

1. 引用概念上定义一个变量的别名,指针存储一个**变量地址**。
2. **引用在定义时必须初始化,而指针没有要求**
3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
4. 没有NULL引用,但有NULL指针
5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
位平台下占4个字节)
6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
7. 有多级指针,但是没有多级引用
8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
9. 引用比指针使用起来相对更安全

八、内联函数

8.1内联函数概念

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率
在这里插入图片描述
这里便涉及到汇编的一些知识

内联函数实质是,将整个函数(也就是这一堆的指令) ,直接展开使用
比较 宏: 宏虽然也能直接展开函,但宏的本质是将所写的指令从一个名字中替换

8.2 特性

  1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会
    用函数体替换函数调用.
    缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。
  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。
  3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址
    了,链接就会找不到

相较于的优缺点:
优:

  1. 可以增强代码复用性
  2. 提高性能
    缺:
  3. 不方便调试
  4. 可读性差
  5. 没有类型的检查

C++有哪些技术替代宏?

  1. 常量定义 换用const enum
  2. 短小函数定义 换用内联函数

九、auto关键字

9.1类型别名思考

当程序过于复杂,类型过于繁多复杂,如

  1. 类型难以拼写
  2. 含义不明确
#include <string>
#include <map>
int main()
{std::map<std::string, std::string> m{ { "apple", "苹果" }, { "orange", 
"橙子" }, {"pear","梨"} };std::map<std::string, std::string>::iterator it = m.begin();while (it != m.end()){//....}return 0;
}

std::map<std::string, std::string>::iterator 是一个类型,但是该类型太长了,特别容易写错。

使用typedef给类型取别名确实可以简化代码,但是typedef有会遇到新的难题:

typedef char* pstring;
int main()
{const pstring p1;    // 编译成功还是失败?const pstring* p2;   // 编译成功还是失败?return 0;
}

在编程时,常常需要把表达式的值赋值给变量,这就要求在声明变量的时候清楚地知道表达式的
类型。然而有时候要做到这点并非那么容易,因此C++11给auto赋予了新的含义。

9.2 auto简介

使用auto修饰的变量,是具有自动存储器的局部变量
但实际应用中并不多见,这是为什么?

:auto不再是一个存储类型指示符,而是作为一
个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得

注意
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。

9.3 auto的使用细则

  1. auto与指针和引用结合起来使用
    用auto声明指针类型时,用auto和auto* 没有区别,但用auto声明引用类型则必须加 &
  2. 在同一行定义多个变量 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译 器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

9.4 auto不能推导的场景

  1. auto不能作为函数的参数
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
  1. 不能直接用来声明数组

十、C++范围的for循环(C++11)

10.1范围for的语法

C++是兼容C的,所以for循环中,C的语法依然是适用的

int main()
{for(int i=0;i<10;i++){printf("%d ",i);}return 0;
}

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因
此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范
围内用于迭代的变量
,第二部分则表示被迭代的范围

for(迭代变量 : 别迭代范围){}

int main()
{int array1[] = { 1,2,3,4,5,6 };int array2[] = { 1,2,3,4,5,6 };//仅仅只是变量的拷贝,不做修改for (int i : array1){i *= 2;}for (auto e : array1){cout << e << " ";}cout << endl;//for范围配合引用,可以做到指针的效果for (auto& i : array2){i *= 2;}for (auto i : array2){cout << i << " ";}return 0;
}

在这里插入图片描述

10.2范围for的使用条件

for循环迭代的范围必须是确定的
对于数组而言**,就是数组中第一个元素和最后一个元素的范围**;对于类而言,应该提供begin和end的办法,begin和end就是for循环迭代的范围

十一、nullptr指针空值(C++11)

声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下方式对其进行初始化:

	int* N = NULL;int* M = 0;

在C的头文件中,(stddef.h)
NULL实际是一个宏 ,所以在应用中,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦

void fun(int)
{cout << "fun(int)" << endl;
}
void fun(int*)
{cout << "fun(int*)" << endl;
}int main()
{fun(0);fun(NULL);fun((int*)NULL);return 0;
}

在这里插入图片描述
本意是想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,因此与程序的
初衷相悖.
字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。

注意:

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入 的。
  2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
  3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

解析十六进制雷达数据格式:解析雷达数据长度。

以Cat62格式雷达数据为例&#xff0c;十六进制雷达数据部分代码&#xff1a; 3e0120bf7da4ffee0085 雷达数据长度使用4个字符&#xff08;2个字节&#xff09;标识&#xff0c;在这里是“0120”&#xff0c;转换为十进制数为288。 雷达数据长度父类&#xff1a; base_length_…

Easy Excel动态表头的实现

步骤&#xff1a; 1.查找官方API文档理解实现 2.实现融入到代码里面 一&#xff1a;Easy Excel动态头实时生成头写入 动态头实时生成头写入 二&#xff1a;实现 目的&#xff1a;实现表头为&#xff0c;第一列是固定列&#xff0c;第二列为动态生成的时间段的每一天的日期…

《MySQL 简易速速上手小册》第7章:MySQL监控和日志分析(2024 最新版)

文章目录 7.1 配置和使用 MySQL 监控工具7.1.1 基础知识7.1.2 重点案例&#xff1a;使用 Python 和 Prometheus 监控 MySQL 性能7.1.3 拓展案例 1&#xff1a;自动化 MySQL 慢查询日志分析7.1.4 拓展案例 2&#xff1a;实时警报系统 7.2 解读 MySQL 日志文件7.2.1 基础知识7.2.…

Linux网络编程——udp套接字

本章Gitee地址&#xff1a;udp套接字 文章目录 创建套接字绑定端口号读取数据发送数据聊天框输入框 创建套接字 #include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol);int domain参数&#xff1a;表面要创建套接字的域…

07 A B 从计数器到可控线性序列机

07. A.从计数器到可控线性序列机 让LED灯按照亮0.25秒。灭0.75秒的状态循环亮灭让LED灯按照亮0.25秒&#xff0c;灭0.5秒&#xff0c;亮0.75秒&#xff0c;灭1秒的状态循环亮灭让LED灯按照指定的亮灭模式亮灭&#xff0c;亮灭模式未知&#xff0c;由用户随即指定。以0.25秒为一…

Vuex介绍和使用

1. 什么是Vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式和库。它解决了在大型 Vue.js 应用程序中共享和管理状态的问题&#xff0c;使得状态管理变得更加简单、可预测和可维护。 在 Vue.js 应用中&#xff0c;组件之间的通信可以通过 props 和事件进行&#xff0c…

Java基础常见面试题总结-集合(一)

常见的集合有哪些&#xff1f; Java集合类主要由两个接口Collection和Map派生出来的&#xff0c;Collection有三个子接口&#xff1a;List、Set、Queue。 Java集合框架图如下&#xff1a; List代表了有序可重复集合&#xff0c;可直接根据元素的索引来访问&#xff1b;Set代表…

Unity类银河恶魔城学习记录5-3 P64 Foundation of Skill System源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili SkillManager.cs using System.Collections; using System.Collections.G…

(1)短距离(<10KM)

文章目录 1.1 Bluetooth 1.2 CUAV PW-Link 1.3 ESP8266 wifi telemetry 1.4 ESP32 wifi telemetry 1.5 FrSky telemetry 1.6 Yaapu双向遥测地面站 1.7 HOTT telemetry 1.8 MSP(MultiWii 串行协议)(4.1 版) 1.9 MSP (version 4.2) 1.10 SiK Radio v1 1.11 SiK Radio …

速过计算机二级python——第9讲 详解第 2 套真题

第9讲 详解第 2 套真题 基本编程题【15 分】简单应用题【25 分】综合应用题【20 分】**问题 1**【10 分】:**问题 2【10 分】:**基本编程题【15 分】 考生文件夹下存在一个文件 PY101.py,请写代码替换横线,不修改其他代码,实现以下功能:【5 分】题目: import __________ b…

算法---回溯(正文)

1.什么是回溯&#xff1f; 回溯算法的定义就是和暴力枚举一样枚举所有可能并加撤回&#xff0c;也能和暴力一样去掉一些重复&#xff08;在之前就被筛出&#xff0c;但还要枚举这个&#xff0c;我们可以跳过这个了---------这个就是回溯剪枝&#xff09;。但为什么回溯不是暴力…

Python实现文本情感分析

前言 文本情感分析是一种重要的自然语言处理(NLP)任务&#xff0c;旨在从文本数据中推断出情感信息&#xff0c;例如正面、负面或中性情感。它在社交媒体分析、产品评论、市场调研等领域都有广泛的应用。本文将详细介绍如何使用Python进行文本情感分析&#xff0c;包括基础概念…

【从零开始学设计模式】第四章_抽象工厂模式(与工厂方法模式区分)

第四章_抽象工厂模式&#xff08;与工厂模式区分&#xff09; 1.介绍 1.1定义 为访问类提供一个创建一组相关或相互依赖对象的接口&#xff0c;且访问类无须指定所要产品的具体类 就能得到同族的不同等级的产品的模式结构&#xff1b; 1.2解决的问题 主要解决接口选择的问…

解析十六进制雷达数据格式:解析雷达数据类型。

以Cat62格式雷达数据为例&#xff0c;十六进制雷达数据部分代码&#xff1a; 3e0120bf7da4ffee0085 雷达数据使用2个字符&#xff08;1个字节&#xff09;标识&#xff0c;在这里是“3e”&#xff0c;转换为十进制数为62。 雷达数据类型父类&#xff1a; base_header_process…

Git简单了解

文章目录 1、Git概述2、Git下载与安装3、Git代码托管服务3.1、使用码云托管服务 1、Git概述 什么是Git Git是一个分布式版本控制工具&#xff0c;主要用于管理开发过程中的源代码文件&#xff08;Java类、xml文件、html页面等&#xff09;&#xff0c;在软件开发过程中被广泛使…

jvm问题自查思路

本文聊一下最近处理了一些jvm的问题上&#xff0c;将这个排查和学习过程分享一下&#xff0c;看了很多资料&#xff0c;最终都会落地到几个工具的使用&#xff0c;本文主要是从文档学习、工具学习和第三方技术验证来打开认知和实践&#xff0c;希望有用。 一、文档 不仅知道了…

新年新展望

去年其实是收获颇丰的一年&#xff0c;除了工作中各项工作都得到了很大的推进&#xff0c;个人生活中也有很多变化&#xff0c;其中还拿到了功能安全工程师的证书&#xff0c;以及功能安全经理的证书。 展望一下2024年准备输出的内容&#xff0c;一个是对ISO26262的解读&#x…

力扣刷题之旅:进阶篇(五)—— 动态规划(DP)的妙用

力扣&#xff08;LeetCode&#xff09;是一个在线编程平台&#xff0c;主要用于帮助程序员提升算法和数据结构方面的能力。以下是一些力扣上的入门题目&#xff0c;以及它们的解题代码。 --点击进入刷题地址 引言&#xff1a; 在算法的世界中&#xff0c;动态规划&#xff…

开发JSP应用程序

开发JSP应用程序 问题陈述 TecknoSoft Pvt Ltd.公司的首席技术官(CTO)John Barrett将创建一个应用程序的任务委托给了开发团队,该应用程序应在客户访问其账户详细信息前验证其客户ID和密码。客户ID应是数字形式。John希望如果所输入的客户ID或密码不正确,应向客户显示错误…

一文带你读懂JSON模块

json模块 JSON (JavaScript Object Notation)&#xff1a;是一个轻量级的数据交换格式模块&#xff0c;受javascript对象文本语法启发&#xff0c;但不属于JavaScript的子集。 常用方法&#xff1a; dump(obj,fp)&#xff1a;将对象以字符串的形式写入文件中。 load(fp)&am…