当前位置: 首页 > news >正文

【C++初阶】C++入门

1、C++第一个程序

C++是脱胎于C语言的,所以也包含了C语言绝大多数的内容,C++兼容C语言绝大多数的语法,在C语言中能实现的程序在C++中也是可以执行的,但需要将定义文件代码的后缀改为.cpp

就比如hello world程序

// test.cpp
#include<stdio.h>
int main()
{
printf("hello world\n");
return 0;
}

但在C++中,它是自成体系的,有自己的输入输出 c++版的hello world程序为

#include<iostream>
using namespace std;int main()
{cout<<"hello world\n"<<endl;return 0;
}
初学C++的小伙伴出看见这个代码会有很多疑惑,但不要慌张,接下来让我来为你详细解释

2、命名空间:namespace

在看很多书上的C++代码都很看到这样的一行代码“using namespace std;”,

都会疑惑namespace是什么?在这里有什么作用?
不要急,我们慢慢来

我们要知道在C语言中我们经常会因为变量和函数的命名冲突而感到困惑,而我们的C++的祖师爷可能也是深受它的毒害吧,就创造了一个新概念,叫做命名空间(namespace)

使用命名空间的目的就是对标识符的名称进⾏本地化,以避免命名 冲突或名字污染namespace关键字的出现就是针对这种问题的

namespace的定义

1、

定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中

即为命名空间的成员。命名空间中可以定义变量/函数/类型

namespae 空间名
{}

命名空间的本质,在C语言中我们学过了全局域和局部域,而我们在C++中学习的命名空间这个域独立于全局域,又因为不同的域可以定义同名的变量,在这里我们也可以知道,命名空间域中的变量也和全局变量一样,只有在程序结束后才会结束生命周期

总结就是:命名空间域内的变量和全局变量类似
命名空间会影响编译查找变量的规则,使得C++中查找规则是:先查找局部域,在查找全局域,一般不会在命名空间中查找

2、

namespace只能定义在全局域中,而且它还可以嵌套定义:就是在一个namespace中再定义一个namespace(可以无限套娃,但最多嵌套两三次就足够了)

这里的嵌套定义就类似于一个公司里面有很多部门,每个部门就相当于一个namespace,而每个部门里面又有很多员工,每个员工又是一个独立的namespace

嵌套定义后使用命名空间就需要由外向里的进行寻找

3、

多个文件中定义了多个同名的namespace的时候,并不会发生冲突,它会自动合并为一个命名空间

4、

C++的标准库都放在std的命名空间中,这就是为什么许多C++代码都会有“using namespace std;

namespace的使用

1、指定命名空间访问(项目中推荐使用)
2、using将命名空间中的某个成员展开,这适用于项目中经常使用而且不存在冲突的成员
3、using将命名空间中全部的成员展开,这种方法在项目中不推荐使用,而且当出现多个using的展开可能会出现冲突
using n::b;
int main()
{printf("%d ",n::a);//指定命名空间访问 printf("%d ",b);//using将命名空间中的某个成员展开   return 0;
}

using namespace n;//展开命名空间中的全部成员int main()
{printf("%d",a);return 0;
}

3、C++的输入输出

<iostream> 是 Input Output Stream 的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输出对象。

std::cin 是 istream 类的对象,它主要⾯向窄字符(narrow characters (of type char))的标准输入流。

std::cout 是 ostream 类的对象,它主要⾯向窄字符的标准输出流。

std::endl 是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区。

<<是流插⼊运算符,>>是流提取运算符。(C语⾔还⽤这两个运算符做位运算左移/右移)

使⽤C++输⼊输出更⽅便,不需要像printf/scanf输⼊输出时那样,需要⼿动指定格式,C++的输⼊

输出可以⾃动识别变量类型(本质是通过函数重载实现的,这个以后会讲到),其实最重要的是

C++的流能更好的⽀持⾃定义类型对象的输⼊输出。

IO流涉及类和对象,运算符重载、继承等很多⾯向对象的知识,这些知识我们还没有讲解,所以这

⾥我们只能简单认识⼀下C++ IO流的⽤法,后⾯我们会有专⻔的⼀个章节来细节IO流库。

cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要 通过命名空间的使⽤⽅式去⽤使用它们

