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命名空间中的a

cout<<"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;//加上 namespace
 cout<<a<<endl;
fun1();
fun1(1);
fun1(1,2);
return 0;
}

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

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

打印结果是0

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

int a=0;
int main(){
using namespace A;//加上 namespace

 cout<<a<<endl;

return 0;
}

error: reference to 'a' is ambiguous
  cout<<a<<endl;
        ^

加上作用域解决

int a=0;
int main(){
using namespace A;//加上 namespace

 cout<<A::a<<endl;//使用的是A中的a
 cout<<::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;error
    cout<<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);//10
    return 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;
}

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

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

相关文章

学习小记录——python函数的定义和调用

今日小好运&#xff0c;未来有好运。&#x1f381;&#x1f496;&#x1fad4; 分享个人学习的小小心意&#xff0c;一起来看看吧 函数的定义 函数通常来说就是带名字的代码块&#xff0c;用于完成具体的工作&#xff0c;需要使用的时候调用即可&#xff0c;这不仅提高代码的…

我的创作纪念日-砥砺前行

机缘 大家好&#xff0c;我是诊断协议那些事儿&#xff0c;又和大家见面了&#xff0c;记录一下创作日记&#xff0c;转眼间已经在CSDN平台创作三年了&#xff0c;最初仅仅是为了记录学习过程中的笔记&#xff0c;后来慢慢转为项目实践中的经验分享&#xff0c;当然更多的希望…

dm8 什么时候视图中统计的内存会超过OS

v$bufferpool和v$mem_pool视图记录着DMSERVER各组件的内存占用量。理论上跟OS看到的保持一致。但实际大多数场景下&#xff0c;OS中看到的数据远大于视图中的统计。这里面可能有内存泄漏的原因。不过也有的时候视图中的统计数据超过OS。下面就是这种情况&#xff1a; 上图中红线…

nas连接萤石云摄像机CTQ6X

需要准备的nassurveillance 请参考这个大佬的流程 https://www.bilibili.com/video/BV1ri4y1g7EN/ 踩坑&#xff1a; 一直到添加录像机验证一直没问题&#xff0c;但是验证一直不通过&#xff0c;后面下载了萤石云工作室的win桌面客户端&#xff0c;不知道是不是设置了预览还…

【Ubuntu】【Shell】执行sh脚本报错“xxx.sh:/bin/bash^M:解释器错误: 没有那个文件或目录“

背景 在自己Ubuntu环境执行sh脚本&#xff0c;报错"xxx.sh&#xff1a;/bin/bash^M&#xff1a;解释器错误: 没有那个文件或目录"&#xff0c;查了下是Ubuntu系统默认的shell是dash: 修改配置过下&#xff0c;变成bash 解决方案 在终端执行&#xff1a; sudo dp…

云队友:专业的远程工作和程序员接单平台,用户体验佳

编程赚钱的平台有不少&#xff0c;良莠不齐&#xff0c;今天给大家分享个专业的远程工作平台&#xff0c;以技术类工作为主&#xff08;包括编程&#xff09;&#xff1a; 云队友简介 外包大师是PMCAFF互联网产品社区于2016年推出的互联网产品技术外包服务平台。外包大师最新…

MyBatis 核心配置文件详细内容详解

1. MyBatis 核心配置文件详细内容详解 文章目录 1. MyBatis 核心配置文件详细内容详解2. 测试和学习的准备工作3. environment 标签4. transactionManager 标签5. dataSource 标签6. properties 标签7. mapper 标签8. 总结&#xff1a;9. 最后&#xff1a; 关于 MyBatis 这个核…

攻防世界---misc---2017_Dating_in_Singapore

1、题目描述 2、下载附件是一个pdf&#xff0c;里面是一个日历 3、题目描述是一些数字&#xff0c;直觉猜测是和日历的日期有关&#xff0c;仔细看题目的描述&#xff0c;会发现有个-连接&#xff0c;拆开之后发现一共有12组数据&#xff0c;再连联系到十二个月份&#xff0c;再…

音视频开发—FFmpeg播放YUV文件,YUV转换为JPEG操作

