当前位置: 首页 > 知识库问答 >
问题:

为什么字符串::compare返回一个int?

罗俭
2023-03-14

为什么string::compare返回int而不是像shortchar这样的较小类型?我的理解是,这个方法只返回-1、0或1。

第二部分,如果我要设计一个比较方法来比较两个Foo类型的对象,并且我只想返回-1、0或1,那么使用shortchar通常是个好主意吗?

编辑:我已经更正,字符串::compare不返回-1,0或1,它实际上返回一个值

答案似乎大致是,没有理由返回小于int的类型,因为返回值是右值,而这些右值不会受益于小于int类型(4字节)。此外,许多人指出,大多数系统的寄存器可能会有大小int,因为无论你给它们一个1、2或4字节的值,这些寄存器都将被填充,所以没有真正的优势返回较小的值。

编辑2:事实上,在使用较小的数据类型(如对齐、屏蔽等)时,可能会有额外的处理开销。一般的共识是,较小的数据类型的存在是为了在处理大量数据时节省内存,例如在数组中。

今天学到了一些东西,再次感谢伙计们!

共有3个答案

董联
2023-03-14

int通常是(在大多数现代硬件上的意思)一个与系统总线和/或cpu寄存器大小相同的整数,也就是所谓的机器字。因此,int通常比较小的类型传递得更快,因为它不需要对齐、掩蔽和其他操作。

较小的类型主要用于优化阵列和结构的RAM使用。在大多数情况下,为了更好地使用RAM,它们会牺牲一些CPU周期(以对齐操作的形式)。

除非您需要将返回值强制为一个有符号或无符号的centain大小的数字(char,short…),否则最好使用int,这就是标准库这样做的原因。

杨无尘
2023-03-14

它故意不返回-1、0或1。

它允许(注意这不适用于字符串,但同样适用于字符串)

int compare(int *a, int *b)
{
   return *a - *b;
}

这比:

int compare(int *a, int *b)
{
   if (*a == *b) return 0;
   if (*a > *b) return 1;
   return -1;
}

如果必须返回-1、0或1,则必须执行此操作(或类似操作)。

它也适用于更复杂的类型:

class Date
{
    int year;
    int month;
    int day;
}

int compare(const Date &a, const Date &b)
{
   if (a.year != b.year) return a.year - b.year;
   if (a.month != b.month) return a.month - b.month;
   return a.day - b.day;
}

在字符串情况下,我们可以这样做:

int compare(const std::string& a, const std::string& b)
{
   int len = min(a.length(), b.length());

   for(int i = 0; i < len; i++)
   {
      if (a[i] != b[i]) return a[i] - b[i];
   }
   // We only get here if the string is equal all the way to one of them
   // ends. If the length isn't equal, "longest" wins. 
   return a.length() - b.length();
}
戚翼
2023-03-14

首先,规范是它将返回小于、等于或大于0,而不一定是-11。第二,返回值是右值,受整数提升的影响,因此没有必要返回更小的值。

在C语言中(就像在C语言中一样),每个表达式要么是右值,要么是左值。历史上,这些术语指的是左值出现在赋值的左边,而as右值只能出现在右边。今天,非类类型的一个简单近似值是左值在内存中有地址,右值没有地址。因此,不能获取右值的地址,cv限定符(条件“访问”)不适用。在C语言中,没有类类型的右值是纯值,而不是对象。函数的返回值是右值,除非它具有引用类型。(例如,适合寄存器的非类类型几乎总是在寄存器中返回,而不是在内存中返回。)

对于类类型,问题要复杂一些,因为您可以在右值上html" target="_blank">调用成员函数。这意味着,对于This指针,Rvalue实际上必须具有地址,并且可以是cv限定的,因为cv限定在重载解析中起作用。最后,C11引入了几个新的区别,以支持右值引用;这些也主要适用于类类型。

积分提升是指当小于int的积分类型在表达式中用作右值时,在大多数上下文中,它们将提升为int。因此,即使我有一个声明为短a, b;的变量,在表达式a b中,在添加发生之前,ab都被提升为int。同样,如果我写a

short a = 1;
std::cout << sizeof( a ) << std::endl;
std::cout << sizeof( a + 0 ) << std::endl;

应该给出不同的结果:第一个结果相当于sizeof(short),第二个结果相当于sizeof(int)(因为整体升级)。

这两个问题在形式上是正交的;右值和左值与整体提升无关。除了积分提升仅适用于右值,并且大多数(但不是所有)使用右值的情况都会导致积分提升。因此,实际上没有理由返回小于int的数值。甚至有很好的理由不将其作为字符类型返回。重载运算符,如

char f() { return 'a'; }
std::cout << f() << std::endl;      //  displays "a"
std::cout << f() + 0 << std::endl;  //  displays "97" on my machine

不同的是,在第二种情况下,添加导致了积分提升,这导致了不同的重载。

 类似资料:
  • 问题内容: 我有一个带有3个嵌套数组的简单php结构。 我不使用特定的对象,而是使用2个嵌套循环构建数组。 这是我要转换为Json的数组的var_dump的示例。 在另一个脚本中,我具有类似的结构并且工作正常。所以我不明白为什么在这里不起作用。 编辑:似乎有编码问题。当返回ASCII,该作品但当它返回UTF8,它不工作了。 Edit2:返回表示:格式错误的UTF-8字符,可能编码不正确。 问题答案

  • 问题内容: 这可能是最简单的事情之一,但我看不到自己在做错什么。 我的输入包括一个带有数字的第一行(要读取的行数),一串包含数据的行和最后一行仅包含\ n的行。我应该处理此输入,并在最后一行之后做一些工作。 我有这个输入: 对于读取输入,我有以下代码。 我的问题是为什么我什么都不打印?程序读取第一行,然后不执行任何操作。 问题答案: 不读取以下换行符,因此第一个(返回 当前 行的其余部分 )将始终

  • 问题内容: 这是有效的,并返回JavaScript中的字符串 为什么?这是怎么回事 问题答案: 如果我们将其拆分,则混乱等于: 在JavaScript中,确实是这样。将某物转换为数字,在这种情况下,它将降为或(请参见下面的规范详细信息)。 因此,我们可以简化它(优先于): 因为意思是:从中获取第一个元素,所以确实: 返回内部数组()。由于引用,说错了,但是让我们调用内部数组以避免错误的表示法。 在

  • 问题内容: 为什么要得到一个空字符串?我的代码是: 此代码警报,但我想得到,我怎么了?谁能帮我? 更新 我更改了CSS函数,现在可以正常使用了: 问题答案: 该属性用于获取直接放置在元素上的样式。它不会从样式表中计算样式。

  • 问题内容: 好的,这就是我的for子手游戏代码,我唯一要做的就是让我的程序将其中一个单词随机化,这应该在方法中成功完成。但是我唯一的问题是让String变量 “ word” 返回到主类(在主类中的所有 “ word” 变量下面都有错误)。 如果我可以通过这种方法获得另一种帮助,或者从列表中产生随机单词的另一种方法,那将是惊人的。 问题答案: 在Java中,参数是通过值而不是引用传递的。因此,您不能

  • 问题内容: 我有限的大脑无法理解为什么会这样: 在PHP中,等效比较返回false: 问题答案: 从文档中: 对于Unicode和字符串类型,当且仅当 x 是 y 的子字符串时,才为true 。等效测试为。注意, x 和 y 不必是同一类型;因此,将返回。 空字符串始终被视为任何其他字符串的子字符串,因此将返回。 通过查看呼叫,您正在使用2.x。 要更深入,请看一下字节码: 是我们进行布尔运算并查