4、缺省参数(默认参数)

缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值,也就是给函数的形参一个默认值。在调用该函数时,如果没有给明实参就采用该形参的默认值(缺省值)否则就使用给明的实参

缺省参数又分为全缺省半缺省参数
全缺省:函数的全部形参都给缺省值
半缺省:就是部分形参给缺省值

C++规定半缺省参数必须从右往左依次连续缺省,不能中间跳跃给实参;而且带缺省参数的函数调用时,C++规定必须从左往右依次给实参,不能跳跃给实参

缺省参数不能在函数声明和定义中同时出现,且规定必须函数声明给缺省值
#include <iostream>
using namespace std;void Func(int a = 0)
{cout << a << endl;
}
int main()
{Func(); // 没有传参时,使⽤参数的默认值Func(10); // 传参时,使⽤指定的实参return 0;
}

#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
int main()
{Func1();Func1(1);Func1(1,2);Func1(1,2,3);Func2(100);Func2(100, 200);Func2(100, 200, 300);return 0;
}

5、函数重载

C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者 类型不同。这样C++函数调⽤就表现出了多态⾏为,使⽤更灵活。C语⾔是不⽀持同⼀作⽤域中出现同名函数的。

函数重载主要是根据形参来进行区别
1、形参类型不同
2、形参个数不同
3、形参顺序不同
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}

这里要注意的是返回值不同的同名函数不构成重载,编译器无法进行区分

int f(int a)
{cout << "f(int a)" << endl;return 0;
}void f(int a)
{cout << "f(int a)" << endl;
}int main()
{f(10);f();return 0;
}

