C#基础学习(三)值类型和引用类型:编程世界的“现金“ vs “银行卡“,以及string这个“渣男“的叛变行为

开场白
        各位程序猿/媛们,今天我们来聊一聊编程世界里的"金钱观"。
你以为只有人类会纠结现金和存款的区别?不不不,C#中的值类型和引用类型每天都在上演这场大戏!
        而我们的string同学,表面是个引用类型,背地里却偷偷活成了值类型的样子——像极了在朋友圈立健身人设,实际在家躺平的你。

第一章:当值类型和引用类型去开房(内存分配篇)​

已经学习过的数据类型

无符号整型有符号类型 浮点数      特殊类型
//byte b;     //sbyte sb;    //float f;     //bool bo;
//ushort us;  //short s;     //double d     //char a;;
//uint ui;    //int i;       //decimal      //string str;c;
//ulong ul;   //long l;复杂数据类型引用类型:string 数组 类(未学习)
枚举        值类型:其他,结构体
数组

想象值类型和引用类型是两个性格迥异的房客:

  • 值类型:实诚的直男
    入住时自带全部家当(数据),直接住进快捷酒店()。退房时连卫生纸都带走(深拷贝),绝不拖泥带水。例如你有一个数据A,你将其复制给B,那么此时他两就从此天涯陌路人,丝毫关系都莫得了啊,你无论怎么修改B,都绝不会影响到A。
    代表嘉宾:int, double, struct

  • 引用类型:心机的高富帅
    只带一张房卡(内存地址),把行李全扔在豪宅()里。复制时只给你房卡复印件(浅拷贝),真要去豪宅会发现里面住着前任!对于咱们得引用类型而言呢,他就不像值类型那样绝情,他们在复制的时候,其实是把自己本体也拿过去了,就像是你的银行卡,你可以存钱存上去,你的朋友也可以打钱上去,跑得了和尚跑不了银行卡。钱,始终都是存在银行卡上面的,你可以取出来,假如你和你的朋友穿一条裤子,你把密码告诉了他(你偷偷把银行卡的密码复制给了他)那么他也可以取出来了钱。
    代表嘉宾:class, array

示例:

int a = 10;         // 直男值类型:揣着10块钱现金
int b = a;          // 克隆人战争,b是a的复制体
b = 20;             // 改b不会让a变成土豪List<int> list1 = new List<int>(); // 引用类型开豪宅
List<int> list2 = list1;           // 渣男行为:共享同一套房
list2.Add(42);                     // 现在list1也被迫拥有42了!

示例:

//1.使用上的区别
//值类型
int a = 10;
//引用类型
int[] arr = new int[] {1,2,3,4,5 };
//申明了一个b等于a
int b = a;
//申明了一个arr2让其等于之前的arr
int[] arr2 = arr;
Console.WriteLine("a={0},b={1}", a, b);
Console.WriteLine("arr[0]={0},arr2[0]={1}", arr[0], arr2[0]);b = 20;
arr2[0] = 5;
Console.WriteLine("修改后");
Console.WriteLine("a={0},b={1}", a, b);
Console.WriteLine("arr[0]={0},arr2[0]={1}", arr[0], arr2[0]);
//值类型 在相互赋值时  把内容拷贝给了对方 他变我不变
//引用类型的相互赋值 是 让二者指向同一个值 它变我也变 数组 string 类//2.为什么有以上区别
//二者的存储的内存区域不同 存储方式不同 故使用上有区别
//值类型 存储在 栈空间 - 系统分配,自动回收,小而快
//引用类型 存储在堆空间 - 手动申请和释放,大而慢
string str = "123";
string str2 = str;
str2 = "321";
Console.WriteLine(str);
Console.ReadKey();

第二章:string的"薛定谔式"生存法则

string同学作为引用类型家族的叛徒,活出了精分现场:

  1. 表面身份:根正苗红的引用类型
    身份证上写着"System.String",住在堆区豪宅里。

  2. 实际行为

    • 不可变の强迫症:每次修改都像在墙上贴瓷砖——必须拆了旧墙建新房!
    • 假装值类型:复制时宛如克隆人,和原对象老死不相往来。
    • ​**== 运算符的叛变**:其他引用类型用==比地址,string却开始比内涵(值内容)!

 //string 的他变我不变
//string非常特殊 它具备 它变我不变
//string 虽然方便 但是频繁的 改变string 重新赋值会产生内存垃圾

        

