C++基础(一)

目录

1.不同版本的hello word!

2.namespace和::域作用限定符以及using

2.1 namespace

 2.2::

2.3using用于展开域

3.C++输入和输出

4.缺省参数

 5.重载

6.引用

6.1引用介绍

6.2 引用的特性

注意:

 6.4 const 的引用

 6.5指针和引用的关系

 7.inline

 8.nullptr



1.不同版本的hello word!

还记得第一次写C语言的hello word吗

//text.c
#include<stdio.h>int main()
{printf("hello word!\n");return 0;
}

 这是C++版的

//text.cpp
#include<iostream>
using namespace std;
int main()
{cout << "hello word! \n" << endl;return 0;
}

C++ 诞生于c之后,c++兼容了c,我们重点了解c++中不同于c的部分

2.namespace和::域作用限定符以及using

 定义命名空间,需要用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。命名空间可以定义变量/函数/类型等。

2.1 namespace

namespace bit

{

//定义变量
int rand=10;

//定义函数

int Add ( int a , int b )

{

return a +b ;
}

//定义类型

 struct Node

{

struct Node* next;

int val;
};

}

 2.2::

调用域下面的变量/函数等

bit  ::rand

  • namespace本质是定义了一个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下面的rand不存在冲突了
namespace text1 {int rand = 0;
}
namespace text2 {int rand = 10;
}

 C++中域有函数局部域,全局域,类域;域影响的是编译时语法查找一个变量/函数/类型出处(声明或定义)的逻辑,所以有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的声明周期,命名空间域和类域不影响变量声明周期。

