C++对C的增强

1、作用域运算符

::解决归属问题(谁是谁的谁)
可以优先使用全局变量

在这里插入图片描述

2、命名空间

使用关键字namespace,控制标名称的作用域。

命名空间的本质:对符号常量、变量、函数、结构、枚举、类和对象等等进行封装

1、创建一个命名空间

#include <iostream>
using namespace std;
namespace A {
int data=10;
}
namespace B {
int data=20;
}
int main(){
cout<<"A::data"<<A::data<<endl;
cout<<"B::data"<<B::data<<endl;
return 0;
}

输出结果:

A::data10
B::data20

2、命名空间 只能定义在全局(重要)

在这里插入图片描述

3、命名空间可以嵌套

#include <iostream>
using namespace std;
namespace A {int data=10;namespace B {int data=20;
}
}int main(){cout<<"A::data"<<A::data<<endl;
cout<<"A::B::data"<<A::B::data<<endl;
return 0;
}

4、可以随时将新的成员加入命名空间

#include <iostream>
using namespace std;
namespace A {
int data=10;
}
//1000行代码后
namespace A {
void fun(void){cout<<"hello A"<<endl;
}
}int main(){cout<<"A::data"<<A::data<<endl;
A::fun();
return 0;
}

5、命名空间中函数的声明和实现分开

在命名空间内部声明,在外部实现

namespace B{
void fun1();
void fun2();
}void B::fun1(){cout<<"B中的fun1()"<<endl;}
void B::fun2(){cout<<"B中的fun2()"<<endl;
}

下面这种实现是错误的

namespace B{
void fun1();
void fun2();
}void fun1(){cout<<"B中的fun1()"<<endl;}
void fun2(){cout<<"B中的fun2()"<<endl;
}

6、无名命名空间

无名命名空间相当于static int a=10,只能在本文件下使用

namespace {
int a=10;
}int main(){
cout<<a<<endl;
return 0;
}

7、命名空间取别名

namespace B{
void fun1();
void fun2();
}

给B起别名为B2

namespace B2=B;
int main(){B2::fun1();
return 0;
}

8、使用using申明命名空间中的某几个成员可用

namespace A {
int data=10;
int a=100;
int b=200;
}
int main(){using A::a;//申明A命名空间中的acout<<"A命名空间中a="<<a<<endl;
return 0;
}

注:当在全局中使用时

using A::a;
int main(){int a=0;cout<<a<<endl;
return 0;
}

打印的是局部变量a=0

int main(){
using A::a;//可以看做局部变量
int a=0;cout<<a<<endl;
return 0;
}

程序报错

9、当using遇到函数重载

namespace A {
void fun1(){cout<<"fun1()"<<endl;
}
void fun1(int a){cout<<"fun1(int)"<<endl;
}
void fun1(int a,int b){cout<<"fun1(int,int)"<<endl;
}
}
int main(){
using A::fun1;//函数名即可
fun1();
fun1(1);
fun1(1,2);
return 0;
}

打印结果:

fun1()
fun1(int)
fun1(int,int)

10、using申明整个命名空间

using namespace std;
namespace A {
int a=100;
void fun1(){cout<<"fun1()"<<endl;
}
void fun1(int a){cout<<"fun1(int)"<<endl;
}
void fun1(int a,int b){cout<<"fun1(int,int)"<<endl;
}
}
int main(){
using namespace A;//加上 namespacecout<<a<<endl;
fun1();
fun1(1);
fun1(1,2);
return 0;
}

注:①当命名空间中与局部变量重名,先找局部变量

namespace A {
int a=100;
}
int main(){
using namespace A;//加上 namespaceint a=0;//当 命名空间中与局部变量重名,先找局部变量cout<<a<<endl;
return 0;
}

打印结果是0

②当命名空间中的变量与全局变量重名,程序报错

int a=0;
int main(){
using namespace A;//加上 namespacecout<<a<<endl;return 0;
}
error: reference to 'a' is ambiguouscout<<a<<endl;^

加上作用域解决

