Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在c++;_C++_Arrays_Function - Fatal编程技术网

C++ 如何在c++;

C++ 如何在c++;,c++,arrays,function,C++,Arrays,Function,我想写一个函数,可以打印不同的数组。例如: #include<iostream> using namespace std; int main(){ int a[10]; int b[3][2]; for(int i = 0; i < 10; i++){ a[i] = i; } for(int i = 0; i < 3; i++){ for(int j = 0; j < 2; j++){

我想写一个函数,可以打印不同的数组。例如:

#include<iostream>
using namespace std;
int main(){
    int a[10];
    int b[3][2];
    for(int i = 0; i < 10; i++){
        a[i] = i;
    }
    for(int i = 0; i < 3; i++){
        for(int j = 0; j < 2; j++){
            b[i][j] = i * 2 + j;
        }
    }
    print_arr(a, /*some input*/);
// output: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    print_arr(b, /*some input*/);
// output: 
// 0, 1
// 2, 3
// 4, 5
   return 0;
}
#包括
使用名称空间std;
int main(){
INTA[10];
int b[3][2];
对于(int i=0;i<10;i++){
a[i]=i;
}
对于(int i=0;i<3;i++){
对于(int j=0;j<2;j++){
b[i][j]=i*2+j;
}
}
打印(a,/*一些输入*/);
//输出:0,1,2,3,4,5,6,7,8,9,10
打印arr(b,/*一些输入*/);
//输出:
// 0, 1
// 2, 3
// 4, 5
返回0;
}
谁能帮帮我,或者说这是不可能的。
也许这个问题已经得到了回答。在这种情况下,请您共享该问题的链接

您可以创建一个递归展开数组的函数模板

例如:

#include <iostream>
#include <type_traits>

// only enable the function for arrays
template<class T, std::enable_if_t<std::is_array_v<T>, int> = 0>
void print_arr(const T& x) {
    for(auto& in : x) {
        if constexpr (std::rank_v<T> > 1) // more dimensions to go
            print_arr(in);                // call to unwrap next dimension
        else
            std::cout << in << ' ';       // last dimension, print the value
            
    }
    std::cout << '\n';
}
#include <sstream>

template<class T>
std::string print_arr(const T& x) {
    static_assert(std::is_array_v<T>);
    std::ostringstream os;

    for(auto& in : x) {
        if constexpr (std::rank_v<T> > 1)
            os << print_arr(in);
        else
            os << in << ' ';
            
    }
    os << '\n';
    return os.str();
}

// ...

    std::cout << print_arr(a);
    std::cout << print_arr(b);
您可以添加一个
std::ostream&
参数使其流到任何流,而不是直接流到
std::cout


Ted Lyngmo的答案肯定是最简洁的,可能是最接近实现您要求的,但仍有一些事情值得指出,包括在某些情况下可能有意义的替代解决方案

<>首先,对于阅读此文档的人来说,了解C和C++类型默认不包含任何类型的运行时类型信息是很重要的。是的,RTTI确实存在于记录类型中,但是像
int-arr[2][3]
这样的内置C数组对于“给我一个足够大的内存区域来存储6个int”来说并没有什么好处。例如,这与python之类的语言形成对比,在python中,列表对象将包含关于大小和内容的元数据。正是这种元数据允许您编写非常灵活的函数,而不是查询对象本身的结构,当然这是有代价的

当我们引入像上面这样的模板化解决方案时,我们没有添加运行时类型信息,而是要求编译器为可能需要的数组类型的每个可能排列生成代码。如果您只有两个数组,这很好,但是如果函数被大量使用,并且使用了许多不同的数组类型,那么事情会发展得非常快。在某些环境中,这实际上可能会成为一个问题。例如,考虑以下主要功能:

template<class T>
void print_arr(const T& x) {
    static_assert(std::is_array_v<T>);
    // ...
int main(int argc, char **argv)
{
    int arr1[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
    print_arr(arr1);
    int arr2[3] = {13, 14, 15};
    print_arr(arr2);
    int arr3[3][2][2] = {{{10, 20}, {30, 40}}, {{50, 60}, {70, 80}}, {{90, 100}, {110, 120}}};
    print_arr(arr3);
    return 0;
}
现在看看生成的AST:

jon@prompt$ clang++ -fsyntax-only -Xclang -ast-dump test.cpp -std=c++17 | grep FunctionDecl | grep print_arr
| |-FunctionDecl 0x10921fd88 <line:6:1, line:15:1> line:6:6 print_arr 'void (const T &)'
| |-FunctionDecl 0x109224c18 <line:6:1, line:15:1> line:6:6 used print_arr 'void (int const &[3][4])'
| |-FunctionDecl 0x109225ab8 <line:6:1, line:15:1> line:6:6 used print_arr 'void (int const &[3])'
| |-FunctionDecl 0x1092270a8 <line:6:1, line:15:1> line:6:6 used print_arr 'void (int const &[3][2][2])'
| |-FunctionDecl 0x10933db08 <line:6:1, line:15:1> line:6:6 used print_arr 'void (int const &[4])'
| |-FunctionDecl 0x1093539a8 <line:6:1, line:15:1> line:6:6 used print_arr 'void (int const &[2][2])'
| `-FunctionDecl 0x1093552d8 <line:6:1, line:15:1> line:6:6 used print_arr 'void (int const &[2])'
下面是如何将其用于相同的示例阵列:

int main(int argc, char **argv)
{
    int arr1[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
    print_arr(&arr1[0][0], 2, (int[2]){3, 4});
    printf("\n");
    int arr2[3] = {13, 14, 15};
    print_arr(&arr2[0], 1, (int[1]){3});
    printf("\n");
    int arr3[3][2][2] = {{{10, 20}, {30, 40}}, {{50, 60}, {70, 80}}, {{90, 100}, {110, 120}}};
    print_arr(&arr3[0][0][0], 3, (int[3]){3, 2, 2});
    printf("\n");

    return 0;
}
输出:

jon@promptC$ ./test
{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}
{13, 14, 15}
{{{10, 20}, {30, 40}}, {{50, 60}, {70, 80}}, {{90, 100}, {110, 120}}}
这种方法有几个优点,最重要的是编译器几乎准确地发出所写的内容。它还迫使您在代码中非常明确,这在本例中可能很好


<> P>和C和C++一样,你需要知道你发现的情况最适合什么。但是如果你刚开始认识到
a
b
是完全不同的类型,这将是一个巨大的障碍。你可以先编写两个不同的函数,它们采用不同的参数类型,并将它们命名为
print\u arr
。使用模板和专门化非常简单。你熟悉这些C++主题吗?不错的解决方案,但我实际上建议OP使用<代码> STD::OSWATE运算符@ 2B-T谢谢。好主意。我添加了两个选项。是的,它的大小不变,但我有一个小问题<代码>整数a[n]使用此数组返回编译错误:“没有匹配函数用于调用print_arr(int[n])”@Jekuper如果需要可变大小的数组(VLA:s),我建议使用
std::vector
s。VLA是一种非标准扩展,仅在某些编译器中可用。
int main(int argc, char **argv)
{
    int arr1[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
    print_arr(&arr1[0][0], 2, (int[2]){3, 4});
    printf("\n");
    int arr2[3] = {13, 14, 15};
    print_arr(&arr2[0], 1, (int[1]){3});
    printf("\n");
    int arr3[3][2][2] = {{{10, 20}, {30, 40}}, {{50, 60}, {70, 80}}, {{90, 100}, {110, 120}}};
    print_arr(&arr3[0][0][0], 3, (int[3]){3, 2, 2});
    printf("\n");

    return 0;
}
jon@promptC$ ./test
{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}
{13, 14, 15}
{{{10, 20}, {30, 40}}, {{50, 60}, {70, 80}}, {{90, 100}, {110, 120}}}