string A = "我是原配";
string B = A;    // 此时B拿着和A一样的房卡(引用地址)
B = "我是小三";  // 此时A依然坚贞不屈:"我是原配"

表面现象:​
        看起来像是深拷贝(复制值),B改嫁后A不受影响,仿佛string有「值类型の纯洁」。 

真相1:​ 赋值时它就是个普通引用类型!
        B和A最初共享同一块内存​(指向堆里的"我是原配"),和所有引用类型一样发的是房卡复印件。

真相2:​ 一切改变都是「假装努力」!
        当B试图修改时,string的不可变性(Immutable)​ 强迫症发作:
👉 系统在堆里新建豪宅"我是小三"
👉 把B的房卡偷偷换成新地址
👉 而A的房卡还是旧地址,自然不受影响

这就像:​
        你和朋友合租时,你突然暴富买了别墅搬走,但室友依然住在老破小——不是因为你们分行李了,而是你直接换房了!

  • 普通引用类型:共享同一套房,装修直接改原房(浅拷贝)
  • ​string:表面共享房卡,实际变心就换房(不可变+新建对象)

string的「深拷贝错觉」= 引用类型的身子 + 值类型的命 + 不可变的病! 

示例:

string s1 = "Hello";       
string s2 = s1;          // 此时s2是s1的舔狗
s2 = "World";            // 渣男突然自立门户,s1还是单身贵族string s3 = "Hello";
string s4 = "Hello";
// 此时s3和s4在堆里上演"替身文学",共享同一个"Hello"(拘留池机制)

第三章:当它们去参加《非诚勿扰》(参数传递篇)​

  • 值类型女嘉宾
    "我的数据我自己带!"(默认值传递)
    牵手时直接克隆一个自己送过去,原版继续在舞台单身。

  • 引用类型男嘉宾
    "我只给你我家钥匙~"(默认引用传递)
    女嘉宾拿到钥匙后能随便装修房子,甚至能把家具全卖了!

彩蛋时刻——当ref来搅局:​
值类型被ref修饰后,瞬间黑化成"地址传递",开始共享闺房密码!

        ref的好朋友out我们后面再说,这其实是在函数里面用到的,来帮助我们将函数内修改的值传递到函数外面去。所以说呢,这也算是个好僚机。当你正苦恼怎么获得女神的微信时候,这个时候女神的室友直接祝你一臂之力,只需要你用ref收买她,她就偷偷的把你的女神的微信号给偷出来了。

        小彩蛋:

第一阶段:基础篇(无ref时)​
void 追求女神()
{string 女神微信号 = null; 室友帮忙偷号(女神微信号);Console.WriteLine(女神微信号); // 输出:null (惨遭失败!)
}void 室友帮忙偷号(string 微信号)
{微信号 = "LoveU3000"; // 修改的是局部变量副本
}

剧情解析:​
        此时室友是「猪队友」,在函数内改了微信号的副本,但原始变量仍是null。就像您托人递情书,结果TA自己抄了一份,把原件扔了。 

第二阶段:ref僚机觉醒篇
void 追求女神()
{string 女神微信号 = null; 室友帮忙偷号(ref 女神微信号); // 递上ref接头暗号Console.WriteLine(女神微信号); // 输出:"LoveU3000" (成功!)
}void 室友帮忙偷号(ref string 微信号)
{微信号 = "LoveU3000"; // 直接修改原变量的内存地址
}

