FOR循环外定义的变量范围?

时间:2012-12-12 15:44:39

标签: c++ c++11

以下代码用于替换仅出现一次的字符串中的连续重复字符

e.g. "AAAABBBB" -> "AB" 

当我退出for循环并在temp中打印值时,我的期望是得到一个字符串单词的最后一个字母。但是,我得到了字符串的第一个字母(即,我初始化了temp的值)。

string processString(string word) {
  char temp = word[0];
  string result = "";
  int size = word.size();
  for(int i=0, temp=word[0]; i<size; i++) {
    if(word[i] == temp) {
      continue;
    } else {
      result += temp;
      temp = word[i];
    }
  }
  cout << "TEMP : " << temp << endl;
  return result + temp;
}

结果:

WORD: CJXEJACCAJEXJF
TEMP: C
Output of function: CJXEJACAJEXJC

但如果我删除for循环中的重新初始化,上面的代码就可以正常工作:

string processString(string word) {
  char temp = word[0];
  string result = "";
  int size = word.size();
  for(int i=0; i<size; i++) {
    if(word[i] == temp) {
      continue;
    } else {
      result += temp;
      temp = word[i];
    }
  }
  cout << "TEMP : " << temp << endl;
  return result + temp;
}

结果:

WORD: CJXEJACCAJEXJF
TEMP: F
Output of function: CJXEJACAJEXJF

任何线索为何会发生这种情况?为什么在FOR循环中重新初始化会产生如此大的差异?

4 个答案:

答案 0 :(得分:2)

for循环中,您没有重新初始化temp。您正在创建一个名为int的全新temp变量,该变量会遮蔽外部temp

for(int i=0,temp=word[0];i<size;i++){
            ^^^^ brand new `temp'

可以配置一些编译器来警告:

$ g++ -Wshadow test.cpp
test.cpp: In function 'std::string processString(std::string)':
test.cpp:10:15: warning: declaration of 'temp' shadows a previous local [-Wshadow]
test.cpp:7:8: warning: shadowed declaration is here [-Wshadow]

答案 1 :(得分:2)

关于阴影的其他答案是正确的,但仅供参考,您的函数可以简单地写为:

#include <string>
#include <iterator>
#include <algorithm>

std::string unique(std::string const &source)
{
    std::string result;

    std::unique_copy(src.begin(), src.end(),
                     std::back_inserter(result));
    return result;
}

答案 2 :(得分:1)

for(int i=0,temp=word[0];i<size;i++)

声明了两个变量itempfor语句中的。这个temp隐藏了在for语句之外声明的那个。

答案 3 :(得分:1)

temp循环中,名为int的新变量被声明为for

for(int i=0,temp=word[0];i<size;i++){

隐藏外部char temp变量,意味着永远不会在char temp内使用for变量。 for循环的第二个版本没有通过省略初始化来声明新的temp变量。