int a=0;
int main(){
using namespace A;//加上 namespacecout<<A::a<<endl;//使用的是A中的acout<<::a<<endl;//使用的是全局变量中的a
return 0;
}

所以当使用namespace时,不会和同名局部变量冲突,会和全局同名变量冲突

3、c++对c的增强

1、新增bool类型

2、结构体增强

结构体可以放函数,且给结构体赋值时可以省略struct

示例:

#include <iostream>
using namespace std;
struct student{int id;char name[30];void fun1(){cout<<"打游戏"<<endl;}
};
int main(){
student lucy={1,"lucy"};
cout<<"id:"<<lucy.id<<"name:"<<lucy.name<<endl;
lucy.fun1();return 0;
}

3、三目运算符增强

c++三目运算符返回值是引用,c语言返回的是值

int main(){
int a=10;
int b=20;
a>b?a:b=100;
cout<<"a="<<a<<"b="<<b<<endl;//三目运算符返回的是b=100,若是c中 则是10=100
return 0;
}

输出结果:a=10 b=100

4、c++的const 会对变量 优化

1、c++和c中的const都是修饰变量为只读。
2、c语言 严格准许 const修饰的是只读变量

但是在c语言中,可以通过指针对const的值进行修改

const int a=10;
int *p=(int *)&a;
*p=100;
3、c++的const 会对变量优化

1、如果以常量 初始化const修饰的变量 编译器会将变量的值 放入符号常量表中,不会立即给变量开辟空间

在这里插入图片描述

int main(){
const int a=10;
int *p=(int *)&a;
*p=100;
cout<<a<<endl;
return 0;
}

输出结果为10

2、只有当对a 取地址时 编译器才会给a开辟空间(只读变量)

int main(){
const int a=10;
int *p=(int *)&a;
*p=100;//只能修改*p所指向的值,并不能修改符号常量表中的值
cout<<a<<endl;//a=10
cout<<*p<<endl;//*p=100
return 0;
}

3、如果以变量 初始化const修饰的只读变量,没有符号常量表,立即开辟空间

int main(){int b=10;const int a=b;int *p=(int *)&a;*p=100;cout<<a<<endl;cout<<*p<<endl;
return 0;
}

输出结果:

100
100

4、如果以const修饰的是自定义类型的变量 也不会有符号常量表,立即开辟空间

#include <iostream>
#include <cstring>
using namespace std;struct STU{int num;char name[30];
};
int main(){const STU lucy={100,"lucy"};STU *p=(STU *)&lucy;p->num=20;strcpy(p->name,"lili");cout<<p->num<<endl;cout<<p->name<<endl;
return 0;
}

输出结果:

20
lili

5、c++中尽量使用 const代替define

①const有类型,可进行编译器类型安全检查。#define无类型,不可进行类型检查
②const有作用域,而#define不重视作用域,宏不能作为命名空间、结构体、类的
成员,而const可以

5、引用

引用的本质:就是给变量名取个别名。
引用定义的步骤:

1 &别名
2 给哪个变量取别名 就定义该变量
3 从上往下整体替换

①给普通变量起别名

int main(int argc, char *argv[])
{int a=10;int &num=a;cout<<"a="<<a<<endl;cout<<"num="<<num<<endl;int b=20;num=b;cout<<"a="<<a<<endl;cout<<"num="<<num<<endl;return 0;
}

打印结果:

a=10
num=10
a=20
num=20

②给数组起别名

int main(int argc, char *argv[])
{
int nums[5]={1,2,3,4,5};
int length=sizeof(nums)/sizeof(nums[0]);
int (&arr)[5]=nums;
for(int i=0;i<length;i++){
cout<<arr[i]<<" ";
}return 0;
}

打印结果:

1 2 3 4 5

③给指针变量取别名

int main(int argc, char *argv[])
{int a=10;
int *p=&a;
int* &num=p;
cout<<"*p="<<*p<<endl;
cout<<"*num="<<*num<<endl;return 0;
}

打印结果:

*p=10
*num=10

④给函数取别名

