为什么布尔在.NET框架中消耗4个字节和2个字节?布尔值应占用1位或至少小于char.
鉴于我有一个可能处于一个或多个真/假状态的对象的情况,我总是有点模糊为什么程序员经常使用标志+位掩码而不是仅仅使用几个布尔值.
它遍布.NET框架.不确定这是否是最好的示例,但.NET框架具有以下内容:
public enum AnchorStyles
{
None = 0,
Top = 1,
Bottom = 2,
Left = 4,
Right = 8
}
Run Code Online (Sandbox Code Playgroud)
因此,给定锚样式,我们可以使用位掩码来确定选择哪个状态.但是,似乎您可以使用AnchorStyle类/结构来完成相同的操作,其中为每个可能的值或单个枚举值的数组定义了bool属性.
当然,我的问题的主要原因是我想知道我是否应该使用自己的代码进行类似的练习.
那么,为什么要用这种方法呢?
我只是学习C#并深入研究数据类型.
为什么bool数据类型不是1位?
它似乎只能保存两个值中的一个(真或假),那么只占用1位空间来表示该值吗?
是因为这篇文章中提到的值的最小'可寻址'大小是一个字节(8位)?
我的总体目标是在逻辑上设想C#中每种数据类型的不同大小,所以我试图创建一个包含所有数据类型及其分配位大小的列表,这让我感动.
我正在阅读这里发布的一个问题:C#中的数独算法
其中一个解决方案是这段代码.
public static bool IsValid(int[] values) {
int flag = 0;
foreach (int value in values) {
if (value != 0) {
int bit = 1 << value;
if ((flag & bit) != 0) return false;
flag |= bit;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
这个想法是它将检测值数组中的重复项; 但是我不知道有多少我不知所措.谁可以给我解释一下这个?
编辑:谢谢大家.这么多很棒的答案,我不知道如何选择一个.它现在非常有意义.
这个问题来自这里.我在VS中尝试了这个语句,看看会发生什么:
Len(Name <= 3)
Run Code Online (Sandbox Code Playgroud)
根据这个答案也是这个,布尔要消耗4个字节.根据MSDN,Len函数在VB中
返回一个整数,该整数包含字符串中的字符数或存储变量所需的标称字节数.
Name <= 3应该将3转换为String并执行字符串比较,返回一个布尔值,因此Len应评估其中的字节数,该值应为4.出于某种原因,无论第二个参数如何,上面的代码都返回2.换句话说,Len(True)也返回2.尝试不同的平台目标(32和64) - 同样的事情.
为什么Len(Boolean)返回2而不是4?
测验:以下程序打印什么?
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication2 {
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct Struct1 {
bool b;
int i;
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct Struct2 {
byte b;
int i;
}
class Program {
static void Main(string[] args) {
Console.WriteLine(Marshal.SizeOf(typeof(Struct1)));
Console.WriteLine(Marshal.SizeOf(typeof(Struct2)));
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
回答:
8
5
Run Code Online (Sandbox Code Playgroud)
这对我来说非常困惑.bool和byte都有1个字节的大小,指定[StructLayout(LayoutKind.Sequential, Pack=1)]应该使任何填充问题无效.两个结构都应该是5个字节.所以我有两个问题:
谢谢.
由于布尔值实际占用1个字节的空间,因此a bool[]不是表示位数组的最节省空间的方式.有时整数和长整数用作更有效的位数组,但长整数和长整数只能容纳64位.是否有更节省空间的方法在有限的内存中存储数千万位的数组?
我需要对这个数组做的就是设置/清除各个位并检查某些位是1还是0,即我需要的唯一功能:
void Set(int index, bool value);
bool Get(int index);
Run Code Online (Sandbox Code Playgroud) 如果我做
class x
{
int a; // here we have 2 integers, each reference has 4 bytes itself
int b;
public int GetSize()
{
// this function is supposed to return size of the class in operating memory in bytes
return sizeof(int) * 2;
// OR should it be this?
return sizeof(int) * 2 + IntPtr.Size * 2;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在某种类型上调用sizeof,例如int或double,它是否返回该值使用的ram的多少?或者它也计算引用本身的大小.我知道c#中的每个引用都至少占用4个字节(因此bool等通常是内存便宜的类型,在c#中的内存非常昂贵).
如果我想知道操作记忆精确int x = 5;吃多少我应该只计算sizeof(int)或sizeof(int) + IntPtr.Size?
注意:我知道这Marshal.SizeOf可以让你调用一些特殊的函数来返回非托管对象/类型的精确大小,但这对我来说似乎太慢了.我需要一种方法来获得尽可能少吃cpu的对象的大小,所以我更喜欢使用原生sizeof()