首页 文章

是否可以在for循环中声明两个不同类型的变量?

提问于
浏览
204

是否可以在C中的for循环的初始化主体中声明两个不同类型的变量?

例如:

for(int i=0,j=0 ...

定义了两个整数 . 我可以在初始化主体中定义 intchar 吗?怎么做?

6 回答

  • 1

    不可能,但你可以这样做:

    float f;
    int i;
    for (i = 0,f = 0.0; i < 5; i++)
    {
      //...
    }
    

    或者,使用其他括号明确限制 fi 的范围:

    {
        float f; 
        int i;
        for (i = 0,f = 0.0; i < 5; i++)
        {
           //...
        }
    }
    
  • 94

    不 - 但从技术上讲,有一种解决方法(不是我实际上使用它,除非被迫):

    for(struct { int a; char b; } s = { 0, 'a' } ; s.a < 5 ; ++s.a) 
    {
        std::cout << s.a << " " << s.b << std::endl;
    }
    
  • 256

    C++17Yes! 您应该使用structured binding declaration . gcc-7和clang-4.0(clang live example)支持该语法 . 这允许我们像这样解压缩一个元组:

    for (auto [i, f, s] = std::tuple{1, 1.0, std::string{"abc"}}; i < N; ++i) {
        // ...
    }
    

    以上将给你:

    • int i 设为 1

    • double f 设为 1.0

    • std::string s 设为 "abc"

    请确保 #include <tuple> 用于此类声明 .

    如果要为类型命名,可以像 std::string 一样输入 tuple 中的确切类型 . 例如:

    auto [vec, i32] = std::tuple{std::vector<int>{3, 4, 5}, std::int32_t{12}}
    

    C++14 :您可以使用基于类型的 std::get 添加与C 11(下面)相同的内容 . 因此,在下面的示例中,您可以使用 std::get<int>(t) 而不是 std::get<0>(t) .


    C++11std::make_pair允许您执行此操作,以及std::make_tuple允许您执行两个以上的对象 .

    for (auto p = std::make_pair(5, std::string("Hello World")); p.first < 10; ++p.first) {
        std::cout << p.second << std::endl;
    }
    

    std::make_pair 将在 std::pair 中返回两个参数 . 可以使用 .first.second 访问这些元素 .

    对于两个以上的对象,您需要使用 std::tuple

    for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
            std::get<0>(t) < 10;
            ++std::get<0>(t)) {
        std::cout << std::get<1>(t) << std::endl; // cout Hello world
        std::get<2>(t).push_back(std::get<0>(t)); // add counter value to the vector
    }
    

    std::make_tuple 是一个可变参数模板,它将构造任意数量参数的元组(当然有一些技术限制) . 可以使用 std::get<INDEX>(tuple_object) 索引访问元素

    在for循环体内,您可以轻松地对对象进行别名,但仍需要使用 .firststd::get 作为for循环条件并更新表达式

    for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
            std::get<0>(t) < 10;
            ++std::get<0>(t)) {
        auto& i = std::get<0>(t);
        auto& s = std::get<1>(t);
        auto& v = std::get<2>(t);
        std::cout << s << std::endl; // cout Hello world
        v.push_back(i); // add counter value to the vector
    }
    

    C++98 and C++03 您可以明确命名 std::pair 的类型 . 但是,没有标准的方法可以将其概括为两种以上类型:

    for (std::pair<int, std::string> p(5, "Hello World"); p.first < 10; ++p.first) {
        std::cout << p.second << std::endl;
    }
    
  • 14

    您不能在初始化中声明多个类型,但可以指定多个类型E.G.

    {
       int i;
       char x;
       for(i = 0, x = 'p'; ...){
          ...
       }
    }
    

    只需在自己的范围内声明它们 .

  • 0

    请参阅“Is there a way to define variables of two types in for loop? " for another way involving nesting multiple for loops. The advantage of the other way over Georg's " struct trick”,它(1)允许您混合使用静态和非静态局部变量,(2)它允许您拥有不可复制的变量 . 缺点是它的可读性要低得多,而且效率可能会降低 .

  • 197

    定义一个宏:

    #define FOR( typeX,x,valueX,  typeY,y,valueY,  condition, increments) typeX x; typeY y; for(x=valueX,y=valueY;condition;increments)
    
    FOR(int,i,0,  int,f,0.0,  i < 5, i++)
    {
      //...
    }
    

    请记住,您的变量范围也不会以这种方式在for循环中 .

相关问题