void fun1(void ){cout<<"fun1()"<<endl;
}int main(int argc, char *argv[])
{
void (&myfun)(void)=fun1;
myfun();return 0;
}

⑤作为函数参数

void swap(int &x,int &y){//通过引用实现交换函数int temp=x;x=y;y=temp;}int main(int argc, char *argv[])
{
int a=10,b=20;
swap(a,b);
cout<<"a="<<a<<"b="<<b<<endl;return 0;
}

节约空间

eg:

struct STU{int age;char name[6];
};void fun1(STU stu){//占空间cout<<stu.name<<stu.age<<endl;
}
void fun2(STU &stu){//不占空间cout<<stu.name<<stu.age<<endl;
}

⑤引用作为函数返回值

int& fun3(){int num=100;return num;//返回num 外界就是给num取别名
}int main(int argc, char *argv[])
{
int &b=fun3();//由于num是局部变量在函数执行结束后会回收,所以打印结果为空白
cout<<b<<endl;return 0;
}
int& fun3(){static int num=100;//使用static延长生命周期return num;//返回num 外界就是给num取别名
}int main(int argc, char *argv[])
{
int &b=fun3();为空白
cout<<b<<endl;return 0;
}

链式操作:

struct stut{stut& print_stut(stut &s,int age){cout<<age<<endl;return s;}
};int main(int argc, char *argv[])
{stut s1;
s1.print_stut(s1,100).print_stut(s1,200).print_stut(s1,300);return 0;
}

输出结果:

100
200
300

⑥常引用

给常量去别名

void test10()
2 {
3 //int &a = 10;//err
4 const int &a = 10;//a就是10的别名
5 //a = 100;//err 不能通过常引用修改内容
6 cout<<a<<endl;
7 }
void fun4(int &arg){//为了节约空间使用了引用arg=200;//但是却有被修改的风险cout<<arg<<endl;
}
int main(int argc, char *argv[])
{
int num=100;
fun4(num);return 0;
}

通过常引用避免这种风险

void fun4(const int &arg){//为了节约空间使用了引用
//    arg=200;errorcout<<arg<<endl;
}

⑦ 引用的本质

常量指针

int &b = a;//b为a的别名 
int * const b = &a;
b = 100;//a的值为100 *b = 100;

6、内联函数

内联函数:在编译阶段 将内联函数中的函数体 替换函数调用处。避免函数调用时的开销。
内联函数 必须在定义的时候 使用关键字inline修饰, 不能在声明的时候使用inline

int my_add(int x, int y);//函数声明时,不要使用inline//内联函数 在定义的时候使用inline
inline int my_add(int x, int y)
{
return x+y;
}
1、宏函数和内联函数的区别(重要背)

1、宏函数和内联函数 都会在适当的位置 进行展开避免函数调用开销。
2、宏函数的参数没有类型,不能保证参数的完整性。而内联函数的参数有类型 能保证参数的完整性。
3、宏函数在预处理阶段展开,内联函数在编译阶段展开
4、宏函数没有作用域的限制,不能作为命名空间、结构体、类的成员
内联函数有作用域的限制,能作为命名空间、结构体、类的成员

2、内联函数的注意事项

在内联函数定义的时候加inline修饰
类中的成员函数 默认都是内联函数(不加inline 也是内联函数)
有时候 就算加上inline也不一定是内联函数(内联函数条件)
不能存在任何形式的循环语句
不能存在过多的条件判断语句
函数体不能过于庞大
不能对函数取地址
有时候不加inline修饰 也有可能是内联函数。内不内联 由编译器决定。

7、函数重载

函数重载的条件:
同一作用域,函数的参数类型、个数、顺序不同 都可以重载。(返回值类型不能作为重载的条件)

void printFun(int a)
{
cout<<"int"<<endl;
}void printFun(int a, char b){cout<<"int char"<<endl;}void printFun(char a, int b){cout<<"char int"<<endl;
}
void printFun(char a){cout<<"char"<<endl;}void test02(){printFun(10);printFun(10, 'a');printFun('a', 10);printFun('a');
}

8、缺省参数

在函数声明处 给函数参数一个默认的值,如果函数调用处,用户没用传实参,编译器就可以使用这个默认的值。

void sub(int a,int b=10){cout<<"a-b="<<a-b<<endl;}int main(int argc, char *argv[])
{
sub(20);//10
sub(30,20);//10return 0;
}

注意:如果函数的某个参数设置为默认参数, 那么这个参数的右边的所有参数 都必须是默认参数.

案例:一下默认参数正确的是

int func(int a, int b, int c=10);//正确
int func(int a, int b=20, int c);//错误 c必须默认参数
int func(int a=10, int b, int c);//错误 b c必须默认参数
int func(int a, int b=10, int c=20);//正确
int func(int a=10, int b, int c=20);//错误 b必须默认参数
int func(int a=10, int b=20, int c=20);//正确

缺省参数和函数重载同时出现 一定要注意二义性

void sub(int a){cout<<"a="<<a<<endl;
}void sub(int a,int b=10){cout<<"a-b="<<a-b<<endl;}int main(int argc, char *argv[])
{
sub(20);//上面两个函数都可以调用,出现二义性
return 0;
}

9、占位参数

//没有形参名的形参,叫占位参数void sub(int a,int ){cout<<"a="<<a<<endl;
}
int main(int argc, char *argv[])
{
sub(20,10);return 0;
}

