繁体   English   中英

为什么我收到有关 int 与 unsigned long 不匹配的错误?

[英]Why am I getting errors about int not matching unsigned long?

int solve(const std::string &s, const std::string &ops)
{
  std::vector<int> order;
  std::vector<int> tnfs;
  unsigned long answer = 0;
  unsigned long opslen = ops.size();
  unsigned long slen = s.size();
  bool loopAnswer;
  bool countThisLoop;

  for (size_t i = 0; i < opslen; i++)
    order.push_back(i);
  for (size_t i = 0; i < slen; i++)
    tnfs.push_back(s[i] == 't');
  do{ 
    //Reset
    countThisLoop = 1;
    unsigned long connection[10][10] = {{0}};
    for (size_t i = 0; i < slen; i++)
      tnfs[i] = (s[i] == 't');  
    for(size_t i = 0; i < opslen; i++)
    {
      if(ops[order[i]] == '&'){
        tnfs[order[i]] = tnfs[order[i]] && tnfs[order[i] + 1];
      }   
      if(ops[order[i]] == '^'){
        tnfs[order[i]] = tnfs[order[i]] != tnfs[order[i] + 1];
      }  
      if(ops[order[i]] == '|'){
        tnfs[order[i]] = tnfs[order[i]] || tnfs[order[i] + 1];
      } 
      connection[order[i]][order[i]] = 1;
      connection[order[i]][order[i]+1] = 1;
      // look in each row for a match in the two column that were just connected
      for(size_t j = 0; j < slen; j++)
      {
        // if there is a match then OR all of that row's connections
        if((connection[order[i]][order[i]] && connection[j][order[i]]) || 
           (connection[order[i]][order[i]+1] && connection[j][order[i]+1]))
        {
          for(size_t k = 0; k < slen; k++)
          {
            connection[order[i]][k] |= connection[j][k];
          }
        }
      }
      bool thisLoopHasOverlappingConnections = false;
      for(size_t k = 0; k < slen; k++)
      {
        if(connection[order[i]][k] && connection[order[i-1]][k])
        {
          thisLoopHasOverlappingConnections |= true;
        }
      }
      if(!thisLoopHasOverlappingConnections && (order[i-1] > order[i]))
      {
        countThisLoop = 0;
        break;
      }
      for(size_t j = 0; j < slen; j++)
      {
        if(connection[order[i]][j] == 1)
        {
          tnfs[j] = tnfs[order[i]];
        }
      }
      loopAnswer = tnfs[order[i]];
    }
    if(countThisLoop)
      answer += loopAnswer;
  } while (std::next_permutation(order.begin(), order.end()));
  return answer;
}

我已经尝试了变量类型的每种组合,但我不断收到一条消息,内容为...

 warning: comparison of integers of different signs: 'int' and 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::size_type' (aka 'unsigned long') [-Wsign-compare] for (int i = 0; i < s.size(); i++) results[1][i][s[i]=='t'] = 1;

将已签名的 integer 与未签名的 integer 进行比较是不安全的,除非您绝对知道已签名的 integer 不是负数,或者未签名的类型比带符号的类型窄。

这是因为在有符号整数和无符号整数之间的任何算术运算(包括数字比较)中,无符号类型至少与有符号类型一样宽(因此具有无法转换为有符号类型的值),C++ 将自动转换将有符号integer 的值转换为无符号类型。 这将导致小的负值具有非常大的正值,因为负有符号整数转换为无符号整数的方法是将最大可能的无符号值加一,直到负值变为正值。 (这种行为是 C++ 标准所要求的,并且有充分的理由。我不会再进一步介绍它。)

结果是,如果你这样做:

int i = -1;
if (i > a.size())
  std::cout << i << " is greater than " << a.size() << '\n';

您的程序可能会告诉您“-1 大于 42”(或其他),这可能会让人有点意外。

为了避免你以这种方式感到惊讶,如果编译器看到你正在做这种类型的比较,它会警告你。 如果您绝对知道签名的 integer 在任何情况下都不能,包括您想不到的情况,那么您可以忽略警告。 或者,您可以将有符号 integer 的类型更改为无符号类型,使其不能为负数。

当然,这不会阻止你犯像unsigned i = -1;这样的错误。 (这是完全合法的,你的 C++ 编译器不会警告你,因为它假设你知道在这种情况下你在做什么。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM