我试图写一个函数,打印出数组中的元素。但是,当我处理传递的数组时,我不知道如何迭代数组。
void print_array(int* b) { int sizeof_b = sizeof(b) / sizeof(b[0]); int i; for (i = 0; i < sizeof_b; i++) { printf("%d", b[i]); } }
迭代传递的数组的最佳方法是什么?
k5ifujac1#
您还需要将数组的大小传递给函数。当你把数组传递给函数时,你实际上是在传递数组中第一个元素的地址。所以指针只在函数内部指向第一个元素一次。由于数组中的内存是连续的,因此仍然可以使用指针算法(如(b+1))来指向第二个元素或等效的b[1]
(b+1)
b[1]
void print_array(int* b, int num_elements) { for (int i = 0; i < num_elements; i++) { printf("%d", b[i]); } }
这个技巧只适用于数组,而不适用于指针:
sizeof(b) / sizeof(b[0])
arrays are not the same as pointers
uqjltbpv2#
为什么不使用函数模板(C++)?
template<class T, int N> void f(T (&r)[N]){ } int main(){ int buf[10]; f(buf); }
编辑2:qn现在看起来有C标记,C++标记被删除。
cx6n0qe33#
对于C,你必须传递数组的长度(元素的数量)。对于C++,你可以传递长度,但是,如果你可以访问C++0x,最好使用std::array。参见here和here。它携带长度,并在使用at()成员函数访问元素时提供越界检查。
std::array
at()
hgc7kmma4#
在C99中,你可以要求一个数组至少有n个元素:
n
void print_array(int b[static n]);
6.7.5.3.7:将参数声明为“array of type”应调整为“qualified pointer to type”,其中类型限定符(如果有的话)是在数组类型派生的[ and ]中指定的。如果关键字static也出现在数组类型派生的[ and ]中,则对于每个函数调用,相应的实际参数的值应提供对数组的第一个元素的访问,该数组至少具有与size表达式指定的元素一样多的元素。在GCC中,你可以像这样pass the size of an array implicitly:
void print_array(int n, int b[n]);
bhmjp9jg5#
你可以试试这个。。
#include <cstdio> void print_array(int b[], size_t N) { for (int i = 0; i < N; ++i) printf("%d ", b[i]); printf("\n"); } template <size_t N> inline void print_array(int (&b)[N]) { // could have loop here, but inline forwarding to // single function eliminates code bloat... print_array(b, N); } int main() { int a[] = { 1, 2 }; int b[] = { }; int c[] = { 1, 2, 3, 4, 5 }; print_array(a); // print_array(b); print_array(c); }
有趣的是,B不工作。
array_size.cc: In function `int main()': array_size.cc:19: error: no matching function for call to `print_array(int[0u])'
JoshD在下面的评论中指出了大小为0的数组(GCC扩展)的问题,以及上面的大小推断。
ygya80vv6#
在c中,你也可以使用某种类型的列表类,它被实现为一个带有size方法的数组或一个带有size成员的结构(在c或c中)。
1szpjjfi7#
使用变量传递数组的大小。int sizeof_b = sizeof(b) / sizeof(b[0]);除了获取预先声明的数组大小外什么都不做,数组大小是已知的,你可以把它作为参数传递;例如void print_array(int*b, int size)。size也可以是用户定义的大小。
int sizeof_b = sizeof(b) / sizeof(b[0]);
void print_array(int*b, int size)
size
xpcnnkqh8#
这个问题已经有了一些很好的答案,例如the second one。然而,由于缺乏解释,因此我想扩展示例并解释它:使用模板和模板参数(在本例中为None-Type Template parameters)可以获得任何类型的固定数组的大小。假设你有这样一个函数模板:
template<typename T, int S> int getSizeOfArray(T (&arr)[S]) { return S; }
该模板显然适用于任何类型(这里是T)和固定整数(S)。如你所见,函数接受了一个对T* 类型的S对象数组的引用,正如你所知道的,在C++中,你不能通过值来传递数组,而是通过引用来传递数组,所以函数必须接受一个引用。如果你这样使用它:
int i_arr[] = { 3, 8, 90, -1 }; std::cout << "number f elements in Array: " << getSizeOfArray(i_arr) << std::endl;
编译器将隐式地示例化模板函数并检测参数,因此这里的S是4,它被返回并打印到输出。
4
8条答案
按热度按时间k5ifujac1#
您还需要将数组的大小传递给函数。
当你把数组传递给函数时,你实际上是在传递数组中第一个元素的地址。所以指针只在函数内部指向第一个元素一次。
由于数组中的内存是连续的,因此仍然可以使用指针算法(如
(b+1)
)来指向第二个元素或等效的b[1]
这个技巧只适用于数组,而不适用于指针:
arrays are not the same as pointers
uqjltbpv2#
为什么不使用函数模板(C++)?
编辑2:
qn现在看起来有C标记,C++标记被删除。
cx6n0qe33#
对于C,你必须传递数组的长度(元素的数量)。
对于C++,你可以传递长度,但是,如果你可以访问C++0x,最好使用
std::array
。参见here和here。它携带长度,并在使用at()
成员函数访问元素时提供越界检查。hgc7kmma4#
在C99中,你可以要求一个数组至少有
n
个元素:6.7.5.3.7:将参数声明为“array of type”应调整为“qualified pointer to type”,其中类型限定符(如果有的话)是在数组类型派生的[ and ]中指定的。如果关键字static也出现在数组类型派生的[ and ]中,则对于每个函数调用,相应的实际参数的值应提供对数组的第一个元素的访问,该数组至少具有与size表达式指定的元素一样多的元素。
在GCC中,你可以像这样pass the size of an array implicitly:
bhmjp9jg5#
你可以试试这个。。
有趣的是,B不工作。
JoshD在下面的评论中指出了大小为0的数组(GCC扩展)的问题,以及上面的大小推断。
ygya80vv6#
在c中,你也可以使用某种类型的列表类,它被实现为一个带有size方法的数组或一个带有size成员的结构(在c或c中)。
1szpjjfi7#
使用变量传递数组的大小。
int sizeof_b = sizeof(b) / sizeof(b[0]);
除了获取预先声明的数组大小外什么都不做,数组大小是已知的,你可以把它作为参数传递;例如void print_array(int*b, int size)
。size
也可以是用户定义的大小。int sizeof_b = sizeof(b) / sizeof(b[0]);
会在元素数量小于预先声明的array-size时导致冗余迭代。*xpcnnkqh8#
这个问题已经有了一些很好的答案,例如the second one。然而,由于缺乏解释,因此我想扩展示例并解释它:
使用模板和模板参数(在本例中为None-Type Template parameters)可以获得任何类型的固定数组的大小。
假设你有这样一个函数模板:
该模板显然适用于任何类型(这里是T)和固定整数(S)。如你所见,函数接受了一个对T* 类型的S对象数组的引用,正如你所知道的,在C++中,你不能通过值来传递数组,而是通过引用来传递数组,所以函数必须接受一个引用。
如果你这样使用它:
编译器将隐式地示例化模板函数并检测参数,因此这里的S是
4
,它被返回并打印到输出。