占位参数 也可以是缺省参数(默认参数)

void sub(int a,int=10 ){cout<<"a="<<a<<endl;}int main(int argc, char *argv[])
{
sub(20,10);return 0;
}

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

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

相关文章

Go 语言中的指针

在许多现代编程语言中&#xff0c;如 Java 和 .NET&#xff0c;程序员通常无法直接控制底层的内存管理。然而&#xff0c;Go 语言提供了这样的能力&#xff0c;同时限制了可能导致错误的操作&#xff0c;比如指针运算。 文章目录 1、Go 语言中指针的介绍1.1、什么是指针&#x…

图解DSPy:Prompt的时代终结者?!

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调重新阅读。而最新科技&#xff08;Mamba&#xff0c;xLSTM,KAN&#xff09;则提供了大模…

时序动作定位 | PivoTAL:弱监督时间动作定位的先验驱动监督(CVPR 2023)

<PivoTAL: Prior-Driven Supervision for Weakly-Supervised Temporal Action Localization> 论文:PivoTAL: Prior-Driven Supervision for Weakly-Supervised Temporal Action Localization (thecvf.com) 创新点: 定位驱动的监督框架:定位视角:文章提出的PivoTAL方法…

chap6 RNN

循环神经网络&#xff08;RNN&#xff09; 问题描述&#xff1a; 利用循环神经网络&#xff0c;实现唐诗生成任务 数据集&#xff1a; 唐诗 题目要求&#xff1a; 补全程序&#xff0c;主要是前面的3个空和生成诗歌的一段代码&#xff0c;pytorch需要补全对应的rnn.py文件…

多元联合分布建模 Copula python实例

多元联合分布建模 Copula python实例 目录 库安装 实例可视化代码 库安装 pip install copulas 实例可视化代码 import numpy as np import pandas as pd from copulas.multivariate import GaussianMultivariate# Generate some example data np.random.seed(42) data = …

ChatTTS:开源最强文本转真人语音工具

目录 1.前言 2.详细介绍 2.1 什么是ChatTTS 2.2 项目地址: 2.3 应用特点: 3.如何安装和使用 3.1.谷歌colab 3.1.1.点击链接 3.1.2 进行保存 3.1.3 按照流程依次点击运行 3.1.4 填写自己需要转的文字 3.2 本地运行 3.2.1 下载或克隆项目源码到本地 3.2.2 …

算法每日一题(python,2024.05.31)

题目来源&#xff08;力扣. - 力扣&#xff08;LeetCode&#xff09;&#xff0c;简单&#xff09; 解题思路&#xff1a; 二次遍历&#xff0c;第一次遍历用哈希表记录每个字母的出现次数&#xff0c;出现一次则将它的value值赋为True&#xff0c;将它的下标赋为key值&#x…