//text.cpp
#include<iostream>
using namespace std;namespace bit 
{int rand;int a = 2;int Fun(float c, float d){return c * d;}
}
int Fun(int c ,int d )
{return c + d;
}
int a = 1;
int main()
{int a = 0;printf("%d\n", a);// a没有被域限定 代码从上往下走,main 函数下被重新赋值 a=0,所以输出0printf("%d\n", ::a);//a被::域限定符限定,但左边没有元素,默认为全局域,a=1所以输出1printf("%d\n", bit::a);//a被::域限定符限定,左边有域名,限定在自定义的域,在bit域中a=2,所以输出2
printf("%d\n",Fun(1,2));
// a没有被域限定 代码从上往下走,找到自定义函数Fun调用Fun实现相加,输出3
printf("%d\n", ::Fun(1, 2));
//a虽然有域限定符,但是并没有限定范围,还是全局域找到Fun实现相加,输出3printf("%d\n", bit::Fun(1,2));//a被::域限定符限定,左边有域名,限定在自定义的域,在bit域中找到Fun实现相乘,输出2}

 验证答案

namespace只能定义在全局,当然他还可以嵌套定义

//text.cpp
#include<iostream>
using namespace std;namespace bit 
{int rand;namespace aa{int rand=1;}namespace bb {int rand=0;}
}int a = 1;
int main()
{printf("%d\n", bit::aa::rand);printf("%d\n", bit::bb::rand);return 0;
}

项目工程中多个文件中定义的同名namespace会认为是一个namespace,不会冲突

C++标准库都放在一个叫std(stdndard)的命名空间中

2.3using用于展开域

using namespace std;
//展开std头文件
using namespace bit::rand;
//展开bit中的rand

 一般日常练习中我们可以using namespace std,世纪项目开发中不建议using namespace

3.C++输入和输出

  1.  <iostream>是Input Output Stream 的缩写,是标准的输入,输出流库,定义了标准的输入,输出对象
  2. std::cin是ostream类的对象,他主要面向窄字符(narrow character (of type char))的标准输入流
  3. std::cout是ostream类的对象,它主要面向窄字符的标准输出流
  4. std::endl 是一个函数,流插入输出流,相当于插入一个换行字符加刷新缓冲区
  5. <<是流插入运算符,>>是流提取运算符(c语言中的左移右移操作符)
  6. 使用C++输入输出更方便,不要像printf/scanf输入输出那样,需要手动指定格式,C++的输入输出可以自动识别变量类型(本质是痛过重载实现的),其实最重要的是C++的流能更好的支持只定义类型对象的输入和输出。
//text.cpp
#include<iostream>
using namespace std;int main()
{int i = 123;int j = 234;int x;int y;cin >> x >> y;//控制台手动输入x,ycout << i << j << endl;//输出i和j并且最后换行return 0;
}

但是一对<<  <<内只能有一个变量,否则编译器报错

在c++中我们没有包含<stdio.h>,也可以使用printf和scanf,在包含<iostream>间接包含了。vs编译器是这样的,但其他编译器会报错

4.缺省参数

  • 缺省参数是声明或定义函数时为函数指定一个确实值,在调用该函数时,如果没有指定实参则采用改形式参数的缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数                                                                                                                                                                   全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省必须从右往左依次连续缺省,不能间隔条约给缺省值
  • 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值
//text.cpp
#include<iostream>
using namespace std;
//全缺省
void Fun1(int a=10,int b=20,int c=30)
{cout << "全缺省" << endl;cout << "a=" << a << endl;cout << "b=" << b << endl;cout << "c=" << c << endl;}
//半缺省
void Fun2( int a ,int b=10 ,int c=20)
{cout << "半缺省" << endl;cout << "a=" << a << endl;cout << "b=" << b << endl;cout << "c=" << c << endl;
}void Fun3(int a, int b, int c)
{cout << "普通" << endl;cout << "a=" << a << endl;cout << "b=" << b << endl;cout << "c=" << c << endl;
}
int main()
{Fun1();//没有传参时,使用参数的默认值Fun2(10);//传参时,使用的指定值Fun3(10,20,30);//传入指定值return 0;
}

 5.重载

C++支持在同一作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或则类型不同。这样C++函数调用就表现出了多态行为,使用更加灵活。C语言是不支持同一作用域中出现同名函数的。

//text.cpp
#include<iostream>
using namespace std;
//1.参数类型不同
int Add(int a, int b)
{cout << "int Add(int a, int b)" << endl;return a + b;
}
double Add(double a, double b)
{cout << "double Add(double a, double b)" << endl;return a + b;
}
//2.参数个数不同
int Add(int a)
{cout << "int Add(int a)" << endl;return a;
}
double Add(double a, double b)
{cout << "double Add(double a, double b)" << endl;return a + b;
}
//3.参数类型顺序不同
void  fun(int a, char b)
{cout << "void fun(int a, char b)" << endl;}
void  fun(char b, int  a)
{cout << "void fun(char a, int b)" << endl;}
int main()
{cout << "参数类型不同" << endl;cout << Add(3,5)<< endl;cout << Add(3.1,5.0) << endl;cout << "参数个数不同" << endl;cout << Add(3) << endl;cout << Add(3.1, 5.0) << endl;cout << "参数类型顺序不同" << endl;fun(3, 'x');fun('x', 5);return 0;
}

 注意:返回值不能作为判断是否重载的依据因为容易产生歧义,如下面的代码f()调用

//text.cpp
#include<iostream>
using namespace std;
void f()
{
cout<<"f()<<endl;
}
void f(int a=10)
{
cout<<"f(int a=20)"<<endl;
}int main()
{f();
return 0;
}

 

6.引用

6.1引用介绍

 引用不是新定义一个变量,而是给已存在变量去了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间

类型&引用别名=引用对象;

//text.cpp
#include<iostream>
using namespace std;int main()
{int a = 0;//引用:b和c是a的别名cout << "a=" << a <<" " << &a << endl;int &b = a;cout << "b=" << b <<" " << &b << endl;int& c = a;cout << "c=" << c << " " << &c << endl;//也可以给b取别名,d还是相当于a的别名int& d = a;cout << "d=" << d<< " " << &d << endl;return 0;
}

 值一样,地址也一样

 只是取得“外号”罢了

 传统的交换函数

void Swap(int* x,int* y)
{
int tem=*x;
*y=*x;
*x=tem;
}

现在只要传引用就能解决

void Swap(int& rx,int&ry)
{
int tem=rx;
rx=ry;
ry=tem;}

6.2 引用的特性

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

//text.cpp
#include<iostream>
using namespace std;int main()
{int a = 0;int ra&;//编译器报错,未给初始化引用//一个变量可以有多个别名int &b = a;//引用:b和c是a的别名int& c = a;//也可以给b取别名,d还是相当于a的别名int& d = a;//d是a的别名//给别名取别名int& f = b;return 0;
}

 

注意:

  1. 引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时改变被引用对象
  2. 引用传参跟指针传参功能类似,引用传参相对更加方便
  3. 引用返回值的场景相对比较复杂
  4. 引用和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引用跟其他语言的引用有很大差别,除了用法,最大的点,C++引用定义后不能改变指向,JAVA的引用可以改变指向

 6.4 const 的引用

  • 可以引用一个const对象,但是必须用const引用。const引用也可以引用普通对象,因为对象的访问权限在引用过程中可以缩小,但是不能放大

不需要注意的是类似于int& rb=a*3; double d=12.34 ; int & rd=d;这样一些场景下a*3的值结果保存在一个临时对象中,int& rd=d 也是类似,在类型转换中会产生临时对象存储中间值,也就是说,rb和rd引用的都是临时对象,而C++规定的临时对象具有常性,所以在这里就触发了权限放大,必须要用常引用才可以

所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象,C++把这个未命名对象叫做临时对象

//text.cpp
#include<iostream>
using namespace std;int main()
{int a = 0; //定义整型a=0const int b = 10;//定义整型常量b=10int& ra = a;//给ra引用a,权限一样,没问题const int& raa = a;//给raa引用a ,权限缩小,也没问题int& rb = b;//给rb引用b,有const修饰到没有const修饰,权限放大,编译器报错const int& rbb = b;//给rbb引用b,有const修饰到const修饰,权限一致,没问题int& ab = (a + b);//编译器报错,表达式的结果存在临时对象里,临时对象具有常性const int& ab = (a + b);//编译通过int rd = b;int abb = a + b;//编译通过,表达式的结果虽然存在临时变量里,这里是将表达式的值拷贝一份给abb没有涉及权限的问题a++;ra++;//可以执行,没有const修饰rb++;//不存在rbb++;raa++;b++;//有const修饰,编译器报错double d = 12.34;int i = d;//隐式类型转换会产生临时变量,但是值得拷贝不影响int& ri = d; //编译不通过,double转换为int类似,C++规定会产生临时对象,临时对象具有常性,所以这里不加const,权限缩小const int& rii = d;//编译通过return 0;
}

注意:临时对象只有短暂的生命周期,但是被引用后,生命周期会延长直到引用对象销毁

 6.5指针和引用的关系

C++中指针和引用就像两个性格迥异的亲兄弟,指针是哥哥,引用是弟弟,在实践中他们相辅相成,功能具有重叠性,但是各有自己的特点,互相不可替代

  • 语法概念上引用是一个变量的取别名不开空间,指针是存储一个变量的地址,要开空间
  • 引用在定义时引用一个对象后,就不能再引用其他对象;而指针可以不断得改变指向对象
  • 引用可以直接访问指向对象,指针需要解引用才能访问指向对象
  • sizeof中含义不同,引用结果为引用类型大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位平台下是8字节)
  • 指针很容易出现空指针和野指针的问题,引用很少出现,引用使用起来相对更安全一些

 