文章目录 1.使用命令行播放YUV数据1.1命令解析1.2参数说明 2.使用C语言实现将YUV数据转为JPEG图片格式2.1需求分析2.2读取YUV源文件2.3将YUV数据封装为AVFrame2.4将NV12 转换为YUV420平面格式2.5初始化MJPEG编码器2.6将YUV420P编码为JPEG2.7将编码数据写入图片文件2.8完整代码 …

从零开始实现自己的串口调试助手(4) -实现自动发送 / 时间显示

实现自动发送:checkBox 添加bool槽函数 bool 值&#xff0c;当√的时候为true 取消√ 位false 实现带bool 类型的槽函数: void Widget::on_checkBox_SendInTime_clicked(bool checked) {qDebug()<<"checkStatus:"<<checked;if(checked){ // 被勾选了//…

Python语言进阶学习

目录 一、类、对象和成员方法 二、构造方法 三、面向对象 &#xff08;1&#xff09;封装 &#xff08;2&#xff09;继承 单继承 多继承 复写 super&#xff1a;调用父类同名成员 &#xff08;3&#xff09;多态 &#xff08;4&#xff09;抽象类 五、Python操作…

Leecode---技巧---只出现一次的数字 / 多数元素

题解&#xff1a; 利用异或运算 a⊕a 0 的性质&#xff0c;可用来消除所有出现了两次的元素&#xff0c;最后剩余的即为所得。 class Solution { public:int singleNumber(vector<int>& nums){// 初始化为0int ans 0;for(int x: nums){// 异或操作ans ^ x;}retur…

Java循环结构while

1.while 是最基本的循环&#xff0c;它的结构为 while&#xff08;布尔表达式&#xff09;{ //循环内容 } 2.只要布尔表达式为true&#xff0c;循环就会一直执行下去 3.我们大多数情况是会让循环停止下来的&#xff0c;我们需要一个让表达式时效的方式来结束…

05C零碎语法

C零碎语法 目录 文章目录 C零碎语法1.函数指针2.回调函数3.数据拷贝3.1静态内存分配![请添加图片描述](https://img-blog.csdnimg.cn/direct/54d44e32bb7944f0866d4ca1e2667ce8.png)### 4.1动态内存分配 字符串6.sizeof()和strlen()的区别7.strcpy()/strncpy()函数7.1**strcp…

重生之 SpringBoot3 入门保姆级学习(16、函数式 Web 编程)

重生之 SpringBoot3 入门保姆级学习&#xff08;16、函数式 Web 编程&#xff09; 3.4 函数式 Web 3.4 函数式 Web 个人写过 go 类似于 go gin 框架 1、场景 场景: User RESTful - CRUD GET/user/1 获取1号用户GET/users 获取所有用户POST/user 清求体携带JSON&#xff0c;新…

【Tlias智能学习辅助系统】04 部门管理 删除 和 新增

Tlias智能学习辅助系统 04 部门管理 删除 和 新增 删除部门APIDeptController.javaDeptService.javaDeptServiceImpl.javaDeptMapper.java前端联调 新增部门API有一步简化DeptController.javaDeptService.javaDeptServiceImpl.javaDeptMapper.java前端联调 删除部门API 请求路径…

友善RK3399v2平台利用rkmpp实现硬件编解码加速

测试VPU 编译mpp sudo apt update sudo apt install gcc g cmake make cd ~ git clone https://github.com/rockchip-linux/mpp.git cd mpp/build/linux/aarch64/ sed -i s/aarch64-linux-gnu-gcc/gcc/g ./arm.linux.cross.cmake sed -i s/aarch64-linux-gnu-g/g/g ./arm.lin…

6月2号总结

刷题记录Codeforces Round 925 &#xff08;A,B,C&#xff09; 1.A. Recovering a Small String 问题 - A - Codeforces 输入&#xff1a; 5 24 70 3 55 48 输出&#xff1a; aav rzz aaa czz auz 给定一个3~78的整数&#xff0c;将这个整数分成a,b,c&#xff0c;其中1表示…

洛谷P2370yyy2015c01 的 U 盘

传送门——P2370 yyy2015c01 的 U 盘 题解&#xff1a;题目意思很好理解&#xff0c;就是说&#xff0c;当能够达到预期的U盘的最小接口&#xff08;接口越大&#xff0c;能传递的文件越大&#xff09;&#xff0c;然后我们就需要先看题目了&#xff0c;有n个文件&#xff0c;每…