筑基五层 —— 位运算看这篇就行了
目录
一.修炼必备
二. 位运算
二.移位运算符
三.位运算综合使用
恭喜你,成功突破至筑基五层!!!
一.修炼必备
1.入门必备:VS2019社区版,下载地址:Visual Studio 较旧的下载 - 2019、2017、2015 和以前的版本 (microsoft.com)
2.趁手武器:印象笔记/有道云笔记
3.修炼秘籍:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
4.雷劫必备:leetcode 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
注:遇到瓶颈怎么办?百度百科_全球领先的中文百科全书 (baidu.com)
二. 位运算
1.什么是位运算?
——位运算就是直接对整数在内存中的二进制位进行操作的运算
2.位运算操作符
位操作符 | 特点 |
&(按位与) | 有0为0,全1为1 |
|(按位或) | 有1为1,全0为0 |
^(按位异或) | 相同为0.不同为1 |
~(按位取反) | 0变1,1变0 |
注:
1)二进制的运算均是以补码进行运算的
2)异或满足交换律和结合律
交换律:num ^ 0 = num; 0 ^ num = num;
结合律:num ^ a ^ a = num; a ^ num ^ a = num;
//任何数和0异或等于本身,相同数异或为0
3)只有对整数才能进行位运算,浮点数不能进行位运算
3.一个小case快速了解位运算符
#include<stdio.h>int main()
{int a=7;int b=4;//按位与int c=a&b;//00000000 00000000 00000000 00000111 -> a: 7//00000000 00000000 00000000 00000100 -> b: 4//00000000 00000000 00000000 00000100 -> a&b: 4printf("%d & %d = %d\n",a,b,c);// 7 & 4 = 4//按位或c=a|b;//00000000 00000000 00000000 00000111 -> a: 7//00000000 00000000 00000000 00000100 -> b: 4//00000000 00000000 00000000 00000111 -> a|b: 7 printf("%d | %d = %d\n",a,b,c);// 7 | 4 = 7//按位异或c=a^b;//00000000 00000000 00000000 00000111 -> a: 7//00000000 00000000 00000000 00000100 -> b: 4//00000000 00000000 00000000 00000011 -> a^b: 3printf("%d ^ %d = %d\n",a,b,c);// 7 ^ 4 = 3//按位取反c = ~a;//00000000 00000000 00000000 00000111 -> a: 7//11111111 11111111 11111111 11111000 -> ~a(补码)//11111111 11111111 11111111 11110111 -> 反码//10000000 00000000 00000000 00001000 -> 原码(打印的是原码):-8printf("~%d = %d\n", a, c);//~7 = -8return 0;
}
4.常用的位操作符
1)判断奇偶性
奇数:(num & 1) == 1 等价于 num % 2 == 1
偶数:(num & 1) == 0 等价于 num % 2 == 0
注:为什么num&1要加括号? —— ==的优先级比&的优先级高
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);//若是想要使用num & 1 == 1,则需要使用括号括上(num & 1) == 1if (num & 1){printf("%d是奇数\n", num);}else{printf("%d是偶数\n", num);}return 0;
}
2)计算二进制中有几个1:num = num & (num -1)
#include <stdio.h>int getOneCount(int num)
{int count = 0;while (num){num = num & (num - 1);count++;//测试用例1:7//00000000 00000000 00000000 00000111 : 7//00000000 00000000 00000000 00000110 : 6//00000000 00000000 00000000 00000110 : 6 :结果//00000000 00000000 00000000 00000101 : 5//00000000 00000000 00000000 00000100 : 4: 结果//00000000 00000000 00000000 00000011 : 3//00000000 00000000 00000000 00000000 : 0: 结果 -->跳出循环//测试用例2:10//00000000 00000000 00000000 00001010 : 10//00000000 00000000 00000000 00001001 : 9//00000000 00000000 00000000 00001000 : 8: 结果//00000000 00000000 00000000 00000111 : 7//00000000 00000000 00000000 00000111 : 0: 结果 -->跳出循环}return count;
}int main()
{int num = 0;scanf("%d", &num);int count = getOneCount(num);//计算1的个数printf("%d的二进制中有%d个1\n", num, count);return 0;
}
3)num & -num:得到二进制的最低位的1(不一定是最后一位)
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);int ret = num & -num;printf("%d & -%d = %d\n", num, num, ret);//说明:二进制的运算均是以补码进行的//测试案例1:7//10000000 00000000 00000000 00000111 -->原码 -7//11111111 11111111 11111111 11111000 -->反码//11111111 11111111 11111111 11111001 -->补码//00000000 00000000 00000000 00000111 -->补码 7//00000000 00000000 00000000 00000001 --> 1 :结果//测试用例2: 10//10000000 00000000 00000000 00001010 -->原码 -10//11111111 11111111 11111111 11110101 -->反码//11111111 11111111 11111111 11110110 -->补码//00000000 00000000 00000000 00001010 -->补码 10//00000000 00000000 00000000 00000010 -->2 : 结果return 0;
}
4)num & ~num:0
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);int ret = num & ~num;printf("%d & ~%d = %d\n", num, num, ret);//测试用例1:3//00000000 00000000 00000000 00000011 :3//11111111 11111111 11111111 11111100 :~3//00000000 00000000 00000000 00000000 :0 结果//测试用例2:4//00000000 00000000 00000000 00000100 :4//11111111 11111111 11111111 11111011 :~4//00000000 00000000 00000000 00000000 :0 结果return 0;
}
5)低位首0变1:num | (num+1)
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);int ret = num | (num + 1);printf("%d | %d = %d\n", num, num + 1, ret);//测试用例1:5//00000000 00000000 00000000 00000101 :5//00000000 00000000 00000000 00000110 :6//00000000 00000000 00000000 00000111 : 7 --> 低位首0变1//测试用例2:9//00000000 00000000 00000000 00001001 :9//00000000 00000000 00000000 00001010 :10//00000000 00000000 00000000 00001011 :11 --> 低位首0变1return 0;
}
6)求num的相反数:~num + 1
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);int ret = ~num + 1;printf("%d\n", ret);//测试用例1:5//11111111 11111111 11111111 11111010 :~5//11111111 11111111 11111111 11111011 :~5 + 1 补码//11111111 11111111 11111111 11111010 :反码//10000000 00000000 00000000 00000101 :原码 --> -5//测试用例2:-5//10000000 00000000 00000000 00000101 原码//11111111 11111111 11111111 11111010 反码//11111111 11111111 11111111 11111011 补码//00000000 00000000 00000000 00000100 ~(-5)//00000000 00000000 00000000 00000101 ~(-5)+ 1 --> 5(结果)return 0;
}
7)判断数是不是2的幂:num & (num-1) == 0
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);if ((num & (num - 1)) == 0){printf("%d是2的幂\n", num);}else{printf("%d不是2的幂\n", num);}//测试案例1:2//00000000 00000000 00000000 00000010 :2//00000000 00000000 00000000 00000001 :1//00000000 00000000 00000000 00000000 :0 --> 结果//测试用例2:8//00000000 00000000 00000000 00001000 : 8//00000000 00000000 00000000 00000111 : 7//00000000 00000000 00000000 00000000 : 0 -->结果return 0;
}
8)异或应用:变量交换
#include <stdio.h>int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);//交换变量a = a ^ b;b = a ^ b;a = a ^ b;printf("%d %d\n", a, b);return 0;
}
二.移位运算符
1.什么是移位运算符?
——在C语言中,使用<<和>>对数的二进制位进行向左移动和向右移动,而<<和>>称为移位运算符
2.移位操作符
移位操作符 | 特点 |
<< | 左边丢弃,右边补0 |
>> | 算术右移:右边丢弃,左边补符号位 逻辑右移:右边丢弃,左边补0 |
二进制位进行移位的时候,不要移动负数位,因为这个标准是未定义的
3.一个小case快速了解移位操作符
#include <stdio.h>int main()
{int num = 7;int ret = num << 2;//00000000 00000000 00000000 00000111 num//000000 00000000 00000000 0000011100 num << 2 :28printf("%d\n", ret);//28ret = num >> 2;//00000000 00000000 00000000 00000111 num//注:我们在这个地方进行的是算术右移,现在大多数编译器都是进行算术右移的//0000000000 00000000 00000000 000001 num >> 2 :1printf("%d\n", ret);//1return 0;
}
4.常用的移位操作
1)num >> 1 等价于 num / 2
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);int ret = num >> 1;int res = num / 2;//测试案例1:10//00000000 00000000 00000000 00001010 num: 10//00000000 00000000 00000000 00000101 num >> 1:5//num / 2 = 5//测试案例2:15//00000000 00000000 00000000 00001111 num:15//00000000 00000000 00000000 00000111 num >> 1:7//num / 2= 7if (ret == res){printf("num>>1和num/2相等\n");}else{printf("num>>1和num/2不相等\n");}return 0;
}
2)去掉num的低x位(从最低位一直到x位):num >> x
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);int ret = num >> 3;//去掉低三位//00000000 00000000 00000000 00001111 num:15//00000000 00000000 00000000 00000001 num:1printf("%d\n", ret);//1ret = num >> 2;//去掉低两位//00000000 00000000 00000000 00001111 num:15//00000000 00000000 00000000 00000011 num:3printf("%d\n", ret);//3return 0;
}
三.位运算综合使用
注:规定,我的最低位是从1开始,最高位是32
1.获取num二进制位的第n位值:(num >> n) &1
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);int ret = (num >> 3) & 1;printf("%d\n", ret);//测试案例:15//00000000 00000000 00000000 00001111 num:15//00000000 00000000 00000000 00000001 num >> 3//00000000 00000000 00000000 00000001 (num >> 3) & 1//00000000 00000000 00000000 00000001 1return 0;
}
2.将num的第(n+1)位置为1:num | (1 << n)
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);//将num的第4位置为1int ret = num | (1 << 3);printf("%d\n", ret);//测试案例:5//00000000 00000000 00000000 00000101//00000000 00000000 00000000 00001000 1 << 3//00000000 00000000 00000000 00001101 13return 0;
}
3.将num的第(n+1)位置为0:num & (~(1 << n))
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);//将num的第3位置为0int ret = num & (~(1 << 2));printf("%d\n", ret);//测试案例:5//00000000 00000000 00000000 00000100 1 << 2//11111111 11111111 11111111 11111011 ~(1 << 2) :补码//00000000 00000000 00000000 00000101 : 5//00000000 00000000 00000000 00000001 : num & (~(1 << 2))return 0;
}
4.获取num的第(n+1)位的幂值:num & (1 << n)
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);//获取num第3位的幂值int ret = num & (1 << 2);printf("%d\n", ret);//测试案例 :5//00000000 00000000 00000000 00000101 : 5//00000000 00000000 00000000 00000100 : 1 << 2//00000000 00000000 00000000 00000100 : num & (1 << 2): 4//测试案例: 8//00000000 00000000 00000000 00001000 : 8//00000000 00000000 00000000 00000100 : 1 << 2//00000000 00000000 00000000 00000000 : num & (1 << 2): 0return 0;
}
5.将num的最高位到(n+1)位置为0:num & ((1 << n) - 1)
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);//将num的最高位到第4位置为0int ret = num & ((1 << 3) - 1);printf("%d\n", ret);//测试案例:121//00000000 00000000 00000000 01111001 :121//00000000 00000000 00000000 00000111 : 1 << 3 - 1//00000000 00000000 00000000 00000001 : 7return 0;
}
6.将num的第1位到第(n+1)位置为0:num & (~((1 << (n + 1)) - 1))
#include <stdio.h>int main()
{int num = 0;scanf("%d", &num);//将num的第0位到第3位置为0int ret = num & (~((1 << (2 + 1)) - 1));printf("%d\n", ret);//测试案例: 121//00000000 00000000 00000000 00000111 :(1 << (2 +1) - 1)//11111111 11111111 11111111 11111000 :~(1 << (2 +1) - 1)//00000000 00000000 00000000 01111001 :121//00000000 00000000 00000000 01111000return 0;
}
7.代替减法进行两数相减:x + ~y + 1
#include <stdio.h>int main()
{int x = 0;int y = 0;scanf("%d %d", &x, &y);int ret = x + ~y + 1;printf("%d - %d = %d\n", x, y, ret);//测试案例:x = 5, y = 3//00000000 00000000 00000000 00000011 y//11111111 11111111 11111111 11111100 ~y//00000000 00000000 00000000 00000101 x//00000000 00000000 00000000 00000001 x + ~y = 1//00000000 00000000 00000000 00000010 x + ~y + 1 = 2//测试案例: x = 3, y = 5//00000000 00000000 00000000 00000101 y//11111111 11111111 11111111 11111010 ~y//00000000 00000000 00000000 00000011 x//11111111 11111111 11111111 11111101 x + ~y//11111111 11111111 11111111 11111110 x + ~y + 1 补码//11111111 11111111 11111111 11111101 反码//10000000 00000000 00000000 00000010 原码 -2return 0;
}
8.代替加法进行两数相加:x - ~y - 1
#include <stdio.h>int main()
{int x = 0;int y = 0;scanf("%d %d", &x, &y);int sum = ~y;int ret = x - ~y - 1;printf("%d + %d = %d\n", x, y, ret);//测试案例:x = 5, y = 3//00000000 00000000 00000000 00000011 y//00000000 00000000 00000000 00000101 x//11111111 11111111 11111111 11111100 ~y//00000000 00000000 00000000 00001001 x - ~y//00000000 00000000 00000000 00001000 x - ~y - 1: 8return 0;
}
注:位运算的基本常用的操作就在这点了,但是远不止这点,需要我们更加努力的学习和探索位运算的奥妙。
注:若是觉得CSDN看起来很难受的话,请去有道云看我写的原文(排版更好)
链接在此:有道云笔记
恭喜你,成功突破至筑基五层!!!
相关文章:
筑基五层 —— 位运算看这篇就行了
目录 一.修炼必备 二. 位运算 二.移位运算符 三.位运算综合使用 恭喜你,成功突破至筑基五层!!! 一.修炼必备 1.入门必备:VS2019社区版,下载地址:Visual Studio 较旧的下载 - 2019、2017、201…...