从汇编语言来看,引用本质就是指针 

 7.inline

  • 用inline修饰的函数叫做内敛函数,编译时C++编译器会在调用的地方展开内联函数,这样调用内敛函数就需要建立栈帧了,提高效率
//text.cpp
#include<iostream>
using namespace std;inline int Add(int x, int y)
{int ret = x + y;ret += 1;ret += 1;ret += 1;ret += 1;ret += 1;return ret;
}
int main()
{int ret = Add(1, 2);cout << ret << endl;return 0;
}

看一下汇编语言 ,实现内敛了

  • inline对于编译器而言只是一个建议,也就是说,你加了inline编译器也可以选择在调用的地方不展示,不同的编译器关于inline什么情况展开各不相同,因为C++标准没有这个。inline适合用于频繁调用的短小函数,对于递归函数,代码相对较对一些的函数,加上inline也会被编译器忽略2

  • C语言实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错且不方便调试,C++设计了inline目的就是替代C的宏函数
  • VS编译器debug版本下面默认是不展开inline的,这样方便调试,debug版本想展开需要设置一下这两个地方

 

  • inline不建议声明和定义分离到两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,连接时会出现报错


 8.nullptr

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

C++11中引入nullptr,nullptr是一个特殊的关键字,nullptr是一种特殊类型的字面量,它可以转换成任意其他类型的指针类型。使用nullptr定义空指针可避免类型转换的问题,因为nullptr只能被隐式转换成指针类型,而不能被转换为整数类型

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win11用户由中文名改为英文名

