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,一经查实,立即删除!

相关文章

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

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

多元联合分布建模 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; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括…

【智能算法】红嘴蓝喜鹊优化算法(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 之间的混淆。 在日志前加上唯一字符串前缀 在应用…

开箱即用的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…

Android学习之ION memory manager

目录 what is ION? ION原理 ION数据结构 用户空间 API ION API what is ION? ION是Google的内存管理器&#xff0c;用来支持不同的内存分配机制&#xff0c;如CARVOUT(PMEM)&#xff0c;物理连续内存(kmalloc), 虚拟地址连续但物理不连续内存(vmalloc)&#xff0c; IOM…

智慧校园的应用场景有哪些

在21世纪的教育挑战中&#xff0c;如何利用科技手段优化教育资源分配&#xff0c;提升教学质量&#xff1f;智慧校园给出了答案。基于信息化的教育改革&#xff0c;智慧校园不仅提升了校园管理的效率&#xff0c;更通过一系列智能化应用&#xff0c;重塑了教学、学习和交流的方…

搭建大型分布式服务(三十八)SpringBoot 整合多个kafka数据源-支持protobuf

系列文章目录 文章目录 系列文章目录前言一、本文要点二、开发环境三、原项目四、修改项目五、测试一下五、小结 前言 本插件稳定运行上百个kafka项目&#xff0c;每天处理上亿级的数据的精简小插件&#xff0c;快速上手。 <dependency><groupId>io.github.vipjo…

多个短视频剪辑成一个视频:四川京之华锦信息技术公司

多个短视频剪辑成一个视频&#xff1a;创作中的艺术与技术 在数字时代&#xff0c;短视频以其短小精悍、内容丰富的特点&#xff0c;迅速成为社交媒体上的热门内容形式。然而&#xff0c;有时单一的短视频难以完全表达创作者的意图或满足观众的观赏需求。因此&#xff0c;将多…

【Qt秘籍】[007]-LineEdit Pushbutton控件

Qt的中有着各种各样的控件&#xff0c;相较于传统C/C的输出默认只能在控制台实现&#xff0c;Qt中可以有不同的接口实现各种不同的功能&#xff0c;下面我们将实现不同功能的输出 hello world&#xff01; 标签Label 【Qt秘籍】[006]-Label实现Hello World程序-编程第一步-CSD…

C语言王国——内存函数

目录 1 memcpy函数 1.1 函数表达式 1.2 函数模拟 2 memmove函数 2.1 函数的表达式 2.2 函数模拟 3 memset函数 3.1 函数的表达式 3.2 函数的运用 4 memcmp函数 4.1函数的表达式&#xff1a; 4.2 函数的运用 5 结论 接上回我们讲了C语言的字符和字符串函数&#…

MAC帧

基本问题 数据链路层的协议有很多&#xff0c;但是都有三个基本问题&#xff1a;封装成帧&#xff0c;透明传输和差错检测。 封装成帧 封装成帧&#xff08;Framing&#xff09;就是在一段数据的前后分别添加首部和尾部&#xff0c;这样就构成了一个帧。帧是数据链路层的传送…