windows安装proget实现nuget私有包部署
下载proget 官网 下载地址 免费下载 安装proget 下载完成之后双击安装 选择ProGet 默认选择即可 也可以指定数据库,SQL Server数据库 Server服务器名;Database数据库名;User Id用户名;Password密码 Serverlocalhost;DatabaseProGet2;User Idsa;Passwordxxxx…...

SpringBoot简单集成OpenFeign
问题 在SpringBoot中简单集成Feign,不想使用Rest Temple了。 步骤 Maven <properties><spring.cloud-version>2022.0.1</spring.cloud-version></properties> <dependencyManagement><dependencies><dependency><g…...

dfs(九)字符串的全排列
字符串的排列_牛客题霸_牛客网【牛客题霸】收集各企业高频校招笔面试题目,配有官方题解,在线进行百度阿里腾讯网易等互联网名企笔试面试模拟考试练习,和牛人一起讨论经典试题,全面提升你的技术能力https://www.nowcoder.com/practice/fe6b651b66ae47d7ac…...

别具一格,原创唯美浪漫情人节表白专辑,(复制就可用)(html5,css3,svg)表白爱心代码(1)
别具一格,原创唯美浪漫情人节表白专辑, (复制就可用)(html5,css3,svg)表白爱心代码(1) 一、 前言 回眸之间,丰盈了岁月,涟漪了思绪,轻轻落笔,不写伤痕,不写仇怨,只写岁月…...
Hudi-集成Spark之spark-sql方式
Hudi集成Spark之spark-sql方式 启动spark-sql # 启动spark-sql之前需要先启动Hive的Metastore nohup hive --service metastore & #针对Spark 3.2 spark-sql \--conf spark.serializerorg.apache.spark.serializer.KryoSerializer \--conf spark.sql.catalog.spark_catal…...