目录 前情提要 一喜一悲&#xff1a;找回“消失”的文件&#xff0c;却失去新建文件的权限。 找回“消失”的文件 ​编辑 失去新建文件的权限 核心问题&#xff1a;怎么解决右键只建立文件夹&#xff1f; 弯路1&#xff1a;获取管理员权限 弯路2&#xff1a;获取管理员权…

Linux基础(权限)+mysql(函数)+初始shell

[rootcentos ~]# whereis test.c test: /usr/bin/test /usr/share/man/man1/test.1.gz /usr/share/man/man1p/test.1p.gz [rootcentos home]# zip -r my.zip lesson1 将目录设为zip unzip my.zip -d xxxxxx 可指定要减压到的位置。 tar [-cxtzjvf] 文件与目录 .... 参数&…

python自动化之用flask库写一个登陆接口(代码示例)

用到的库&#xff1a; 1、flask&#xff08;写接口&#xff09; 2、cerberus&#xff08;校验数据&#xff09; 实现效果&#xff1a;输入账号和密码&#xff0c;校验数据类型是否是字符串&#xff0c;如果是&#xff0c;返回登陆成功&#xff1b;如果不是&#xff0c;返回数…

UnityHub 无法添加模块问题

文章目录 1.问题描述2.问题解决 1.问题描述 在Hub中无法添加模块 2.问题解决 1、点击设置 2、设置版本安装位置 可以发现installs的安装位置路径设置不是unity安装位置&#xff0c;这里我们更改成自己电脑unity安装位置的上一级路径 添加模块正常&#xff1a;

【C++】哈希表的模拟实现及 unordered_set 和 unorderded_map 的封装

目录 前言一、哈希表的模拟实现1.1 哈希表的改造1.1.1 模板参数列表的改造1.1.2 增加迭代器操作 1.2 哈希表的模拟实现1.2.1 哈希表中仿函数的实现1.2.2 哈希表中节点类的实现1.2.3 哈希表中迭代器类的实现1.2.4 哈希表中构造函数、析构函数和 Clear() 函数的实现1.2.5 哈希表中…

阐述 C 语言中的浮点数精度问题?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 【https://dwz.mosong.cc/cyyjc】通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&…

matlab支持向量机使用错误

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

ROS的TF系统

一、SLAM 1、SLAM全称是Simultaneous Localization And Mapping&#xff0c;即同时定位与地图构建 2、SLAM软件包Hector_Mapping&#xff0c;←建图可参考链接所示文章 二、机器人定位 1、假设机器人开始建图的位置是地图坐标系的原点 2、则机器人在建图过程中的位置可以描…

