【问题标题】:problem with implict casting in c and c++ [duplicate]c和c ++中的隐式转换问题[重复]
【发布时间】:2020-09-15 09:29:53
【问题描述】:

我正在做如下的事情:

int num_of_pairs(std::vector<char>& str)
{
  for(int i = 0; i < str.size() - 1; i++)
    {
      if(str[i] == str[i + 1])
         # Do something
    }
}

但是当我传递一个长度为 0 的空向量时,for 循环仍然会执行并引发索引错误。 vector.size() 在我的编译器上返回一个 size_t,它 unsigned int64 并且我认为编译器正在计算 arr.size() - 1 作为 size_t 然后转换为 int 以检查条件,因为当 arr.size() 为 0 时 arr .size() - 1 变成一个非常大的数字,大概是 2^64 - 1 。

当我这样做时也会发生同样的事情

int n = 50000;
unsigned int a = n*(n + 1);

它给了我垃圾,因为 50000*50000 变成了 25 亿,这对于有符号整数来说是溢出的,但无符号整数可以存储它。

我有两个问题,

  1. 我的想法是否正确(我认为我是,但想确认,因为我不是 netwon 或 einstien)
  2. 有什么方法可以避免这种情况

【问题讨论】:

  • 直截了当:有显式和隐式的转换。强制转换始终是程序员完成的显式转换。但是编译器完成了许多不同类型的隐式转换。因此,不存在“隐式强制转换”之类的东西。
  • 如果给出示例,可能会使用std::adjacent_find(所以只需使用迭代器而不是索引)。

标签: c++ vector visual-c++ implicit-conversion


【解决方案1】:

成员函数size的类型std::vector&lt;char&gt;::size_type是无符号整数类型。所以这个表达式

str.size() - 1

产生无符号整数类型的最大值,前提是 str.size() 由于通常的算术转换而等于 0

在这种情况下

i < str.size() - 1

没有类型转换为int。由于相同的常用算术转换,左操作数再次隐式转换为 std::vector&lt;char&gt;::size_type 类型。

所以在for循环之前你应该检查str.size()是否等于0..

或者你可以重写循环,例如

for( std::decay_t<decltype( str )>::size_type i = 1; i < str.size(); i++)
{
    if(str[i] == str[i - 1])
       # Do something
}

至于这段代码sn-p

int n = 50000;
unsigned int a = n*(n + 1);

然后在表达式n*(n + 1) 中发生int 类型的溢出。

【讨论】:

    【解决方案2】:

    (1) 你几乎是对的。当 arr.size() 为 0 时, arr.size() - 1 变成一个非常大的数字 2^64 - 1 如果 size_t 是 64 位数字,但是变量 i 转换为 std::vector::size_type (通常size_t) 来检查条件。

    这里发生了另一件事:

    int n = 50000;
    unsigned int a = n*(n + 1);
    

    这里,如果int是32位的,那么n*(n + 1)表达式执行会导致溢出;没有强制转换为 unsigned int。转换为 unsigned int 适用于 n*(n + 1) 表达式的结果,该表达式未按标准指定,但应在编译器文档中定义。

    (2) 重写这个函数的方法有很多:

     for(size_t i = 1; i < str.size(); i++)
     {
       if ( str[i - 1] == str[i] )
          // Do something
     }
    

    或者

    int num_of_pairs(std::vector<char>& str)
    {
      if ( str.size() < 2 )
        return 0;
    
      for(size_t i = 0; i < str.size() - 1; i++)
      {
        if(str[i] == str[i + 1])
           # Do something
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-29
      • 1970-01-01
      相关资源
      最近更新 更多