快速排序基本原理
快速排序基本原理1.快速排序1.1 基本原理1.2 快速排序执行步骤1.2.1 分区包含步骤1.2.1 分区步骤1.3 快速排序大O记法表示2. 将[0,5,2,1,6,3]进行快速排序 【实战】2.1 第一次分区步骤2.2 第二次分区步骤2.3 第三次分区步骤2.4 第四次分区步骤3.快速排序代码实现1.快速排序 1.…...
Android开发笔记-提纲(连载中....)
文章目录Android概述Android开发学习笔记提纲1. 认识AS开发Android的基础入门知识2. 认识Activity的生命周期和基础使用3. 认识Activity之间的跳转和传值4. 认识Intent以及全局Activity的属性的共享5. 认识Service6. 学习跨应用服务【AIDL通信】Android概述 Android系统框架的四…...

React Native(一)
移动端触摸事件example1:<ButtononPress{() > {Alert.alert(你点击了按钮!);}}title"点我!" />Touchable 系列组件TouchableHighlight 此组件的背景会在用户手指按下时变暗TouchableNativeFeedback 会在用户手指按下时形成类似墨水涟…...
Kotlin 26. Kotlin 如何播放音频文件
Kotlin 如何播放音频文件 文章目录Kotlin 如何播放音频文件1 下载并放置音频文件2 activity_main.xml3 MainActivity.kt1 下载并放置音频文件 我们可以随便下载一个音频文件,比如 alarm.mp3,需要将其放置在 /res/raw/ 路径下。 2 activity_main.xml 这…...