ref的隐藏规则

  1. 必须提前和女神搭讪过(变量需先初始化
  2. 室友(ref)不是凭空变出微信号,而是修改你们共同关注的聊天窗口
 第三阶段:out僚机的叛变形态
void 追求女神()
{string 女神微信号; // 未初始化! 室友帮忙偷号(out 女神微信号); // out接头更刺激Console.WriteLine(女神微信号); // 输出:"LoveU3000"
}void 室友帮忙偷号(out string 微信号)
{// 必须在这里赋值,否则编译器举起40米大刀!微信号 = "LoveU3000"; 
}

out vs ref 核心区别:​

  • ref:您得先有个目标(变量已初始化),室友助攻修改
  • out:您连目标都没有(变量未初始化),室友直接塞个新人给您

暴击总结(配代码注释)​

// ref是「改良派」:带着已有方案找人优化
int 存款 = 100;
女神理财顾问(ref 存款); // 存款可能变200或归零// out是「革命派」:不管三七二十一必须给结果
int 结果;
女神占卜师(out 结果); // 结果必定被赋值

小结:

  • ref:女神的闺蜜,需要您先请她喝奶茶(初始化),她才透露情报
  • out:女神的宿敌,不需要您付出任何代价,但会强制给您情报(必须赋值)

总结:如何一眼认出它们的真面目?

  1. 灵魂拷问:"你变了吗?"

    • 值类型:我变任我变,关原对象什么事?
    • 引用类型:我变就是全家变!
    • string:我变就是开分基地!
  2. 祖传口诀

值类型在栈上跑,复制就是深拷贝
引用类型堆里笑,地址传递真风骚
string是个两面派,表面引用实则菜(值)

散场彩蛋
        下次看到string时请尊称一声"钮祜禄·string",毕竟人家可是从引用类型底层杀出一条血路,活成了白月光般的存在! 

(完)今天的学习就到此为止吧,学C++去了!咱们以后再见

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

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

相关文章

操作系统的特征

并发 指两个或多个事件在同一时间间隔内发生。这些时间宏观上是同时发生的&#xff0c;但微观上是交替发生的。 并行 指两个或多个事件在同一时刻同时发生 操作系统的并发性 指计算机系统重“同时”运行着多个程序&#xff0c;这些程序宏观上看是同时运行的&#xff0c;而…

数据结构——B树、B+树、哈夫曼树

目录 一、B树概念1.B树的构造2 .B树的特点 二、B树概念1.B树构造2.B树的特点 三、B树和B树的区别四、哈夫曼树1.哈夫曼树的基本概念2.哈夫曼树的构建 一、B树概念 B树的出现是为了弥合不同的存储级别之间的访问速度上的巨大差异&#xff0c;实现高效的 I/O。平衡二叉树的查找效…

电子签的法律效力、业务合规与监管难点

撰稿 | 区长 来源 | 贝多财经 据2025年央视“3.15”晚会报道&#xff0c;借贷宝、人人信等平台上存在高利贷的情形。放贷人与借款人在平台签署借款合同&#xff0c;但是实际借款金额低于合同金额&#xff0c;从而绕开平台对利率的限制。这引发了人们对电子签法律效力、业务合…

资金管理策略思路

详细描述了完整交易策略的实现细节&#xff0c;主要包括输入参数、变量定义、趋势判断、入场与出场条件、止损与止盈设置等多个方面。 输入参数&#xff08;Input&#xff09;&#xff1a; EntryFrL (.6)&#xff1a;多头入场的前一日波动范围的倍数。 EntryFrS (.3)&#xff1…

体育直播视频源格式解析:M3U8 vs FLV

在体育直播领域&#xff0c;视频源的格式选择直接影响着直播的流畅度、画质以及兼容性。目前&#xff0c;M3U8 和 FLV 是两种最为常见的视频流格式&#xff0c;它们各有优劣&#xff0c;适用于不同的场景。本文将从技术原理、优缺点以及应用场景等方面对 M3U8 和 FLV 进行详细解…

【动态规划】下降路径最小和

跟之前不同由于可能取到最右上角值&#xff0c;则左右各加一列&#xff0c;并且由于求最小值&#xff0c;则加的列须设置为正无穷大&#xff1b; class Solution { public:int minFallingPathSum(vector<vector<int>>& matrix) {int nmatrix.size();vector<…

07_GRU模型

GRU模型 双向GRU笔记:https://blog.csdn.net/weixin_44579176/article/details/146459952 概念 GRU&#xff08;Gated Recurrent Unit&#xff09;也称为门控循环单元&#xff0c;是一种改进版的RNN。与LSTM一样能够有效捕捉长序列之间的语义关联&#xff0c;通过引入两个&qu…

VScode

由于centos停止了维护 ,后面使用ubuntu 在Ubuntu中用vscode 充当记事本的作用 替代了centos中vim的作用 后面使用vscode编辑 vscode中继续使用makefile , xshell中的cgdb进行debug (半图形写 ,半命令行debug&&运行) 官网下载地址&#xff1a;https://code.visuals…

【行驶证识别】批量咕嘎OCR识别行驶证照片复印件图片里的文字信息保存表格或改名字,基于QT和腾讯云api_ocr的实现方式

项目背景 在许多业务场景中,如物流管理、车辆租赁、保险理赔等,常常需要处理大量的行驶证照片复印件。手动录入行驶证上的文字信息,像车主姓名、车辆型号、车牌号码等,不仅效率低下,还容易出现人为错误。借助 OCR(光学字符识别)技术,能够自动识别行驶证图片中的文字信…

异步编程与流水线架构:从理论到高并发

目录 一、异步编程核心机制解析 1.1 同步与异步的本质区别 1.1.1 控制流模型 1.1.2 资源利用对比 1.2 阻塞与非阻塞的技术实现 1.2.1 阻塞I/O模型 1.2.2 非阻塞I/O模型 1.3 异步编程关键技术 1.3.1 事件循环机制 1.3.2 Future/Promise模式 1.3.3 协程&#xff08;Cor…

python-selenium 爬虫 由易到难

本质 python第三方库 selenium 控制 浏览器驱动 浏览器驱动控制浏览器 推荐 edge 浏览器驱动&#xff08;不容易遇到版本或者兼容性的问题&#xff09; 驱动下载网址&#xff1a;链接: link 1、实战1 &#xff08;1&#xff09;安装 selenium 库 pip install selenium&#…

前端OOM内存泄漏如何排查?

前言 现代前端开发中&#xff0c;随着应用的复杂性和交互性的增加&#xff0c;OOM&#xff08;Out Of Memory&#xff0c;内存不足&#xff09;问题和内存泄漏逐渐成为影响用户体验和应用性能的关键挑战。排查和解决这些问题需要开发人员具备良好的调试技巧和优化策略。 造成…

C++20:玩转 string 的 starts_with 和 ends_with

文章目录 一、背景与动机二、string::starts_with 和 string::ends_with&#xff08;一&#xff09;语法与功能&#xff08;二&#xff09;使用示例1\. 判断字符串开头2\. 判断字符串结尾 &#xff08;三&#xff09;优势 三、string_view::starts_with 和 string_view::ends_w…

Redis、Memcached应用场景对比

环境 Redis官方网站&#xff1a; Redis - The Real-time Data Platform Redis社区版本下载地址&#xff1a;Install Redis | Docs Memcached官方网站&#xff1a;memcached - a distributed memory object caching system Memcached下载地址&#xff1a;memcached - a dis…

【MySQL】日志

目录 基本概念错误日志二进制日志查询日记慢查询日志 基本概念 日志&#xff08;Log&#xff09;是系统、软件或设备在运行过程中对发生的事件、操作或状态变化所做的记录。这些记录通常包含时间戳、事件类型、相关数据等信息&#xff0c;用于跟踪运行过程、排查故障、审计操作…

ArkUI-List组件

列表是一个复杂的容器&#xff0c;当列表项达到一定数量&#xff0c;使得列表内容超出其范围的时候&#xff0c;就会自动变为可以滚动。列表适合用来展现同类数据类型。 List组件支持使用&#xff0c;条件渲染&#xff0c;循环渲染&#xff0c;懒加载等渲染控制方式生成子组件…

Word限定仅搜索中文或英文引号

在Word中&#xff0c;按下CtrlF键&#xff0c;左侧会弹出导航搜索栏&#xff1b; 点击放大镜旁边的下拉栏&#xff0c;选择高级查找 在查找内容处输入英文状态下的"&#xff0c;然后选择更多->使用通配符&#xff0c;就可以仅查找英文状态下的" 同理&#xff…

智能飞鸟监测 守护高压线安全

飞鸟检测新纪元&#xff1a;视觉分析技术的革新应用 在现代化社会中&#xff0c;飞鸟检测成为了多个领域不可忽视的重要环节。无论是高压线下的安全监测、工厂内的生产秩序维护&#xff0c;还是农业区的作物保护&#xff0c;飞鸟检测都扮演着至关重要的角色。传统的人工检测方…

React初学分享 事件绑定 组价通信 useState useEffect

React初学 React介绍快速搭建React项目JSXJSX的本质优势&#xff1a;JSX中使用JS表达式JSX中的列表渲染JSX实现简单条件渲染JSX实现复杂条件渲染 React中的事件绑定React基础事件绑定传递自定义参数同时传递事件对象和自定义参数 React中的组件useState修改状态的规则状态不可变…

【实战】deepseek数据分类用户评论数据

在平时的工作中&#xff0c;我们会遇到数据分类的情况&#xff0c;比如将一些文本划分为各个标签。如果人工分类这块的工作量将是非常大&#xff0c;而且分类数据的准确性也不高。我们需要用到一些工具来实现。提高效率的同时也提高准确率。 1.示例数据 用户ID 时间戳 评论场…