首页 > 系统相关 >C#经典面试题:执行string abc=“aaa“+“bbb“+“ccc“共分配了多少内存?

C#经典面试题:执行string abc=“aaa“+“bbb“+“ccc“共分配了多少内存?

时间:2024-07-12 15:58:16浏览次数:17  
标签:面试题 abc aaa string C# 内存 str 字符串

C#经典面试题:执行string abc="aaa"+"bbb"+"ccc"共分配了多少内存?

这是一个经典的基础知识题目,它涉及了字符串的类型、堆栈和堆的内存分配机制,因此被很多人拿来考核开发者的基础知识功底。

首先,我们都知道,判断值类型的标准是查看该类型是否会继承自System.ValueType,通过查看和分析,string直接继承于System.Object,因此string是引用类型,其内存分配会遵照引用类型的规范,也就是说如下的代码将会在堆栈上分配一块存储引用的内存,然后再在堆上分配一块存储字符串实例对象的内存。

  string a = "edc";

现在再来看看string abc="aaa"+"bbb"+"ccc",按照常规的思路,字符串具有不可变性,大部分人会认为这里的表达式会涉及很多临时变量的生成,可能C#编译器会先执行"aaa"+"bbb",并且把结果值赋给一个临时变量,再执行临时变量和"ccc"相加,最后把相加的结果再赋值给abc。But,其实C#编译器比想象中要聪明得多,以下的C#代码和IL代码可以充分说明C#编译器的智能:

   // The first format
    string first = "aaa" + "bbb" + "ccc";
    // The second format
    string second = "aaabbbccc";
    // Display string 
    Console.WriteLine(first);
    Console.WriteLine(second);

该C#代码的IL代码如下图所示:

正如我们所看到的,string abc="aaa"+"bbb"+"ccc";这样的表达式被C#编译器看成一个完整的字符串"aaabbbccc",而不是执行某些拼接方法,可以将其看作是C#编译器的优化,所以在本次内存分配中只是在栈中分配了一个存储字符串引用的内存块,以及在托管堆分配了一块存储"aaabbbccc"字符串对象的内存块。

那么,我们的常规思路在.NET程序中又是怎么体现的呢?我们来看一下一段代码:

   int num = 1;
    string str = "aaa" + num.ToString();
    Console.WriteLine(str);

这里我们首先初始化了一个int类型的变量,其次初始化了一个string类型的字符串,并执行 + 操作,这时我们来看看其对应的IL代码:

    int num = 1;
    string str = "aaa" + num.ToString();
    Console.WriteLine(str);

这里我们首先初始化了一个int类型的变量,其次初始化了一个string类型的字符串,并执行 + 操作,这时我们来看看其对应的IL代码:

如上图所示,在这段代码中执行 + 操作,会调用String的Concat方法,该方法需要传入两个string类型的参数,也就产生了另一个string类型的临时变量。换句话说,在此次内存分配中,堆栈中会分配一个存储字符串引用的内存块,在托管堆则分配了两块内存块,分别存储了存储"aaa"字符串对象和"1"字符串对象。

可能这段代码还是不熟悉,我们再来看看下面一段代码,我们就感觉十分亲切熟悉了:

 string str = "aaa";
    str += "bbb";
    str += "ccc";
    Console.WriteLine(str);

其对应的IL代码如下图所示:

如图可以看出,在拼接过程中产生了两个临时字符串对象,并调用了两次String.Concat方法进行拼接。

标签:面试题,abc,aaa,string,C#,内存,str,字符串
From: https://blog.csdn.net/yannsann/article/details/140381297

相关文章

  • 高级java每日一道面试题-2024年7月12日
    如果有遗漏,评论区告诉我进行补充面试官问:你对IO流了解多少我回答:一.什么是JavaIO流?回答:JavaIO流是用于处理输入和输出操作的一组类和接口。它允许程序从不同的数据源(如文件、网络连接、内存缓冲区等)读取数据或将数据写入到不同的目标位置。IO流分为字节流和......
  • 常见的MySQL 索引面试题(超有用)
    在面试中,MySQL索引是一个常见的话题,因为它们对数据库的性能优化至关重要。以下是几个常见的MySQL索引相关的面试题及其解答:1.什么是MySQL索引?有哪些类型?解答:索引是一种用于提升数据库查询速度的数据结构。索引本质上是数据表中一列或多列的有序排列,可以加速数据的......
  • [ABC328D] Take ABC 题解
    题目翻译题目描述给你一个字符串\(S\)包含A、B和C三个不用的字符。只要字符串\(S\)中包含连续的ABC就将ABC删除掉再字符串\(S\)不能操作之后输出这个字符串限制\(S\)的长度小于\(2\times10^5\)思路1总结一下这道题目的操作,可以发现就是将字符串删除一......
  • 精选力扣,牛客链表面试题
    ......
  • 算法工程师热门面试题(二)
    生成对抗网络(GAN):请解释GAN的基本原理及其训练过程。生成对抗网络(GAN,GenerativeAdversarialNetworks)是一种深度学习模型,由蒙特利尔大学的IanGoodfellow在2014年提出。GAN的基本原理和训练过程可以详细解释如下:基本原理GAN通过两个神经网络——生成器(Generator)和判别器(D......
  • 测试工程师面试题(五)
    什么是敏捷测试敏捷测试(Agiletesting)是一种遵循敏捷软件开发规则和原则的测试实践。它强调从客户的角度,即从使用系统的用户角度,来测试系统,并重点关注持续迭代地测试新开发的功能,而不再强调传统测试过程中严格的测试阶段。敏捷测试不仅仅是测试软件本身,还包含了软件测试的......
  • Java 算法和数据结构 答案整理,最新面试题
    Java中如何使用动态规划求解背包问题?1、定义子问题:首先确定动态规划状态,通常以物品数量和背包容量为变量定义子问题,例如dp[i][j]表示前i件物品放入容量为j的背包所能获得的最大价值。2、确定状态转移方程:基于是否选择当前物品,将问题分为两个子问题,即dp[i][j]=......
  • aaaaa
    /home/idiao123/ceshi/mainwindow.cpp:17:error:'open_buzzer'wasnotdeclaredinthisscopeopen_buzzer();^/home/idiao123/ceshi/mainwindow.cpp:21:error:'close_buzzer'wasnotdeclaredinthisscopeclose_......
  • 代码随想录算法训练营第四天 | Python | LeetCode24.两两交换链表中的节点、19.删除链
    LeetCode24.两两交换链表中的节点题目链接:https://leetcode.cn/problems/swap-nodes-in-pairs/description/文章/视频链接:https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html#%E7%AE%9......
  • ABC361
    Alink先输出前\(k\)个,再输出\(x\),最后输出后面的。点击查看代码#include<bits/stdc++.h>usingnamespacestd;intn,k,x;signedmain(){ cin>>n>>k>>x; for(inti=1;i<=n;++i){ inta; cin>>a; cout<<a<<......