recv和明文收包分析
我们CTRLg 跳到recv 分析收包函数 发现函数会断并且收包函数返回值(收包包长)也会不断变化 那么证明recv是真正的收包函数,游戏没有重新实现该函数 我们只要分析该函数即可 在recv函数执行完毕以后下断 eax是包长,esi28是包指针 我们上2个号,让另外…...

【IVIF的超分重建】
Multimodal super-resolution reconstruction of infrared and visible images via deep learning (基于深度学习的红外和可见光图像多模态超分辨率重建) 提出了一种基于编解码器结构的红外-可见光图像融合方法。图像融合任务被重新表述为保持红外-可见…...
“深度学习”学习日记。--加深网络
2023.2.13 深度学习 是加深了层的深度神经网络的学习过程。基于之前介绍的网络,只需要通过 叠加层, 就可以创建深度网络 之前的学习,已经学习到了很多东西,比如构成神经网络的各种层、参数优化方法、误差反向传播法,…...
2023前端面试总结含参考答案
文章目录1. 父子组件生命周期的执行顺序:2. 原型链:3. promise的理解:4. 数组循环,foreach,filter,map,reduce5. 数组去重,set6. 组件通信方式7. 路由钩子8. 首页首屏加载优化:9. th…...

总览 Java 容器--集合框架的体系结构
前言 我们在讲 Java 的数据类型的时候,单独介绍过数组,数组也确实是开发程序中常用的内存类型之一,不过 Java 内置的数组限制颇多,所以此后扩展出了List这种结构,与之类似的Set、Queue 这些内存中的容器都被放在了 Co…...