DenseNet算法实现乳腺癌识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、前期准备 1.设置GPU import torch import torch.nn as nn import torchvision.transforms as transforms import torchvision from torchvision import …

CUDA原子操作

代码 #include <cuda_runtime.h> #include <stdio.h>__global__ void atomicAddAndGet(int *result, int *valueToAdd) {// 原子加法int addedValue atomicAdd(result, *valueToAdd);// 通过原子操作后读取值&#xff0c;确保是加法后的值addedValue *valueToAd…

黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录 Day4

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我会…

HDFS Decommission节点的长尾分析和问题解决

文章目录 前言Decommission过慢的分析过程NameNode页面并不显示Decommission的进度和剩余块数量增加每次调度的块数量增加Stream Limit以避免节点被Skip节点被Skip时应该在DEBUG时打印原因在大量节点被Skip的时候加快有效调度其他可能改进 基本流程解析用户通过节点刷新触发Dec…

java Web学习笔记(一)

文章目录 1. 前置学习知识2. Tomcat介绍Tomcat目录文件介绍URL的组成部分和项目资源的对应关系idea配置部署tomcat并成功运行一个app-web项目 3. HTTP协议介绍&#xff08;很重要&#xff09;HTTP协议和HTTPS的区别HTTP协议的发展理解HTTP协议 报文格式报文响应的状态码 4. Ser…

以设备为核心的状态自动采集、人工运维和预测性维护为一体的智能管理系统

中服云设备全生命周期管理系统充分利用物联网、人工智能、机器学习、大数据等新一代技术&#xff0c;实现对企业生产设备从采购、安装、调试、使用、维护、维修、改造、更新直到报废全生命周期的智能化、数字化、可视化的实时管控&#xff0c;支持设备运行状态的自动采集和人工…

js 中 new Worker 报错 Failed to construct ‘Worker‘

new Worker("worker.js");运行多线程 Web Worker 的时候报错 Uncaught DOMException: Failed to construct ‘Worker’ 原因是浏览器不允许通过本地文件访问使用Web Worker。 解决方法&#xff1a; 将项目部署到服务器上或者用Node起本地服务访问项目

活动回顾|矩阵起源2024WAIC圆满落幕

2024年7月4日至7日&#xff0c;全球瞩目的2024世界人工智能大会暨人工智能全球治理高级别会议&#xff08;WAIC 2024&#xff09;在上海盛大举行&#xff0c;其中Future Tech 100未来之星创新孵化展再次成为大会焦点&#xff0c;它不仅是一场科技成果的展示&#xff0c;更是全球…

网络通信基本知识

网络通信 什么是网络通信&#xff1f; 通信网络是指将各个孤立的设备进行物理连接&#xff0c;实现人与人&#xff0c;人与计算机&#xff0c;计算机与计算机之间进行信息交换的链路&#xff0c;从而达到资源共享和通信的目的。 什么是网络协议&#xff1f; 网络协议是计算机…

SPring Boot整合第三方框架

springboot整合第三方框架 1. 整合mybatis 1.1引入依赖——pom.xml配置文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instanc…

安装isce2

今天再次尝试安装&#xff0c;之前试过2次都是卡在同一步&#xff0c;今天换成了用mamba conda就没有再报错了 全程参考云军老师的step by step教程&#xff0c;安装成功 GitHub - yunjunz/conda-envs: conda environment setup on Linux / macOS for InSAR data processing …

【进阶】利用python内置模块自动化发送邮件及邮件附件

目录 自动化发送邮件 流程&#xff1a; 步骤&#xff1a; 【重点】 【MIMEText--发送文本类型的邮件】 【MIMEImage-发送附件为图片的邮件】 【MIMEBase--发送附件为html报告的邮件】 自动化发送邮件 以qq邮箱为例&#xff0c;提前打开POP3/IMAP/SMTP/Exchange/CardDAV 服…