在多个同名函数中,其中有函数中含有缺省参数时我,虽然在传参时构成重载,但是在不传参时会发生编译错误,因为编译器不知道应该调用哪个函数(这里就涉及到了二义性

void f1()
{cout << "f()" << endl;
}
void f1(int a = 10)
{cout << "f(int a)" << endl;
}
int main()
{f();f(10);return 0;
}

6、引用

C++中引入了一个新的概念叫做:引用,引用顾名思义就是用别人的,而不是自己的,所以,引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间,它和它引⽤的变量共⽤同⼀块内存空间(在这里是是指代语法层)。

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

引用的特性

1、引用在定义时必须初始化;

2、一个变量可以有多个引用;

3、引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体

int main()
{int a = 0;// 引用:b和c是a的别名int& b = a;int& c = a;// 也可以给别名b取别名,d相当于还是a的别名int& d = b;++d;// 编译报错:“ra”: 必须初始化引用//int& ra;int* c = &a;int*& rc = c;//指针也可以取别名// 这里取地址我们看到是一样的cout << &a << endl;cout << &b << endl;cout << &c << endl;cout << &d << endl;int x = 10;d = x;//在这里是赋值拷贝return 0;
}

引用的使用

引用的实践主要是在引用传参引用做返回值两个方面

引用传参:

引用传参跟指针传参功能是类似的,它其实就是代替了指针的传址,而且也不需要像指针一样要解引用和取地址,并且引用不需要开辟空间,减少了拷贝,极大地提高了效率

//引用传参
void Swap(int& ra, int& rb)
{int temp = ra;ra = rb;rb = temp;
}
int main()
{int a = 1, b = 2;printf("a=%d,b=%d\n", a, b);Swap(a, b);printf("a=%d,b=%d\n", a, b);return 0;
}

引用做返回值:

引用做返回值本质是:不会生成临时变量,直接返回对象别名(这里的别名指的是给被引用对象所处空间起的别名)
在引用做函数返回值时,函数结束后函数栈帧会被销毁,却不会影响实参及其别名所处的空间,所以用引用做返回就能起到指针传址调用一样的作用,改变实参

typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;
void STInit(ST& rs, int n = 4)//在这里也是用到引用传参
{rs.a = (STDataType*)malloc(n * sizeof(STDataType));rs.top = 0;rs.capacity = n;
}// 栈顶
void STPush(ST& rs, STDataType x)
{//assert(ps);// 满了, 扩容if (rs.top == rs.capacity){printf("扩容\n");int newcapacity = rs.capacity == 0 ? 4 : rs.capacity * 2;STDataType* tmp = (STDataType*)realloc(rs.a, newcapacity *sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}rs.a = tmp;rs.capacity = newcapacity;}rs.a[rs.top] = x;rs.top++;
}
/*引用做返回值*/
int& STTop(ST& rs)
{//assert(rs.top > 0);return rs.a[rs.top - 1];
}int main()
{ST s;STInit(s);STPush(s, 1);STPush(s, 2);STPush(s, 3);STPush(s, 4);//传值/*int top = STTop(s);top+=10;cout << top << endl;*///引用传参/*STTop(s) += 10;cout << STTop(s) << endl;*/return 0;
}

在这里是使用传值返回,在C/C++中规定,返回类型除引用以外,返回对象是先存储在一个临时变量(或者寄存器)当中,再由临时变量传到主函数中,临时变量的建立需要开辟空间,再由主函数中建立一块空间接收,所以主函数中就需要在建立一个同类型变量接收临时变量的值 

/*传值*/
int STTop(ST& rs)
{return rs.a[rs.top - 1];
}

错误示范,不能返回局部对象的引用 

在该函数结束后,函数栈帧销毁,top也会被销毁,这时的别名就会像free(指针)后,没有给指针置空一样,成为野别名
虽然编译器不会报错,但是也无法实现功能

int& STTop(ST& rs)
{int top = rs.a[rs.top - 1];return top;
}

const引用

可以引用一个const对象,但必须const引用,这里就涉及了权限的平移const->const

const int a=1;
const int& ra=a;//权限的平移

const引用也可以引用普通对象,这里就涉及了权限的缩小由变量变为常量

int a=10;
const int& ra=a;
//权限的缩小

但权限不能放大

const int& a=1;
int& ra=a;//错误

在对象权限的访问中,权限可以平移、缩小,但不能放大 ,这里的对象指的是指针和引用

临时变量(临时对象 )

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

C++中把这个未命名对象叫做临时对象

被引用对象为常量表达式类型不同(会涉及到类型转换)时要用到临时变量,而C++规定临时对象具有常性,所以这⾥就触发了权限放⼤,必须要⽤常引⽤(const才可以。

int main()
{//临时变量的常性(具有const的属性)//常量//int& x = 10;//错误的,要引用一个常量,就要在前面加一个constconst int& x = 10;cout << x << endl;//表达式int p = 2;//错误//int& rp = p*2;//在这里就涉及到了临时变量//p*2的和存储在一个临时变量里面,而临时变量具有const属性,//所以接收值也应该具有const属性,就需要在前面加一个const(都是涉及权限的放大)const int& rp = p*3;cout << rp << endl;//类型不同double d = 1.1;//int& rd = d;//在这里值也是存储在一个临时变量当中,所以也要用const来接收(都是涉及权限的放大)const int& rd = d;cout << d << endl;return 0;
}

当我们在函数传参,用到引用的时候,传入的值就如上面的三种情况时就需要用const引用了 

在现在学习到的场景下,类型转换传值返回会用到临时对象

指针与引用的关系

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

1、

语法概念上引⽤是⼀个变量的取别名不开空间,指针是存储⼀个变量地址,要开空间。但在汇编层面上,其实引用还是以指针的形式运行的

2、

引⽤在定义时必须初始化,指针建议初始化,但是语法上不是必须的。

3、

引⽤在初始化时引⽤⼀个对象后,就不能再引⽤其他对象;⽽指针可以在不断地改变指向对象。

4、

引⽤可以直接访问指向对象,指针需要解引⽤才是访问指向对象。

5、

sizeof中含义不同,引⽤结果为引⽤类型的⼤⼩,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位下是8byte)

6、

指针很容易出现空指针和野指针的问题,引⽤很少出现,引⽤使⽤起来相对更安全⼀些。

7、nullptr

在C语言中NULL其实是一个头文件为(stddef.h)

#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif

由代码可得C++中NULL可能被定义为0或者被定义为无类型(void*)的常量

void f(int x)
{cout << "f(int x)" << endl;
}void f(int* ptr)
{cout << "f(int* ptr)" << endl;
}int main()
{//f(NULL);   // 调用这个函数时原本要为f(int* ptr),但因为被定义为0,所以结果为f(int x),错误//f((void*)0); // 该函数调用会报错f(nullptr);return 0;
}

所以在C++11中引入了nullptr,它是一个特殊关键字,他可以转换成任意类型的指针类型,使用它可以避免类型转换的问题,因为它可以隐式转换为指针类型,而不会转换为整数类型

相关文章:

【C++初阶】C++入门

1、C第一个程序 C是脱胎于C语言的&#xff0c;所以也包含了C语言绝大多数的内容&#xff0c;C兼容C语言绝大多数的语法,在C语言中能实现的程序在C中也是可以执行的&#xff0c;但需要将定义文件代码的后缀改为.cpp 就比如hello world程序 // test.cpp #include<stdio.h&g…...

自然推理系统:的拒取式的解析

要推导出 **"非A"** 的拒取式 (rejection form)&#xff0c;首先我们要理解逻辑推理中几个基本的概念。 假设我们有以下前提&#xff1a; 1. **A → B** &#xff08;如果A成立&#xff0c;那么B成立&#xff09; 2. **非B** &#xff08;B不成立&#xff09; 我们…...

OceanBase 分区表详解

1、分区表的定义 在OceanBase数据库中&#xff0c;普通的表数据可以根据预设的规则被分割并存储到不同的数据区块中&#xff0c;同一区块的数据是在一个物理存储上。这样被分区块的表被称为分区表&#xff0c;而其中的每一个独立的数据区块则被称为一个分区。 如下图所示&…...

Java中 LinkedList<>,ArrayDeque<>的区别 || Queue和Deque的区别

我是你爹 LinkedList<> 和 ArrayDeque<> 的区别Queue接口 和 Deque接口区别Queue 的用法Deque 的用法 LinkedList<> 和 ArrayDeque<> 的区别 1. 数据结构实现方式&#xff1a; LinkedList&#xff1a; 基于链表结构&#xff0c;是一个双向链表。每个…...

freemarker 读取template.xml ,通过response 输出文件,解决中文乱码问题

采用 try (Writer writer new OutputStreamWriter(os, “UTF-8”)) UTF-8 内容转换 public static void setResponseHeader(HttpServletResponse response, String fileName) {try {// fileName "中文.xls";try {fileName new String(fileName.getBytes(),"…...

arkUI:水果选择与管理:基于 ArkUI 的长按编辑功能实现

水果选择与管理&#xff1a;基于 ArkUI 的长按编辑功能实现 1 主要内容说明2 相关内容2.1 相关内容2.1.1 源码1内容的相关说明2.1.1.1 数据结构与状态管理2.1.1.2 添加水果功能2.1.1.3 水果列表展示2.1.1.4 长按进入编辑模式2.1.1.5 复选框的多选功能2.1.1.6 删除水果功能2.1.1…...

docker使用,docker图形化界面+docker详细命令

DockerUI进入 docker container run --rm --name docker.ui -v /var/run/docker.sock:/var/run/docker.sock -p 8999:8999 joinsunsoft/docker.ui访问8999端口就行&#xff0c;就可以图形化管理Docker了 常规使用 搭建 sudo docker-compose build #有一些需要这条命令 su…...

idea项目运行时 java: 错误: 不支持发行版本 21

java项目运行时&#xff0c;同样的项目别的都是正常运行&#xff0c;单个这个项目一直报 java: 错误: 不支持发行版本 21&#xff0c; 报错的解释 这个错误表明你正在尝试使用Java编译器编译一个类&#xff0c;但是编译器遇到了一个它不支持的版本号&#xff0c;在这个上下文…...

hive alter table add columns 是否使用 cascade 的方案

结论 alter table xxx add columns 时加上 cascade 时&#xff0c;会把所有的分区都加上此字段。如果不加则只有新的分区会加上此字段&#xff0c;旧的分区没有此字段&#xff0c;即便数据文件里有对应的数据&#xff0c;也不能显示内容。 如果分区都是 insert overwrite 生成…...

手机怎么玩steam游戏?随时随地远程串流玩steam游戏教程

喜欢在steam上玩游戏的玩家有没有想过&#xff0c;其实这些游戏也能在手机上玩呢&#xff1f;不管是探索的开放世界游戏&#xff0c;还是紧张刺激的射击游戏&#xff0c;还是丰富剧情的视觉小说等等&#xff0c;这些游戏你都可以通过远程串流软件&#xff0c;来帮你实现在手机上…...

【使用antv g6实现拓扑图】

使用antv g6实现拓扑图 安装antv g6创建一个 div&#xff0c;并制定必须的属性 id定义初始化方法定义node节点数据将获取到的数据渲染进页面 安装antv g6 npm install antv/g6 --save import G6 from antv/g6;创建一个 div&#xff0c;并制定必须的属性 id 定义好展示id&…...

【数学 函数空间】拉普拉斯变换解微分方程步骤

拉普拉斯变换解微分方程 拉普拉斯变换解微分方程的一般步骤如下&#xff1a; 写出微分方程。对微分方程两边应用拉普拉斯正变换。求解变换后的代数方程&#xff0c;得到 Y ( s ) Y(s) Y(s)。如果需要&#xff0c;进行部分分式分解。对 Y ( s ) Y(s) Y(s)进行拉普拉斯逆变换&…...

vue3: toRef, reactive, toRefs, toRaw

vue3&#xff1a; toRef, reactive, toRefs, toRaw <template><div>{{ man }}</div><hr><!-- <div>{{ name }}--{{ age }}--{{ like }}</div> --><div><button click"change">修改</button></div&g…...

Unity读取Json

参考 Unity读取Json的几种方法_unity读取json文件-CSDN博客...

基于STM32的智能语音识别饮水机系统设计

功能描述 1、给饮水机设定称呼&#xff0c;喊出称呼&#xff0c;饮水机回答&#xff1a;我在 2、语音进行加热功能&#xff0c;说&#xff1a;请加热&#xff0c;加热片运行 3、饮水机水位检测&#xff0c;低于阈值播报“水量少&#xff0c;请换水” 4、检测饮水机水温&#xf…...

c++的几种构造函数

c的几种构造函数 构造函数拷贝构造函数转换构造函数移动构造函数 析构函数 构造函数 C中的构造函数可以分为5类&#xff1a;默认构造函数、普通构造函数、拷贝构造函数、转换构造函数、移动构造函数。 好像还有委托构造 默认构造和普通构造和java基本一样 详细 拷贝构造函…...

FRP 实现内网穿透

如何通过 FRP 实现内网穿透&#xff1a;群晖 NAS 的 Gitea 和 GitLab 访问配置指南 在自建服务的过程中&#xff0c;经常会遇到内网访问受限的问题。本文将介绍如何利用 FRP&#xff08;Fast Reverse Proxy&#xff09;来实现内网穿透&#xff0c;以便在外网访问群晖 NAS 上的…...

数据结构笔记(其八)--一般树的存储及其遍历

1.知识总览 一般的树会有多个孩子&#xff0c;所以存储结构也会与二叉树略有不同。 一般树的遍历。 2.双亲表示法 双亲表示法&#xff0c;也是父亲表示法&#xff0c;即每个节点中都存储了其父节点的地址信息。 特性&#xff1a;可以轻易地找到父节点&#xff0c;但寻找孩子节…...

在spring boot工程中使用Filter时,@WebFilter 注解不生效的问题分析和解决方案

1. 问题描述 首先编写一个Filter类并通过Component放入spring容器中&#xff0c;通过实现jakarta.servlet中提供的Filter接口完成过滤器的创建&#xff0c;代码如下。 import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter; import org.springframework.st…...

浅谈“通感一体”

文章目录 5G_Advanced的关键技术通感一体的介绍通感一体应用通感一体面临的挑战 5G_Advanced的关键技术 2024年6月18日16点30分&#xff0c;在上海举行的3GPP RAN第104次会议上&#xff0c;R18标准正式冻结&#xff0c;标志着5G技术的又一重要里程碑。值得注意的是&#xff0c…...

不止是‘小电脑’:用树莓派4B+Python+传感器,手把手打造你的第一个智能家居原型

从零构建智能家居中枢&#xff1a;树莓派4B实战指南 当一块信用卡大小的电路板能够控制你家的灯光、监测室内环境并自动调节空调时&#xff0c;传统家电的边界就被彻底打破了。树莓派4B以其不到400元的售价和完整的计算机架构&#xff0c;正在重新定义智能家居的入门门槛。本文…...

WLED与xLights打造音乐同步LED灯光秀:从硬件连接到创意编排

1. 项目概述&#xff1a;从独立闪烁到交响乐章如果你玩过像NeoPixel这类可单独寻址的LED灯带&#xff0c;肯定体验过那种让灯光随心所欲流动的快感。但不知道你有没有想过&#xff0c;把这些闪烁的光点从简单的循环动画&#xff0c;升级成一场能与音乐节拍精准共舞、充满叙事感…...

从芯片到系统:手把手拆解汽车MCU里的安全硬件(SHE/HSE)与独立HSM如何协作

汽车MCU安全架构实战&#xff1a;SHE/HSE与独立HSM的协同设计指南 当一辆现代汽车启动时&#xff0c;从车门解锁到发动机控制&#xff0c;超过1亿行代码在数百个微控制器&#xff08;MCU&#xff09;上同时运行。这些代码中包含着价值连城的数字资产——车主的生物特征数据、自…...

当贝盒子H5 64G版618首销TOP1!多平台登顶,凭什么这么火?

2026年5月14日&#xff0c;当贝官方发布了618抢先购首日当贝盒子H5 64G版的首销战报。据官方数据显示&#xff0c;这款重磅升级的电视盒子在京东、天猫、抖音三大主流电商平台的电视盒子类目热销榜中&#xff0c;全部拿下TOP1席位&#xff0c;成为今年618大促第一天的现象级爆款…...

G101EVT05.1友达液晶屏10.1寸LCD工业电阻触摸液晶屏幕

G101EVT05.1 G101EVT05.1是友达AUO的一款10.1英寸工业触摸液晶屏模组。公开资料显示&#xff0c;这款屏采用1280800分辨率、16:10比例、400cd/m典型亮度、LVDS接口、WLED背光、投射式电容触摸屏PCAP&#xff0c;整体更偏向工业平板、HMI、人机界面、医疗终端、嵌入式控制设备&a…...

告别日志脱敏烦恼:手把手教你用sensitive注解优雅保护用户隐私数据

优雅实现日志脱敏&#xff1a;基于注解的隐私数据保护实战指南 在金融、电商等强合规领域&#xff0c;用户隐私数据保护早已从"可选"变为"必选"。每次看到同事在代码中手动拼接"手机号&#xff1a;"user.getPhone().substring(0,3)"****&qu…...

从单机到联网:手把手教你用NetCA为Oracle数据库配置‘电话线’(监听程序与本地网络服务)

从单机到联网&#xff1a;手把手教你用NetCA为Oracle数据库配置‘电话线’ 想象一下&#xff0c;你刚搬进一栋新公寓&#xff0c;已经熟悉了家里的水电开关&#xff08;本地Oracle安装&#xff09;&#xff0c;但还没登记电话号码&#xff08;监听程序&#xff09;和录入邻居联…...

C语言编程入门:从变量、运算符到控制流与实战计算器

1. 项目概述&#xff1a;为什么C语言是程序员的“内功心法”&#xff1f;如果你刚刚完成“系列&#xff08;一&#xff09;”的安装和环境配置&#xff0c;恭喜你&#xff0c;你已经迈出了从“电脑使用者”到“程序创造者”最关键的一步。很多新手会问&#xff0c;现在有那么多…...

CBAM注意力机制:为什么它比SENet更胜一筹?深入对比通道与空间注意力设计

CBAM注意力机制&#xff1a;通道与空间双重视角下的性能突破 在计算机视觉领域&#xff0c;注意力机制已经成为提升卷积神经网络性能的关键技术之一。当我们面对ImageNet分类、目标检测等复杂任务时&#xff0c;网络需要学会"看重点"——自动识别图像中最相关的区域和…...

告别复制粘贴!用Automa浏览器插件把网页数据自动存进MySQL数据库(保姆级图文教程)

告别复制粘贴&#xff01;用Automa浏览器插件实现网页数据自动入库全攻略 每天重复从网页复制数据到Excel再导入数据库&#xff1f;运营周报、竞品监控、市场分析等场景下&#xff0c;这种低效操作正在吞噬职场人的宝贵时间。本文将带你用Automa这款可视化自动化工具&#xff0…...