即便考分很好也不予录取的研究生复试红线,都是原则性问题
在浙大研究生招生录取政策文件中有这么一句话:坚持“按需招生、全面衡量、择优录取、宁缺毋滥”的原则,以提高人才选拔质量为核心,在确保安全性、公平性和科学性的基础上,做到统筹兼顾、精准施策、严格管理。字字体现出研究生招生…...
Android java创建子线程的几种方法
1.新建一个类继承自Thread,并重写run()方法,并在里面编写耗时逻辑。 1 2 3 4 5 6 7 class ThreadTest extends Thread { Override public void run() { //具体的耗时逻辑代码 } } new ThreadTest().st…...

UVa 11212 Editing a Book 编辑书稿 IDA* Iterative Deepening A Star 迭代加深搜剪枝
题目链接:Editing a Book 题目描述: 给定nnn个(1<n<10)1<n<10)1<n<10)数字,数字分别是1,2,3,...,n1, 2, 3, ...,n1,2,3,...,n,但是顺序是打乱的,你可以选择一个索引区间的数字进行剪切操作。问最少进…...

第一章:unity性能优化之内存优化
目录 前言 unity性能优化之内存的优化 一、unity Analysis工具的使用。 二、内存优化方法 1、设置和压缩图片 2、图片格式 3、动画文件 4、模型 5、RenderTexture(RT) 6、分辨率 7、资源的重复利用 8、shader优化 9、对bundle进行良好的管…...

2023年家族办公室研究报告
第一章 概况 家族办公室最早起源于古罗马时期的大“Domus”(家族主管)以及中世纪时期的大“Domo”(总管家)。现代意义上的家族办公室出现于19世纪中叶,一些抓住产业革命机会的大亨将金融专家、法律专家和财务专家集合…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...