HTTPS加密

一.加密是什么 加密就是把明文(要传输的信息)进行一系列的变换,生成密文. 有加密就有解密,解密就是把密文进行一系列的变换,生成明文. 在这个加密和解密过程中,往往需要一个或多个中间数据,辅助进行这个过程,这样的数据称为密钥. 加密解密到如今已经发展成了一个独立的学科 : 密…

基于Springboot开发的外卖餐购项目(后台管理+消费者端)

免费获取方式↓↓↓ 项目介绍039&#xff1a; 系统运行 后端登录页: http://localhost:8081/backend/page/login/login.html 消费端请求:消费端主页: http://localhost:8081/front/index.html 管理员账号 admin 123456 消费者不需要登录 采用技术栈 前端&#xff1a;Eleme…

力扣20 有效的括号

给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括…

8月编程语言排行榜:揭秘热门语言背后的力量与魅力

8月编程语言排行榜&#xff1a;揭秘热门语言背后的力量与魅力 随着技术的不断进步和创新&#xff0c;编程语言的世界也在不断变化和演进。每年的8月&#xff0c;全球知名编程社区TIOBE都会公布最新的编程语言排行榜&#xff0c;为我们揭示了哪些语言正在引领着技术的潮流。在这…

【智能算法】红嘴蓝喜鹊优化算法(RBMO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;S Fu受到自然界中红嘴蓝喜鹊社会行为启发&#xff0c;提出了红嘴蓝喜鹊优化算法&#xff08;Red-billed Blue Magpie Optimizer, RBMO&#xff09;。 2.算法原理 2.1算…

MicroBlaze 处理器参考指南

概述 本章包含MicroBlaze功能的概述和详细信息MicroBlaze架构包括Big-Endian或Little-Endian位反转格式&#xff0c;32位或64位通用寄存器&#xff0c;虚拟内存管理&#xff0c;缓存软件支持&#xff0c;和AXI4-Stream接口 简介 MicroBlaze嵌入式处理器软核是一个精简指令集…

[JS] 前端充分使用console.log()有效输出(2024-6-1)

将变量包装在对象中 不要使用 console.log(url, url2, baz)&#xff0c;而是使用 console.log({ url, url2, baz })。 如果你比较这两者&#xff0c;你会发现这有多么有用&#xff1a;拥有 url 和 url2 键可以避免这两个 URL 之间的混淆。 在日志前加上唯一字符串前缀 在应用…

PCL 指数函数回归(二维)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 指数回归与之前所提到的线性回归类似,我们只需要变换一下指数的形式,如下所示: y = a ∗ e b x y = a * e^{bx}

开箱即用的Spring Boot 企业级开发平台【毕设项目推荐】

项目概述 基于 Spring 实现的通用权限管理平台&#xff08;RBAC模式&#xff09;。整合最新技术高效快速开发&#xff0c;前后端分离模式&#xff0c;开箱即用。 核心模块包括&#xff1a;用户、角色、职位、组织机构、菜单、字典、日志、多应用管理、文件管理、定时任务等功能…

牛客网刷题 | BC107 箭形图案

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 KiKi学习了循环&am…

【计算机毕业设计】359微信小程序校园失物招领系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Qt | QFile 类(文件)

01、QFile简介 一、QFile 基本原理 1、QFile 基础 ①、QFile 类继承自 QFileDevice 类,QFileDevice 又继承自 QIODevice类。 ②、QFile 类提供了一个用于读取/写入文件的接口,是一种读写二进制文件、文本、资源的 I/O 设备。 ③、默认情况下 QFile 假定为二进制,即不对存…

WebClient 快速入门 (使用 WebClient 发起 HTTP 请求)

1.简介 执行异步 HTTP 请求&#xff1a;WebClient 允许你发送 GET、POST、PUT、DELETE 等各种 HTTP 请求&#xff0c;并且这些请求都是异步的&#xff0c;不会阻塞调用线程。 处理响应&#xff1a;你可以使用 WebClient 来处理 HTTP 响应&#xff0c;包括获取响应体、响应头和…